Skip to content

Commit bd919ec

Browse files
committed
Add FastLru and ARC cache policies to builder and documentation
- Introduced `FastLru` policy for optimized single-threaded performance, avoiding Arc wrapping for faster operations. - Added `Arc` policy for adaptive replacement, balancing recency and frequency with self-tuning capabilities. - Updated documentation to include new policies in the cache policy enumeration and examples, enhancing clarity for users. - Ensured consistency in the cache builder interface by integrating new policies into the existing structure.
1 parent 5c867f6 commit bd919ec

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

src/builder.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616
//! │ │ │
1717
//! │ ├─── CachePolicy::Fifo ────► FifoCache<K, V> │
1818
//! │ ├─── CachePolicy::Lru ─────► LruCore<K, V> │
19+
//! │ ├─── CachePolicy::FastLru ─► FastLru<K, V> │
1920
//! │ ├─── CachePolicy::LruK ────► LrukCache<K, V> │
2021
//! │ ├─── CachePolicy::Lfu ─────► LfuCache<K, V> │
2122
//! │ ├─── CachePolicy::HeapLfu ─► HeapLfuCache<K, V> │
2223
//! │ ├─── CachePolicy::TwoQ ────► TwoQCore<K, V> │
2324
//! │ ├─── CachePolicy::S3Fifo ──► S3FifoCache<K, V> │
25+
//! │ ├─── CachePolicy::Arc ─────► ARCCore<K, V> │
2426
//! │ ├─── CachePolicy::Lifo ────► LifoCore<K, V> │
2527
//! │ ├─── CachePolicy::Mfu ─────► MfuCore<K, V> │
2628
//! │ ├─── CachePolicy::Mru ─────► MruCore<K, V> │
@@ -49,11 +51,13 @@
4951
//! |-----------|-----------------------------------|-----------------------|
5052
//! | FIFO | Simple, predictable workloads | Insertion order |
5153
//! | LRU | Temporal locality | Recency |
54+
//! | FastLRU | Maximum single-threaded speed | Recency (no Arc) |
5255
//! | LRU-K | Scan-resistant workloads | K-th access time |
5356
//! | LFU | Stable access patterns | Frequency (O(1)) |
5457
//! | HeapLFU | Frequent evictions, large caches | Frequency (O(log n)) |
5558
//! | 2Q | Mixed workloads | Two-queue promotion |
5659
//! | S3-FIFO | CDN, scan-heavy workloads | Three-queue FIFO |
60+
//! | ARC | Adaptive recency/frequency | Self-tuning |
5761
//! | LIFO | Stack-like caching | Reverse insertion |
5862
//! | MFU | Inverse frequency patterns | Highest frequency |
5963
//! | MRU | Cyclic access patterns | Most recent access |
@@ -101,8 +105,10 @@ use std::hash::Hash;
101105
use std::sync::Arc;
102106

103107
use crate::ds::frequency_buckets::DEFAULT_BUCKET_PREALLOC;
108+
use crate::policy::arc::ARCCore;
104109
use crate::policy::clock::ClockCache;
105110
use crate::policy::clock_pro::ClockProCache;
111+
use crate::policy::fast_lru::FastLru;
106112
use crate::policy::fifo::FifoCache;
107113
use crate::policy::heap_lfu::HeapLfuCache;
108114
use crate::policy::lfu::LfuCache;
@@ -169,6 +175,12 @@ use crate::traits::{CoreCache, ReadOnlyCache};
169175
/// let slru = CacheBuilder::new(100).build::<u64, String>(
170176
/// CachePolicy::Slru { probationary_frac: 0.25 }
171177
/// );
178+
///
179+
/// // ARC for adaptive recency/frequency balance
180+
/// let arc = CacheBuilder::new(100).build::<u64, String>(CachePolicy::Arc);
181+
///
182+
/// // FastLru for maximum single-threaded performance
183+
/// let fast_lru = CacheBuilder::new(100).build::<u64, String>(CachePolicy::FastLru);
172184
/// ```
173185
#[derive(Debug, Clone)]
174186
pub enum CachePolicy {
@@ -184,6 +196,13 @@ pub enum CachePolicy {
184196
/// Good for: temporal locality, general-purpose caching.
185197
Lru,
186198

199+
/// Fast LRU eviction (optimized for single-threaded performance).
200+
///
201+
/// Like LRU but stores values directly without Arc wrapping,
202+
/// using FxHash for faster operations (~7-10x faster than standard LRU).
203+
/// Good for: maximum single-threaded performance, values don't need to outlive eviction.
204+
FastLru,
205+
187206
/// LRU-K policy with configurable K value.
188207
///
189208
/// Tracks the K-th most recent access time for eviction decisions.
@@ -244,6 +263,15 @@ pub enum CachePolicy {
244263
ghost_ratio: f64,
245264
},
246265

266+
/// Adaptive Replacement Cache eviction.
267+
///
268+
/// Automatically adapts between recency (LRU-like) and frequency (LFU-like)
269+
/// preferences by maintaining four lists (T1, T2, B1, B2) and a dynamic
270+
/// target parameter. Provides excellent performance across diverse workloads.
271+
///
272+
/// Good for: unknown or changing workloads, self-tuning caches.
273+
Arc,
274+
247275
/// Last In, First Out eviction.
248276
///
249277
/// Evicts the most recently inserted item (stack-like behavior).
@@ -370,11 +398,13 @@ where
370398
{
371399
Fifo(FifoCache<K, V>),
372400
Lru(LruCore<K, V>),
401+
FastLru(FastLru<K, V>),
373402
LruK(LrukCache<K, V>),
374403
Lfu(LfuCache<K, V>),
375404
HeapLfu(HeapLfuCache<K, V>),
376405
TwoQ(TwoQCore<K, V>),
377406
S3Fifo(S3FifoCache<K, V>),
407+
Arc(ARCCore<K, V>),
378408
Lifo(LifoCore<K, V>),
379409
Mfu(MfuCore<K, V>),
380410
Mru(MruCore<K, V>),
@@ -416,6 +446,7 @@ where
416446
lru.insert(key, arc_value)
417447
.map(|arc| Arc::try_unwrap(arc).unwrap_or_else(|arc| (*arc).clone()))
418448
},
449+
CacheInner::FastLru(fast_lru) => fast_lru.insert(key, value),
419450
CacheInner::LruK(lruk) => CoreCache::insert(lruk, key, value),
420451
CacheInner::Lfu(lfu) => {
421452
let arc_value = Arc::new(value);
@@ -430,6 +461,7 @@ where
430461
},
431462
CacheInner::TwoQ(twoq) => CoreCache::insert(twoq, key, value),
432463
CacheInner::S3Fifo(s3fifo) => CoreCache::insert(s3fifo, key, value),
464+
CacheInner::Arc(arc) => CoreCache::insert(arc, key, value),
433465
CacheInner::Lifo(lifo) => CoreCache::insert(lifo, key, value),
434466
CacheInner::Mfu(mfu) => CoreCache::insert(mfu, key, value),
435467
CacheInner::Mru(mru) => CoreCache::insert(mru, key, value),
@@ -460,11 +492,13 @@ where
460492
match &mut self.inner {
461493
CacheInner::Fifo(fifo) => fifo.get(key),
462494
CacheInner::Lru(lru) => lru.get(key).map(|arc| arc.as_ref()),
495+
CacheInner::FastLru(fast_lru) => fast_lru.get(key),
463496
CacheInner::LruK(lruk) => lruk.get(key),
464497
CacheInner::Lfu(lfu) => lfu.get(key).map(|arc| arc.as_ref()),
465498
CacheInner::HeapLfu(heap_lfu) => heap_lfu.get(key).map(|arc| arc.as_ref()),
466499
CacheInner::TwoQ(twoq) => twoq.get(key),
467500
CacheInner::S3Fifo(s3fifo) => s3fifo.get(key),
501+
CacheInner::Arc(arc) => arc.get(key),
468502
CacheInner::Lifo(lifo) => lifo.get(key),
469503
CacheInner::Mfu(mfu) => mfu.get(key),
470504
CacheInner::Mru(mru) => mru.get(key),
@@ -495,11 +529,13 @@ where
495529
match &self.inner {
496530
CacheInner::Fifo(fifo) => fifo.contains(key),
497531
CacheInner::Lru(lru) => lru.contains(key),
532+
CacheInner::FastLru(fast_lru) => fast_lru.contains(key),
498533
CacheInner::LruK(lruk) => lruk.contains(key),
499534
CacheInner::Lfu(lfu) => lfu.contains(key),
500535
CacheInner::HeapLfu(heap_lfu) => heap_lfu.contains(key),
501536
CacheInner::TwoQ(twoq) => twoq.contains(key),
502537
CacheInner::S3Fifo(s3fifo) => s3fifo.contains(key),
538+
CacheInner::Arc(arc) => arc.contains(key),
503539
CacheInner::Lifo(lifo) => lifo.contains(key),
504540
CacheInner::Mfu(mfu) => mfu.contains(key),
505541
CacheInner::Mru(mru) => mru.contains(key),
@@ -529,11 +565,13 @@ where
529565
match &self.inner {
530566
CacheInner::Fifo(fifo) => <dyn CoreCache<K, V>>::len(fifo),
531567
CacheInner::Lru(lru) => lru.len(),
568+
CacheInner::FastLru(fast_lru) => fast_lru.len(),
532569
CacheInner::LruK(lruk) => <dyn CoreCache<K, V>>::len(lruk),
533570
CacheInner::Lfu(lfu) => lfu.len(),
534571
CacheInner::HeapLfu(heap_lfu) => heap_lfu.len(),
535572
CacheInner::TwoQ(twoq) => twoq.len(),
536573
CacheInner::S3Fifo(s3fifo) => s3fifo.len(),
574+
CacheInner::Arc(arc) => arc.len(),
537575
CacheInner::Lifo(lifo) => <dyn CoreCache<K, V>>::len(lifo),
538576
CacheInner::Mfu(mfu) => mfu.len(),
539577
CacheInner::Mru(mru) => mru.len(),
@@ -576,11 +614,13 @@ where
576614
match &self.inner {
577615
CacheInner::Fifo(fifo) => <dyn CoreCache<K, V>>::capacity(fifo),
578616
CacheInner::Lru(lru) => lru.capacity(),
617+
CacheInner::FastLru(fast_lru) => fast_lru.capacity(),
579618
CacheInner::LruK(lruk) => <dyn CoreCache<K, V>>::capacity(lruk),
580619
CacheInner::Lfu(lfu) => lfu.capacity(),
581620
CacheInner::HeapLfu(heap_lfu) => heap_lfu.capacity(),
582621
CacheInner::TwoQ(twoq) => twoq.capacity(),
583622
CacheInner::S3Fifo(s3fifo) => s3fifo.capacity(),
623+
CacheInner::Arc(arc) => arc.capacity(),
584624
CacheInner::Lifo(lifo) => <dyn CoreCache<K, V>>::capacity(lifo),
585625
CacheInner::Mfu(mfu) => mfu.capacity(),
586626
CacheInner::Mru(mru) => mru.capacity(),
@@ -612,11 +652,13 @@ where
612652
match &mut self.inner {
613653
CacheInner::Fifo(fifo) => fifo.clear(),
614654
CacheInner::Lru(lru) => lru.clear(),
655+
CacheInner::FastLru(fast_lru) => fast_lru.clear(),
615656
CacheInner::LruK(lruk) => lruk.clear(),
616657
CacheInner::Lfu(lfu) => lfu.clear(),
617658
CacheInner::HeapLfu(heap_lfu) => heap_lfu.clear(),
618659
CacheInner::TwoQ(twoq) => twoq.clear(),
619660
CacheInner::S3Fifo(s3fifo) => s3fifo.clear(),
661+
CacheInner::Arc(arc) => arc.clear(),
620662
CacheInner::Lifo(lifo) => lifo.clear(),
621663
CacheInner::Mfu(mfu) => mfu.clear(),
622664
CacheInner::Mru(mru) => mru.clear(),
@@ -690,6 +732,7 @@ impl CacheBuilder {
690732
let inner = match policy {
691733
CachePolicy::Fifo => CacheInner::Fifo(FifoCache::new(self.capacity)),
692734
CachePolicy::Lru => CacheInner::Lru(LruCore::new(self.capacity)),
735+
CachePolicy::FastLru => CacheInner::FastLru(FastLru::new(self.capacity)),
693736
CachePolicy::LruK { k } => CacheInner::LruK(LrukCache::with_k(self.capacity, k)),
694737
CachePolicy::Lfu { bucket_hint } => {
695738
let hint = bucket_hint.unwrap_or(DEFAULT_BUCKET_PREALLOC);
@@ -707,6 +750,7 @@ impl CacheBuilder {
707750
small_ratio,
708751
ghost_ratio,
709752
)),
753+
CachePolicy::Arc => CacheInner::Arc(ARCCore::new(self.capacity)),
710754
CachePolicy::Lifo => CacheInner::Lifo(LifoCore::new(self.capacity)),
711755
CachePolicy::Mfu { bucket_hint: _ } => {
712756
// MfuCore uses heap internally, bucket_hint is ignored
@@ -735,6 +779,7 @@ mod tests {
735779
let policies = [
736780
CachePolicy::Fifo,
737781
CachePolicy::Lru,
782+
CachePolicy::FastLru,
738783
CachePolicy::LruK { k: 2 },
739784
CachePolicy::Lfu { bucket_hint: None },
740785
CachePolicy::HeapLfu,
@@ -745,6 +790,7 @@ mod tests {
745790
small_ratio: 0.1,
746791
ghost_ratio: 0.9,
747792
},
793+
CachePolicy::Arc,
748794
CachePolicy::Lifo,
749795
CachePolicy::Mfu { bucket_hint: None },
750796
CachePolicy::Mru,

0 commit comments

Comments
 (0)