2525//! │ ├─── CachePolicy::Mfu ─────► MfuCore<K, V> │
2626//! │ ├─── CachePolicy::Mru ─────► MruCore<K, V> │
2727//! │ ├─── CachePolicy::Random ──► RandomCore<K, V> │
28- //! │ └─── CachePolicy::Slru ────► SlruCore<K, V> │
28+ //! │ ├─── CachePolicy::Slru ────► SlruCore<K, V> │
29+ //! │ ├─── CachePolicy::Clock ───► ClockCache<K, V> │
30+ //! │ ├─── CachePolicy::ClockPro ► ClockProCache<K, V> │
31+ //! │ └─── CachePolicy::Nru ─────► NruCache<K, V> │
2932//! │ │
3033//! │ ▼ │
3134//! │ Cache<K, V> (unified wrapper) │
@@ -98,6 +101,8 @@ use std::hash::Hash;
98101use std:: sync:: Arc ;
99102
100103use crate :: ds:: frequency_buckets:: DEFAULT_BUCKET_PREALLOC ;
104+ use crate :: policy:: clock:: ClockCache ;
105+ use crate :: policy:: clock_pro:: ClockProCache ;
101106use crate :: policy:: fifo:: FifoCache ;
102107use crate :: policy:: heap_lfu:: HeapLfuCache ;
103108use crate :: policy:: lfu:: LfuCache ;
@@ -106,6 +111,7 @@ use crate::policy::lru::LruCore;
106111use crate :: policy:: lru_k:: LrukCache ;
107112use crate :: policy:: mfu:: MfuCore ;
108113use crate :: policy:: mru:: MruCore ;
114+ use crate :: policy:: nru:: NruCache ;
109115use crate :: policy:: random:: RandomCore ;
110116use crate :: policy:: s3_fifo:: S3FifoCache ;
111117use crate :: policy:: slru:: SlruCore ;
@@ -281,6 +287,30 @@ pub enum CachePolicy {
281287 /// Fraction of capacity for the probationary segment.
282288 probationary_frac : f64 ,
283289 } ,
290+
291+ /// Clock (Second-Chance) eviction.
292+ ///
293+ /// Approximates LRU using reference bits and a clock hand.
294+ /// Lower overhead than full LRU (no list manipulation on access).
295+ ///
296+ /// Good for: Low-latency caching, LRU approximation with lower overhead.
297+ Clock ,
298+
299+ /// Clock-PRO eviction.
300+ ///
301+ /// Scan-resistant Clock variant with adaptive promotion.
302+ /// Combines Clock mechanics with ghost history tracking.
303+ ///
304+ /// Good for: Scan-heavy workloads, adaptive caching needs.
305+ ClockPro ,
306+
307+ /// NRU (Not Recently Used) eviction.
308+ ///
309+ /// Simple reference bit tracking with O(n) worst-case eviction.
310+ /// Coarser granularity than Clock, simpler implementation.
311+ ///
312+ /// Good for: Small-to-medium caches, simple coarse recency tracking.
313+ Nru ,
284314}
285315
286316/// Unified cache wrapper that provides a consistent API regardless of policy.
@@ -350,6 +380,9 @@ where
350380 Mru ( MruCore < K , V > ) ,
351381 Random ( RandomCore < K , V > ) ,
352382 Slru ( SlruCore < K , V > ) ,
383+ Clock ( ClockCache < K , V > ) ,
384+ ClockPro ( ClockProCache < K , V > ) ,
385+ Nru ( NruCache < K , V > ) ,
353386}
354387
355388impl < K , V > Cache < K , V >
@@ -402,6 +435,9 @@ where
402435 CacheInner :: Mru ( mru) => CoreCache :: insert ( mru, key, value) ,
403436 CacheInner :: Random ( random) => CoreCache :: insert ( random, key, value) ,
404437 CacheInner :: Slru ( slru) => CoreCache :: insert ( slru, key, value) ,
438+ CacheInner :: Clock ( clock) => CoreCache :: insert ( clock, key, value) ,
439+ CacheInner :: ClockPro ( clock_pro) => CoreCache :: insert ( clock_pro, key, value) ,
440+ CacheInner :: Nru ( nru) => CoreCache :: insert ( nru, key, value) ,
405441 }
406442 }
407443
@@ -434,6 +470,9 @@ where
434470 CacheInner :: Mru ( mru) => mru. get ( key) ,
435471 CacheInner :: Random ( random) => random. get ( key) ,
436472 CacheInner :: Slru ( slru) => slru. get ( key) ,
473+ CacheInner :: Clock ( clock) => clock. get ( key) ,
474+ CacheInner :: ClockPro ( clock_pro) => clock_pro. get ( key) ,
475+ CacheInner :: Nru ( nru) => nru. get ( key) ,
437476 }
438477 }
439478
@@ -466,6 +505,9 @@ where
466505 CacheInner :: Mru ( mru) => mru. contains ( key) ,
467506 CacheInner :: Random ( random) => random. contains ( key) ,
468507 CacheInner :: Slru ( slru) => slru. contains ( key) ,
508+ CacheInner :: Clock ( clock) => clock. contains ( key) ,
509+ CacheInner :: ClockPro ( clock_pro) => clock_pro. contains ( key) ,
510+ CacheInner :: Nru ( nru) => nru. contains ( key) ,
469511 }
470512 }
471513
@@ -497,6 +539,9 @@ where
497539 CacheInner :: Mru ( mru) => mru. len ( ) ,
498540 CacheInner :: Random ( random) => CoreCache :: len ( random) ,
499541 CacheInner :: Slru ( slru) => slru. len ( ) ,
542+ CacheInner :: Clock ( clock) => CoreCache :: len ( clock) ,
543+ CacheInner :: ClockPro ( clock_pro) => CoreCache :: len ( clock_pro) ,
544+ CacheInner :: Nru ( nru) => CoreCache :: len ( nru) ,
500545 }
501546 }
502547
@@ -541,6 +586,9 @@ where
541586 CacheInner :: Mru ( mru) => mru. capacity ( ) ,
542587 CacheInner :: Random ( random) => CoreCache :: capacity ( random) ,
543588 CacheInner :: Slru ( slru) => slru. capacity ( ) ,
589+ CacheInner :: Clock ( clock) => CoreCache :: capacity ( clock) ,
590+ CacheInner :: ClockPro ( clock_pro) => CoreCache :: capacity ( clock_pro) ,
591+ CacheInner :: Nru ( nru) => CoreCache :: capacity ( nru) ,
544592 }
545593 }
546594
@@ -574,6 +622,9 @@ where
574622 CacheInner :: Mru ( mru) => mru. clear ( ) ,
575623 CacheInner :: Random ( random) => random. clear ( ) ,
576624 CacheInner :: Slru ( slru) => slru. clear ( ) ,
625+ CacheInner :: Clock ( clock) => clock. clear ( ) ,
626+ CacheInner :: ClockPro ( clock_pro) => clock_pro. clear ( ) ,
627+ CacheInner :: Nru ( nru) => nru. clear ( ) ,
577628 }
578629 }
579630}
@@ -666,6 +717,9 @@ impl CacheBuilder {
666717 CachePolicy :: Slru { probationary_frac } => {
667718 CacheInner :: Slru ( SlruCore :: new ( self . capacity , probationary_frac) )
668719 } ,
720+ CachePolicy :: Clock => CacheInner :: Clock ( ClockCache :: new ( self . capacity ) ) ,
721+ CachePolicy :: ClockPro => CacheInner :: ClockPro ( ClockProCache :: new ( self . capacity ) ) ,
722+ CachePolicy :: Nru => CacheInner :: Nru ( NruCache :: new ( self . capacity ) ) ,
669723 } ;
670724
671725 Cache { inner }
@@ -698,6 +752,9 @@ mod tests {
698752 CachePolicy :: Slru {
699753 probationary_frac : 0.25 ,
700754 } ,
755+ CachePolicy :: Clock ,
756+ CachePolicy :: ClockPro ,
757+ CachePolicy :: Nru ,
701758 ] ;
702759
703760 for policy in policies {
0 commit comments