CacheKit Docs

High-performance cache policies and supporting data structures.

View the Project on GitHub OxidizeLabs/cachekit

NRU (Not Recently Used)

Feature: policy-nru

Goal

Cheap eviction using a coarse “recently used” signal rather than a full ordering. Approximate LRU with minimal overhead and simpler implementation than Clock.

Core Idea

Each entry has a reference bit R. On eviction:

  1. Scan for first entry with R = 0 (unreferenced)
  2. If all entries are referenced, clear all reference bits and evict first entry

Unlike Clock which uses a continuously advancing hand, NRU scans linearly from the beginning when looking for victims.

Core Data Structures

Implementation in NruCache:

Operations

get(key)

insert(key, value)

evict()

Phase 1 - Find unreferenced:

Phase 2 - All referenced:

contains(key)

remove(key)

Complexity & Overhead

Operation Time Notes
get O(1) Hash lookup + bit set
insert O(n)* *Worst case if all entries referenced
contains O(1) Hash lookup only
remove O(1) Hash lookup + swap-remove

Trade-offs vs Other Policies

Aspect NRU Clock True LRU
Access cost O(1) bit set O(1) bit set O(1) list move
Eviction cost O(n) worst case O(1) amortized O(1)
Granularity Binary (used/not used) Binary with hand sweep Full order
Implementation Simple (just scan) Moderate (hand + ring) Complex (linked list)
Overhead/entry ~17 bytes (index + ref) ~1 byte (ref bit) ~16 bytes (2 pointers)

When to Use

Use NRU when:

Avoid NRU when:

Comparison with Clock

NRU vs Clock similarities:

NRU vs Clock differences:

Thread Safety

Implementation Notes

Performance Context

Expected behavior on workload with temporal locality:

Best for: Small-to-medium caches where O(n) scan is acceptable and simplicity is valued over eviction performance.

References