caches/lru/
two_queue.rs

1use crate::lru::raw::EntryNode;
2use crate::lru::{
3    swap_value, CacheError, DefaultEvictCallback, KeysLRUIter, KeysMRUIter, LRUIter, LRUIterMut,
4    MRUIter, MRUIterMut, RawLRU, ValuesLRUIter, ValuesLRUIterMut, ValuesMRUIter, ValuesMRUIterMut,
5};
6use crate::{Cache, DefaultHashBuilder, KeyRef, PutResult};
7use alloc::boxed::Box;
8use alloc::fmt;
9use core::borrow::Borrow;
10use core::hash::{BuildHasher, Hash};
11
12// f64 function polyfill to support no_std contexts
13use crate::polyfill::floor;
14
15/// `DEFAULT_2Q_RECENT_RATIO` is the ratio of the [`TwoQueueCache`] dedicated
16/// to recently added entries that have only been accessed once.
17///
18/// [`TwoQueueCache`]: struct.TwoQueueCache.html
19pub const DEFAULT_2Q_RECENT_RATIO: f64 = 0.25;
20
21/// `DEFAULT_2Q_GHOST_ENTRIES` is the default ratio of ghost
22/// entries kept to track entries recently evicted for [`TwoQueueCache`].
23///
24/// [`TwoQueueCache`]: struct.TwoQueueCache.html
25pub const DEFAULT_2Q_GHOST_RATIO: f64 = 0.5;
26
27/// `TwoQueueCacheBuilder` is used to help build a [`TwoQueueCache`] with custom configuration.
28///
29/// [`TwoQueueCache`]: struct.TwoQueueCache.html
30pub struct TwoQueueCacheBuilder<
31    RH = DefaultHashBuilder,
32    FH = DefaultHashBuilder,
33    GH = DefaultHashBuilder,
34> {
35    size: usize,
36    ghost_ratio: Option<f64>,
37    recent_ratio: Option<f64>,
38    recent_hasher: Option<RH>,
39    freq_hasher: Option<FH>,
40    ghost_hasher: Option<GH>,
41}
42
43impl Default for TwoQueueCacheBuilder {
44    /// Create a default `TwoQueueCacheBuilder`.
45    ///
46    /// # Example
47    /// ```rust
48    /// use caches::{TwoQueueCacheBuilder, TwoQueueCache, Cache};
49    /// let mut cache: TwoQueueCache<u64, u64> = TwoQueueCacheBuilder::default()
50    ///     .set_size(5)
51    ///     .finalize()
52    ///     .unwrap();
53    ///
54    /// cache.put(1, 1);
55    /// ```
56    fn default() -> Self {
57        Self {
58            size: 0,
59            ghost_ratio: Some(DEFAULT_2Q_GHOST_RATIO),
60            recent_ratio: Some(DEFAULT_2Q_RECENT_RATIO),
61            recent_hasher: Some(DefaultHashBuilder::default()),
62            freq_hasher: Some(DefaultHashBuilder::default()),
63            ghost_hasher: Some(DefaultHashBuilder::default()),
64        }
65    }
66}
67
68impl TwoQueueCacheBuilder {
69    /// Returns a default [`TwoQueueCacheBuilder`].
70    ///
71    /// # Example
72    /// ```rust
73    /// use caches::{TwoQueueCacheBuilder, TwoQueueCache, Cache};
74    /// use rustc_hash::FxHasher;
75    /// use std::hash::BuildHasherDefault;
76    ///
77    /// let mut cache = TwoQueueCacheBuilder::new(3)
78    ///     .set_recent_ratio(0.3)
79    ///     .set_ghost_ratio(0.4)
80    ///     .set_recent_hasher(BuildHasherDefault::<FxHasher>::default())
81    ///     .set_frequent_hasher(BuildHasherDefault::<FxHasher>::default())
82    ///     .set_ghost_hasher(BuildHasherDefault::<FxHasher>::default())
83    ///     .finalize::<u64, u64>()
84    ///     .unwrap();
85    ///
86    /// cache.put(1, 1);
87    /// ```
88    ///
89    /// [`TwoQueueCacheBuilder`]: struct.TwoQueueCacheBuilder.html
90    pub fn new(size: usize) -> Self {
91        Self::default().set_size(size)
92    }
93}
94
95impl<RH: BuildHasher, FH: BuildHasher, GH: BuildHasher> TwoQueueCacheBuilder<RH, FH, GH> {
96    /// Set the ghost LRU size ratio
97    pub fn set_ghost_ratio(self, ratio: f64) -> Self {
98        TwoQueueCacheBuilder {
99            size: self.size,
100            ghost_ratio: Some(ratio),
101            recent_ratio: self.recent_ratio,
102            recent_hasher: self.recent_hasher,
103            freq_hasher: self.freq_hasher,
104            ghost_hasher: self.ghost_hasher,
105        }
106    }
107
108    /// Set the recent LRU size ratio
109    pub fn set_recent_ratio(self, ratio: f64) -> Self {
110        TwoQueueCacheBuilder {
111            size: self.size,
112            ghost_ratio: self.ghost_ratio,
113            recent_ratio: Some(ratio),
114            recent_hasher: self.recent_hasher,
115            freq_hasher: self.freq_hasher,
116            ghost_hasher: self.ghost_hasher,
117        }
118    }
119
120    /// Set the cache size
121    pub fn set_size(self, size: usize) -> Self {
122        TwoQueueCacheBuilder {
123            size,
124            ghost_ratio: self.ghost_ratio,
125            recent_ratio: self.recent_ratio,
126            recent_hasher: self.recent_hasher,
127            freq_hasher: self.freq_hasher,
128            ghost_hasher: self.ghost_hasher,
129        }
130    }
131
132    /// Set the recent LRU's hash builder
133    pub fn set_recent_hasher<NRH: BuildHasher>(
134        self,
135        hasher: NRH,
136    ) -> TwoQueueCacheBuilder<NRH, FH, GH> {
137        TwoQueueCacheBuilder {
138            size: self.size,
139            ghost_ratio: self.ghost_ratio,
140            recent_ratio: self.recent_ratio,
141            recent_hasher: Some(hasher),
142            freq_hasher: self.freq_hasher,
143            ghost_hasher: self.ghost_hasher,
144        }
145    }
146
147    /// Set the frequent LRU's hash builder
148    pub fn set_frequent_hasher<NFH: BuildHasher>(
149        self,
150        hasher: NFH,
151    ) -> TwoQueueCacheBuilder<RH, NFH, GH> {
152        TwoQueueCacheBuilder {
153            size: self.size,
154            ghost_ratio: self.ghost_ratio,
155            recent_ratio: self.recent_ratio,
156            recent_hasher: self.recent_hasher,
157            freq_hasher: Some(hasher),
158            ghost_hasher: self.ghost_hasher,
159        }
160    }
161
162    /// Set the ghost LRU's hash builder
163    pub fn set_ghost_hasher<NGH: BuildHasher>(
164        self,
165        hasher: NGH,
166    ) -> TwoQueueCacheBuilder<RH, FH, NGH> {
167        TwoQueueCacheBuilder {
168            size: self.size,
169            ghost_ratio: self.ghost_ratio,
170            recent_ratio: self.recent_ratio,
171            recent_hasher: self.recent_hasher,
172            freq_hasher: self.freq_hasher,
173            ghost_hasher: Some(hasher),
174        }
175    }
176
177    /// Finalize the builder to [`TwoQueueCache`]
178    ///
179    /// [`TwoQueueCache`]: struct.TwoQueueCache.html
180    pub fn finalize<K: Hash + Eq, V>(self) -> Result<TwoQueueCache<K, V, RH, FH, GH>, CacheError> {
181        let size = self.size;
182        if size == 0 {
183            return Err(CacheError::InvalidSize(0));
184        }
185
186        let rr = self.recent_ratio.unwrap();
187        if !(0.0..=1.0).contains(&rr) {
188            return Err(CacheError::InvalidRecentRatio(rr));
189        }
190
191        let gr = self.ghost_ratio.unwrap();
192        if !(0.0..=1.0).contains(&gr) {
193            return Err(CacheError::InvalidGhostRatio(gr));
194        }
195
196        // Determine the sub-sizes
197        let rs = floor((size as f64) * rr) as usize;
198        let es = floor((size as f64) * gr) as usize;
199
200        // allocate the lrus
201
202        let recent = RawLRU::with_hasher(size, self.recent_hasher.unwrap()).unwrap();
203        let freq = RawLRU::with_hasher(size, self.freq_hasher.unwrap()).unwrap();
204
205        let ghost = RawLRU::with_hasher(es, self.ghost_hasher.unwrap()).unwrap();
206
207        Ok(TwoQueueCache {
208            size,
209            recent_size: rs,
210            recent,
211            frequent: freq,
212            ghost,
213        })
214    }
215}
216
217/// `TwoQueueCache` is a fixed size 2Q cache.
218/// 2Q is an enhancement over the standard LRU cache
219/// in that it tracks both frequently and recently used
220/// entries separately. This avoids a burst in access to new
221/// entries from evicting frequently used entries. It adds some
222/// additional tracking overhead to the [`RawLRU`] cache, and is
223/// computationally about **2x** the cost, and adds some metadata over
224/// head. The [`AdaptiveCache`] is similar to the TwoQueueCache, but does not require setting any
225/// parameters.
226///
227/// # Example
228///
229/// ```rust
230///
231/// use caches::{TwoQueueCache, Cache, PutResult};
232///
233/// let mut cache = TwoQueueCache::new(4).unwrap();
234///
235/// // Add 1,2,3,4,
236/// (1..=4).for_each(|i| {
237///     assert_eq!(cache.put(i, i), PutResult::Put);
238/// });
239///
240/// // Add 5 -> Evict 1 to ghost LRU
241/// assert_eq!(cache.put(5, 5), PutResult::Put);
242///
243/// // Pull in the recently evicted
244/// assert_eq!(cache.put(1, 1), PutResult::Update(1));
245///
246/// // Add 6, should cause another recent evict
247/// assert_eq!(cache.put(6, 6), PutResult::<i32, i32>::Put);
248///
249/// // Add 7, should evict an entry from ghost LRU.
250/// assert_eq!(cache.put(7, 7), PutResult::Evicted { key: 2, value: 2 });
251///
252/// // Add 2, should evict an entry from ghost LRU
253/// assert_eq!(cache.put(2, 11), PutResult::Evicted { key: 3, value: 3 });
254///
255/// // Add 4, should put the entry from ghost LRU to freq LRU
256/// assert_eq!(cache.put(4, 11), PutResult::Update(4));
257///
258/// // move all entry in recent to freq.
259/// assert_eq!(cache.put(2, 22), PutResult::Update(11));
260/// assert_eq!(cache.put(7, 77), PutResult::<i32, i32>::Update(7));
261///
262/// // Add 6, should put the entry from ghost LRU to freq LRU, and evicted one
263/// // entry
264/// assert_eq!(cache.put(6, 66), PutResult::EvictedAndUpdate { evicted: (5, 5), update: 6});
265/// assert_eq!(cache.recent_len(), 0);
266/// assert_eq!(cache.ghost_len(), 1);
267/// assert_eq!(cache.frequent_len(), 4);
268/// ```
269///
270/// [`RawLRU`]: struct.RawLRU.html
271/// [`AdaptiveCache`]: struct.AdaptiveCache.html
272pub struct TwoQueueCache<
273    K: Hash + Eq,
274    V,
275    RH = DefaultHashBuilder,
276    FH = DefaultHashBuilder,
277    GH = DefaultHashBuilder,
278> {
279    size: usize,
280    recent_size: usize,
281    recent: RawLRU<K, V, DefaultEvictCallback, RH>,
282    frequent: RawLRU<K, V, DefaultEvictCallback, FH>,
283    ghost: RawLRU<K, V, DefaultEvictCallback, GH>,
284}
285
286impl<K: Hash + Eq, V> TwoQueueCache<K, V> {
287    /// Create a `TwoQueueCache` with size and default configurations.
288    pub fn new(size: usize) -> Result<Self, CacheError> {
289        Self::with_2q_parameters(size, DEFAULT_2Q_RECENT_RATIO, DEFAULT_2Q_GHOST_RATIO)
290    }
291
292    /// Returns a [`TwoQueueCacheBuilder`] to help build a [`TwoQueueCache`].
293    ///
294    /// # Example
295    /// ```rust
296    /// use caches::{TwoQueueCacheBuilder, TwoQueueCache, Cache};
297    /// use rustc_hash::FxHasher;
298    /// use std::hash::BuildHasherDefault;
299    ///
300    /// let mut cache = TwoQueueCache::<u64, u64>::builder(3)
301    ///     .set_recent_ratio(0.3)
302    ///     .set_ghost_ratio(0.4)
303    ///     .set_recent_hasher(BuildHasherDefault::<FxHasher>::default())
304    ///     .set_frequent_hasher(BuildHasherDefault::<FxHasher>::default())
305    ///     .set_ghost_hasher(BuildHasherDefault::<FxHasher>::default())
306    ///     .finalize::<u64, u64>()
307    ///     .unwrap();
308    ///
309    /// cache.put(1, 1);
310    /// ```
311    ///
312    /// [`TwoQueueCacheBuilder`]: struct.TwoQueueCacheBuilder.html
313    /// [`TwoQueueCache`]: struct.TwoQueueCache.html
314    pub fn builder(size: usize) -> TwoQueueCacheBuilder {
315        TwoQueueCacheBuilder::new(size)
316    }
317
318    /// Create a cache with size and recent ratio.
319    ///
320    /// # Example
321    ///
322    /// ```rust
323    /// use caches::{Cache, TwoQueueCache};
324    ///
325    /// let mut cache: TwoQueueCache<u64, u64>= TwoQueueCache::with_recent_ratio(5, 0.3).unwrap();
326    /// ```
327    pub fn with_recent_ratio(size: usize, rr: f64) -> Result<Self, CacheError> {
328        Self::with_2q_parameters(size, rr, DEFAULT_2Q_GHOST_RATIO)
329    }
330
331    /// Create a cache with size and ghost ratio.
332    ///
333    /// # Example
334    ///
335    /// ```rust
336    /// use caches::{Cache, TwoQueueCache};
337    ///
338    /// let mut cache: TwoQueueCache<u64, u64>= TwoQueueCache::with_ghost_ratio(5, 0.6).unwrap();
339    /// ```
340    pub fn with_ghost_ratio(size: usize, gr: f64) -> Result<Self, CacheError> {
341        Self::with_2q_parameters(size, DEFAULT_2Q_RECENT_RATIO, gr)
342    }
343
344    /// Create a cache with size, recent ratio and ghost ratio
345    ///
346    /// # Example
347    ///
348    /// ```rust
349    /// use caches::{Cache, TwoQueueCache};
350    ///
351    /// let mut cache: TwoQueueCache<u64, u64>= TwoQueueCache::with_2q_parameters(5, 0.3, 0.6).unwrap();
352    /// ```
353    pub fn with_2q_parameters(size: usize, rr: f64, gr: f64) -> Result<Self, CacheError> {
354        if size == 0 {
355            return Err(CacheError::InvalidSize(size));
356        }
357
358        if !(0.0..=1.0).contains(&rr) {
359            return Err(CacheError::InvalidRecentRatio(rr));
360        }
361
362        if !(0.0..=1.0).contains(&gr) {
363            return Err(CacheError::InvalidGhostRatio(gr));
364        }
365
366        // Determine the sub-sizes
367        let rs = floor((size as f64) * rr) as usize;
368        let es = floor((size as f64) * gr) as usize;
369
370        // allocate the lrus
371        let recent = RawLRU::new(size).unwrap();
372        let freq = RawLRU::new(size).unwrap();
373
374        let ghost = RawLRU::new(es)?;
375
376        Ok(Self {
377            size,
378            recent_size: rs,
379            recent,
380            frequent: freq,
381            ghost,
382        })
383    }
384}
385
386impl<K: Hash + Eq, V, RH: BuildHasher, FH: BuildHasher, GH: BuildHasher> Cache<K, V>
387    for TwoQueueCache<K, V, RH, FH, GH>
388{
389    /// Puts a key-value pair to the cache.
390    ///
391    /// # Note
392    /// - [`TwoQueueCache`] guarantees that the size of the recent LRU plus the size of the freq LRU
393    ///   is less or equal to the [`TwoQueueCache`]'s size.
394    /// - The ghost LRU has its own size.
395    ///
396    /// # Example
397    /// ```rust
398    /// use caches::{TwoQueueCache, Cache, PutResult};
399    ///
400    /// let mut cache = TwoQueueCache::new(4).unwrap();
401    /// // Add 1,2,3,4,5 -> Evict 1
402    /// cache.put(1, 1);
403    /// cache.put(2, 2);
404    /// cache.put(3, 3);
405    /// cache.put(4, 4);
406    /// cache.put(5, 5);
407    ///
408    /// // Pull in the recently evicted
409    /// assert_eq!(cache.put(1, 1), PutResult::Update(1));
410    ///
411    /// // Add 6, should cause another recent evict
412    /// assert_eq!(cache.put(6, 6), PutResult::Put);
413    ///
414    /// // Add 7, should evict an entry from ghost LRU.
415    /// assert_eq!(cache.put(7, 7), PutResult::Evicted { key: 2, value: 2});
416    ///
417    /// // Add 2, should evict an entry from ghost LRU
418    /// assert_eq!(cache.put(2, 11), PutResult::Evicted { key: 3, value: 3});
419    ///
420    /// // Add 4, should put the entry from ghost LRU to freq LRU
421    /// assert_eq!(cache.put(4, 11), PutResult::Update(4));
422    ///
423    /// // move all entry in recent to freq.
424    /// assert_eq!(cache.put(2, 22), PutResult::Update(11));
425    /// assert_eq!(cache.put(7, 77), PutResult::Update(7));
426    ///
427    /// // Add 6, should put the entry from ghost LRU to freq LRU, and evicted one
428    /// // entry
429    /// assert_eq!(cache.put(6, 66), PutResult::EvictedAndUpdate { evicted: (5, 5), update: 6 });
430    /// ```
431    ///
432    /// [`TwoQueueCache`]: struct.TwoQueueCache.html
433    fn put(&mut self, k: K, mut v: V) -> PutResult<K, V> {
434        let key_ref = KeyRef { k: &k };
435
436        // Check if the value is frequently used already,
437        // and just update the value
438        if let Some(ent_ptr) = self.frequent.map.get_mut(&key_ref).map(|node| {
439            let node_ptr: *mut EntryNode<K, V> = node.as_ptr();
440            node_ptr
441        }) {
442            self.frequent.update(&mut v, ent_ptr);
443            return PutResult::Update(v);
444        }
445
446        // Check if the value is recently used, and promote
447        // the value into the frequent list
448        if self
449            .recent
450            // here we remove an entry from recent LRU if key exists
451            .remove_and_return_ent(&k)
452            .map(|mut ent| {
453                unsafe {
454                    swap_value(&mut v, ent.as_mut());
455                }
456                // here we add the entry to frequent LRU,
457                // the result will always be PutResult::Put
458                // because we have removed this entry from recent LRU
459                self.frequent.put_nonnull(ent)
460            })
461            .is_some()
462        {
463            return PutResult::Update(v);
464        }
465
466        // if we have space, nothing to do
467        let recent_len = self.recent.len();
468        let freq_len = self.frequent.len();
469
470        // If the value was recently evicted, add it to the
471        // frequently used list
472        if self.ghost.contains(&k) {
473            return if recent_len + freq_len >= self.size {
474                let ent = if recent_len > self.recent_size {
475                    self.recent.remove_lru_in().unwrap()
476                } else {
477                    self.frequent.remove_lru_in().unwrap()
478                };
479
480                let rst = self.ghost.put_or_evict_nonnull(ent);
481                match self.ghost.map.remove(&key_ref) {
482                    None => match rst {
483                        None => PutResult::Put,
484                        Some(mut ent) => {
485                            unsafe {
486                                let ent_ptr = ent.as_mut();
487                                core::ptr::swap(&mut v, ent_ptr.val.as_mut_ptr());
488                            }
489                            self.frequent.put_nonnull(ent);
490                            PutResult::Update(v)
491                        }
492                    },
493                    Some(mut ent) => {
494                        let ent_ptr = ent.as_ptr();
495                        self.ghost.detach(ent_ptr);
496
497                        unsafe {
498                            let ent_ref = ent.as_mut();
499                            core::ptr::swap(&mut v, ent_ref.val.as_mut_ptr());
500                            self.frequent.put_nonnull(ent);
501                            match rst {
502                                None => PutResult::Update(v),
503                                Some(ent) => {
504                                    let ptr = ent.as_ptr();
505                                    let ent = *Box::from_raw(ptr);
506                                    PutResult::EvictedAndUpdate {
507                                        evicted: (ent.key.assume_init(), ent.val.assume_init()),
508                                        update: v,
509                                    }
510                                }
511                            }
512                        }
513                    }
514                }
515            } else {
516                let mut ent = self.ghost.map.remove(&key_ref).unwrap();
517                let ent_ptr = ent.as_ptr();
518                self.ghost.detach(ent_ptr);
519                unsafe {
520                    core::ptr::swap(&mut v, ent.as_mut().val.as_mut_ptr());
521                }
522                self.frequent.put_nonnull(ent);
523                PutResult::Update(v)
524            };
525        }
526
527        // Add to the recently seen list.
528        let bks = unsafe {
529            core::ptr::NonNull::new_unchecked(Box::into_raw(Box::new(EntryNode::new(k, v))))
530        };
531        // if we have enough space, we add entry to recent LRU directly
532        if freq_len + recent_len < self.size {
533            return match self.recent.put_or_evict_nonnull(bks) {
534                None => PutResult::Put,
535                Some(evicted) => self.ghost.put_nonnull(evicted),
536            };
537        }
538
539        // The cache does not have enough space, so we remove one entry from freq LRU or recent
540        // LRU. Then, put the removed entry to the front of the ghost LRU,
541        // if ghost LRU is also full, the cache will evict the less recent used entry of
542        // ghost LRU.
543        let ent = if recent_len >= self.recent_size {
544            self.recent.remove_lru_in().unwrap()
545        } else {
546            self.frequent.remove_lru_in().unwrap()
547        };
548
549        self.recent.put_nonnull(bks);
550        self.ghost.put_nonnull(ent)
551    }
552
553    /// Returns a mutable reference to the value of the key in the cache or `None` if it
554    /// is not present in the cache. Moves the key to the head of the LRU list if it exists.
555    ///
556    /// # Example
557    ///
558    /// ```
559    /// use caches::{Cache, TwoQueueCache};
560    /// let mut cache = TwoQueueCache::new(2).unwrap();
561    ///
562    /// cache.put("apple", 8);
563    /// cache.put("banana", 4);
564    /// cache.put("banana", 6);
565    /// cache.put("pear", 2);
566    ///
567    /// assert_eq!(cache.get(&"banana"), Some(&6));
568    /// ```
569    fn get<Q>(&mut self, k: &Q) -> Option<&V>
570    where
571        K: Borrow<Q>,
572        Q: Hash + Eq + ?Sized,
573    {
574        // Check if this is a frequent value
575        self.frequent
576            .get_(k)
577            .or_else(|| {
578                self.recent
579                    .peek_(k)
580                    .and_then(|v| self.move_to_frequent(k, v))
581            })
582            .map(|v| unsafe { core::mem::transmute(v) })
583    }
584
585    /// Returns a mutable reference to the value of the key in the cache or `None` if it
586    /// is not present in the cache. Moves the key to the head of the LRU list if it exists.
587    ///
588    /// # Example
589    ///
590    /// ```
591    /// use caches::{Cache, TwoQueueCache};
592    /// let mut cache = TwoQueueCache::new(2).unwrap();
593    ///
594    /// cache.put("apple", 8);
595    /// cache.put("banana", 4);
596    /// cache.put("banana", 6);
597    /// cache.put("pear", 2);
598    ///
599    /// assert_eq!(cache.get_mut(&"apple"), None);
600    /// assert_eq!(cache.get_mut(&"banana"), Some(&mut 6));
601    /// assert_eq!(cache.get_mut(&"pear"), Some(&mut 2));
602    /// ```
603    fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
604    where
605        K: Borrow<Q>,
606        Q: Hash + Eq + ?Sized,
607    {
608        // Check if this is a frequent value
609        self.frequent
610            .get_mut_(k)
611            .or_else(|| {
612                self.recent
613                    .peek_mut_(k)
614                    .and_then(|v| self.move_to_frequent(k, v))
615            })
616            .map(|v| unsafe { core::mem::transmute(v) })
617    }
618
619    /// Returns a reference to the value corresponding to the key in the cache or `None` if it is
620    /// not present in the cache. Unlike `get`, `peek` does not update the LRU list so the key's
621    /// position will be unchanged.
622    ///
623    /// # Example
624    ///
625    /// ```
626    /// use caches::{Cache, TwoQueueCache};
627    /// let mut cache = TwoQueueCache::new(2).unwrap();
628    ///
629    /// cache.put(1, "a");
630    /// cache.put(2, "b");
631    ///
632    /// assert_eq!(cache.peek(&1), Some(&"a"));
633    /// assert_eq!(cache.peek(&2), Some(&"b"));
634    /// ```
635    fn peek<Q>(&self, k: &Q) -> Option<&V>
636    where
637        K: Borrow<Q>,
638        Q: Hash + Eq + ?Sized,
639    {
640        self.frequent.peek(k).or_else(|| self.recent.peek(k))
641    }
642
643    /// Returns a mutable reference to the value corresponding to the key in the cache or `None`
644    /// if it is not present in the cache. Unlike `get_mut`, `peek_mut` does not update the LRU
645    /// list so the key's position will be unchanged.
646    ///
647    /// # Example
648    ///
649    /// ```
650    /// use caches::{Cache, TwoQueueCache};
651    /// let mut cache = TwoQueueCache::new(2).unwrap();
652    ///
653    /// cache.put(1, "a");
654    /// cache.put(2, "b");
655    ///
656    /// assert_eq!(cache.peek_mut(&1), Some(&mut "a"));
657    /// assert_eq!(cache.peek_mut(&2), Some(&mut "b"));
658    /// ```
659    fn peek_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
660    where
661        K: Borrow<Q>,
662        Q: Hash + Eq + ?Sized,
663    {
664        match self.frequent.peek_mut(k) {
665            Some(v) => Some(v),
666            None => self.recent.peek_mut(k),
667        }
668    }
669
670    /// Removes and returns the value corresponding to the key from the cache or
671    /// `None` if it does not exist.
672    ///
673    /// # Example
674    ///
675    /// ```
676    /// use caches::{Cache, TwoQueueCache};
677    /// let mut cache = TwoQueueCache::new(2).unwrap();
678    ///
679    /// cache.put(2, "a");
680    ///
681    /// assert_eq!(cache.remove(&1), None);
682    /// assert_eq!(cache.remove(&2), Some("a"));
683    /// assert_eq!(cache.remove(&2), None);
684    /// assert_eq!(cache.len(), 0);
685    /// ```
686    fn remove<Q>(&mut self, k: &Q) -> Option<V>
687    where
688        K: Borrow<Q>,
689        Q: Hash + Eq + ?Sized,
690    {
691        self.frequent
692            .remove(k)
693            .or_else(|| self.recent.remove(k))
694            .or_else(|| self.ghost.remove(k))
695    }
696
697    /// Returns a bool indicating whether the given key is in the cache. Does not update the
698    /// LRU list.
699    ///
700    /// # Example
701    ///
702    /// ```
703    /// use caches::{Cache, TwoQueueCache};
704    /// let mut cache = TwoQueueCache::new(2).unwrap();
705    ///
706    /// cache.put(1, "a");
707    /// cache.put(2, "b");
708    /// cache.put(3, "c");
709    ///
710    /// assert!(!cache.contains(&1));
711    /// assert!(cache.contains(&2));
712    /// assert!(cache.contains(&3));
713    /// ```
714    fn contains<Q>(&self, k: &Q) -> bool
715    where
716        K: Borrow<Q>,
717        Q: Hash + Eq + ?Sized,
718    {
719        self.frequent.contains(k) || self.recent.contains(k)
720    }
721
722    /// Clears the contents of the cache.
723    ///
724    /// # Example
725    ///
726    /// ```
727    /// use caches::{Cache, TwoQueueCache};
728    /// let mut cache: TwoQueueCache<isize, &str> = TwoQueueCache::new(2).unwrap();
729    /// assert_eq!(cache.len(), 0);
730    ///
731    /// cache.put(1, "a");
732    /// assert_eq!(cache.len(), 1);
733    ///
734    /// cache.put(2, "b");
735    /// assert_eq!(cache.len(), 2);
736    ///
737    /// cache.purge();
738    /// assert_eq!(cache.len(), 0);
739    /// ```
740    fn purge(&mut self) {
741        self.frequent.purge();
742        self.recent.purge();
743        self.ghost.purge();
744    }
745
746    /// Returns the number of key-value pairs that are currently in the the cache
747    /// (excluding the length of inner ghost LRU).
748    ///
749    /// # Example
750    ///
751    /// ```
752    /// use caches::{Cache, TwoQueueCache};
753    /// let mut cache = TwoQueueCache::new(2).unwrap();
754    /// assert_eq!(cache.len(), 0);
755    ///
756    /// cache.put(1, "a");
757    /// assert_eq!(cache.len(), 1);
758    ///
759    /// cache.put(2, "b");
760    /// assert_eq!(cache.len(), 2);
761    ///
762    /// cache.put(3, "c");
763    /// assert_eq!(cache.len(), 2);
764    /// ```
765    fn len(&self) -> usize {
766        self.recent.len() + self.frequent.len()
767    }
768
769    /// Returns the maximum number of key-value pairs the cache can hold
770    /// (excluding the capacity of inner ghost LRU).
771    ///
772    /// # Example
773    ///
774    /// ```
775    /// use caches::{Cache, TwoQueueCache};
776    /// let mut cache: TwoQueueCache<isize, &str> = TwoQueueCache::new(2).unwrap();
777    /// assert_eq!(cache.cap(), 2);
778    /// ```
779    fn cap(&self) -> usize {
780        self.size
781    }
782
783    fn is_empty(&self) -> bool {
784        self.frequent.is_empty() && self.recent.is_empty() && self.ghost.is_empty()
785    }
786}
787
788impl<K: Hash + Eq, V, RH: BuildHasher, FH: BuildHasher, GH: BuildHasher>
789    TwoQueueCache<K, V, RH, FH, GH>
790{
791    /// Create a [`TwoQueueCache`] from [`TwoQueueCacheBuilder`].
792    ///
793    /// # Example
794    /// ```rust
795    /// use caches::{TwoQueueCacheBuilder, TwoQueueCache, Cache};
796    /// use rustc_hash::FxHasher;
797    /// use std::hash::BuildHasherDefault;
798    ///
799    /// let builder = TwoQueueCacheBuilder::new(5)
800    ///     .set_recent_ratio(0.3)
801    ///     .set_ghost_ratio(0.4)
802    ///     .set_recent_hasher(BuildHasherDefault::<FxHasher>::default())
803    ///     .set_frequent_hasher(BuildHasherDefault::<FxHasher>::default())
804    ///     .set_ghost_hasher(BuildHasherDefault::<FxHasher>::default());
805    ///
806    /// let mut cache = TwoQueueCache::from_builder(builder).unwrap();
807    /// cache.put(1, 1);
808    /// ```
809    ///
810    /// [`TwoQueueCacheBuilder`]: struct.TwoQueueCacheBuilder.html
811    /// [`TwoQueueCache`]: struct.TwoQueueCache.html
812    pub fn from_builder(builder: TwoQueueCacheBuilder<RH, FH, GH>) -> Result<Self, CacheError> {
813        builder.finalize()
814    }
815
816    /// Returns the number of key-value pairs that are currently in the the recent LRU.
817    pub fn recent_len(&self) -> usize {
818        self.recent.len()
819    }
820
821    /// Returns the number of key-value pairs that are currently in the the frequent LRU.
822    pub fn frequent_len(&self) -> usize {
823        self.frequent.len()
824    }
825
826    /// Returns the number of key-value pairs that are currently in the the ghost LRU.
827    pub fn ghost_len(&self) -> usize {
828        self.ghost.len()
829    }
830
831    /// An iterator visiting all keys of recent LRU in most-recently used order. The iterator element type is
832    /// `&'a K`.
833    ///
834    /// # Examples
835    ///
836    /// ```
837    /// use caches::{Cache, TwoQueueCache};
838    ///
839    /// let mut cache = TwoQueueCache::new(3).unwrap();
840    /// cache.put("a", 1);
841    /// cache.put("b", 2);
842    /// cache.put("c", 3);
843    ///
844    /// for key in cache.recent_keys() {
845    ///     println!("key: {}", key);
846    /// }
847    /// ```
848    pub fn recent_keys(&self) -> KeysMRUIter<'_, K, V> {
849        self.recent.keys()
850    }
851
852    /// An iterator visiting all keys of recent LRU in less-recently used order. The iterator element type is
853    /// `&'a K`.
854    ///
855    /// # Examples
856    ///
857    /// ```
858    /// use caches::{Cache, TwoQueueCache};
859    ///
860    /// let mut cache = TwoQueueCache::new(3).unwrap();
861    /// cache.put("a", 1);
862    /// cache.put("b", 2);
863    /// cache.put("c", 3);
864    ///
865    /// for key in cache.recent_keys_lru() {
866    ///     println!("key: {}", key);
867    /// }
868    /// ```
869    pub fn recent_keys_lru(&self) -> KeysLRUIter<'_, K, V> {
870        self.recent.keys_lru()
871    }
872
873    /// An iterator visiting all values of recent LRU in most-recently used order. The iterator element type is
874    /// `&'a V`.
875    ///
876    /// # Examples
877    ///
878    /// ```
879    /// use caches::{Cache, TwoQueueCache};
880    ///
881    /// let mut cache = TwoQueueCache::new(3).unwrap();
882    /// cache.put("a", 1);
883    /// cache.put("b", 2);
884    /// cache.put("c", 3);
885    ///
886    /// for val in cache.recent_values() {
887    ///     println!("val: {}",  val);
888    /// }
889    /// ```
890    pub fn recent_values(&self) -> ValuesMRUIter<'_, K, V> {
891        self.recent.values()
892    }
893
894    /// An iterator visiting all values in less-recently used order. The iterator element type is
895    /// `&'a V`.
896    ///
897    /// # Examples
898    ///
899    /// ```
900    /// use caches::{Cache, TwoQueueCache};
901    ///
902    /// let mut cache = TwoQueueCache::new(3).unwrap();
903    /// cache.put("a", 1);
904    /// cache.put("b", 2);
905    /// cache.put("c", 3);
906    ///
907    /// for val in cache.recent_values_lru() {
908    ///     println!("val: {}", val);
909    /// }
910    /// ```
911    pub fn recent_values_lru(&self) -> ValuesLRUIter<'_, K, V> {
912        self.recent.values_lru()
913    }
914
915    /// An iterator visiting all values of recent LRU in most-recently used order. The iterator element type is
916    /// `&'a mut V`.
917    ///
918    /// # Examples
919    ///
920    /// ```
921    /// use caches::{Cache, TwoQueueCache};
922    ///
923    /// let mut cache = TwoQueueCache::new(3).unwrap();
924    /// cache.put("a", 1);
925    /// cache.put("b", 2);
926    /// cache.put("c", 3);
927    ///
928    /// for val in cache.recent_values_mut() {
929    ///     println!("val: {}", val);
930    /// }
931    /// ```
932    pub fn recent_values_mut(&mut self) -> ValuesMRUIterMut<'_, K, V> {
933        self.recent.values_mut()
934    }
935
936    /// An iterator visiting all values of recent LRU in less-recently used order. The iterator element type is
937    /// `&'a mut V`.
938    ///
939    /// # Examples
940    ///
941    /// ```
942    /// use caches::{Cache, TwoQueueCache};
943    ///
944    /// let mut cache = TwoQueueCache::new(3).unwrap();
945    /// cache.put("a", 1);
946    /// cache.put("b", 2);
947    /// cache.put("c", 3);
948    ///
949    /// for val in cache.recent_values_lru_mut() {
950    ///     println!("val: {}", val);
951    /// }
952    /// ```
953    pub fn recent_values_lru_mut(&mut self) -> ValuesLRUIterMut<'_, K, V> {
954        self.recent.values_lru_mut()
955    }
956
957    /// An iterator visiting all entries of recent LRU in most-recently used order. The iterator element type is
958    /// `(&'a K, &'a V)`.
959    ///
960    /// # Examples
961    ///
962    /// ```
963    /// use caches::{Cache, TwoQueueCache};
964    ///
965    /// let mut cache = TwoQueueCache::new(3).unwrap();
966    /// cache.put("a", 1);
967    /// cache.put("b", 2);
968    /// cache.put("c", 3);
969    ///
970    /// for (key, val) in cache.recent_iter() {
971    ///     println!("key: {} val: {}", key, val);
972    /// }
973    /// ```
974    pub fn recent_iter(&self) -> MRUIter<'_, K, V> {
975        self.recent.iter()
976    }
977
978    /// An iterator visiting all entries of recent LRU in less-recently used order. The iterator element type is
979    /// `(&'a K, &'a V)`.
980    ///
981    /// # Examples
982    ///
983    /// ```
984    /// use caches::{Cache, TwoQueueCache};
985    ///
986    /// let mut cache = TwoQueueCache::new(3).unwrap();
987    /// cache.put("a", 1);
988    /// cache.put("b", 2);
989    /// cache.put("c", 3);
990    ///
991    /// for (key, val) in cache.recent_iter_lru() {
992    ///     println!("key: {} val: {}", key, val);
993    /// }
994    /// ```
995    pub fn recent_iter_lru(&self) -> LRUIter<'_, K, V> {
996        self.recent.iter_lru()
997    }
998
999    /// An iterator visiting all entries of recent LRU in most-recently-used order, giving a mutable reference on
1000    /// V.  The iterator element type is `(&'a K, &'a mut V)`.
1001    ///
1002    /// # Examples
1003    ///
1004    /// ```
1005    /// use caches::{Cache, TwoQueueCache};
1006    ///
1007    /// struct HddBlock {
1008    ///     idx: u64,
1009    ///     dirty: bool,
1010    ///     data: [u8; 512]
1011    /// }
1012    ///
1013    /// let mut cache = TwoQueueCache::new(3).unwrap();
1014    ///
1015    /// // put in recent list
1016    /// cache.put(0, HddBlock { idx: 0, dirty: false, data: [0x00; 512]});
1017    /// cache.put(1, HddBlock { idx: 1, dirty: true,  data: [0x55; 512]});
1018    /// cache.put(2, HddBlock { idx: 2, dirty: true,  data: [0x77; 512]});
1019    ///
1020    /// let mut ctr = 2i32;
1021    /// // write dirty blocks to disk.
1022    /// for (block_id, block) in cache.recent_iter_mut() {
1023    ///     if block.dirty {
1024    ///         // write block to disk
1025    ///         block.dirty = false
1026    ///     }
1027    ///     assert_eq!(*block_id, ctr);
1028    ///     ctr -= 1;
1029    /// }
1030    /// ```
1031    pub fn recent_iter_mut(&mut self) -> MRUIterMut<'_, K, V> {
1032        self.recent.iter_mut()
1033    }
1034
1035    /// An iterator visiting all entries of recent LRU in less-recently-used order, giving a mutable reference on
1036    /// V.  The iterator element type is `(&'a K, &'a mut V)`.
1037    ///
1038    /// # Examples
1039    ///
1040    /// ```
1041    /// use caches::{Cache, TwoQueueCache};
1042    ///
1043    /// struct HddBlock {
1044    ///     idx: u64,
1045    ///     dirty: bool,
1046    ///     data: [u8; 512]
1047    /// }
1048    ///
1049    /// let mut cache = TwoQueueCache::new(3).unwrap();
1050    ///
1051    /// // put in recent list
1052    /// cache.put(0, HddBlock { idx: 0, dirty: false, data: [0x00; 512]});
1053    /// cache.put(1, HddBlock { idx: 1, dirty: true,  data: [0x55; 512]});
1054    /// cache.put(2, HddBlock { idx: 2, dirty: true,  data: [0x77; 512]});
1055    ///
1056    /// // upgrade to frequent list
1057    /// cache.put(0, HddBlock { idx: 0, dirty: false, data: [0x00; 512]});
1058    /// cache.put(1, HddBlock { idx: 1, dirty: true,  data: [0x55; 512]});
1059    /// cache.put(2, HddBlock { idx: 2, dirty: true,  data: [0x77; 512]});
1060    ///
1061    /// let mut ctr = 0i32;
1062    ///
1063    /// // write dirty blocks to disk.
1064    /// for (block_id, block) in cache.frequent_iter_lru_mut() {
1065    ///     if block.dirty {
1066    ///         // write block to disk
1067    ///         block.dirty = false
1068    ///     }
1069    ///     assert_eq!(*block_id, ctr);
1070    ///     ctr += 1;
1071    /// }
1072    /// ```
1073    pub fn recent_iter_lru_mut(&mut self) -> LRUIterMut<'_, K, V> {
1074        self.recent.iter_lru_mut()
1075    }
1076
1077    /// An iterator visiting all keys of ghost LRU in most-recently used order. The iterator element type is
1078    /// `&'a K`.
1079    ///
1080    /// # Examples
1081    ///
1082    /// ```
1083    /// use caches::{Cache, TwoQueueCache};
1084    ///
1085    /// let mut cache = TwoQueueCache::new(3).unwrap();
1086    /// cache.put("a", 1);
1087    /// cache.put("b", 2);
1088    /// cache.put("c", 3);
1089    ///
1090    /// for key in cache.ghost_keys() {
1091    ///     println!("key: {}", key);
1092    /// }
1093    /// ```
1094    pub fn ghost_keys(&self) -> KeysMRUIter<'_, K, V> {
1095        self.ghost.keys()
1096    }
1097
1098    /// An iterator visiting all keys of ghost LRU in less-recently used order. The iterator element type is
1099    /// `&'a K`.
1100    ///
1101    /// # Examples
1102    ///
1103    /// ```
1104    /// use caches::{Cache, TwoQueueCache};
1105    ///
1106    /// let mut cache = TwoQueueCache::new(3).unwrap();
1107    /// cache.put("a", 1);
1108    /// cache.put("b", 2);
1109    /// cache.put("c", 3);
1110    ///
1111    /// for key in cache.ghost_keys_lru() {
1112    ///     println!("key: {}", key);
1113    /// }
1114    /// ```
1115    pub fn ghost_keys_lru(&self) -> KeysLRUIter<'_, K, V> {
1116        self.ghost.keys_lru()
1117    }
1118
1119    /// An iterator visiting all values of ghost LRU in most-recently used order. The iterator element type is
1120    /// `&'a V`.
1121    ///
1122    /// # Examples
1123    ///
1124    /// ```
1125    /// use caches::{Cache, TwoQueueCache};
1126    ///
1127    /// let mut cache = TwoQueueCache::new(3).unwrap();
1128    /// cache.put("a", 1);
1129    /// cache.put("b", 2);
1130    /// cache.put("c", 3);
1131    ///
1132    /// for val in cache.ghost_values() {
1133    ///     println!("val: {}",  val);
1134    /// }
1135    /// ```
1136    pub fn ghost_values(&self) -> ValuesMRUIter<'_, K, V> {
1137        self.ghost.values()
1138    }
1139
1140    /// An iterator visiting all values in less-recently used order. The iterator element type is
1141    /// `&'a V`.
1142    ///
1143    /// # Examples
1144    ///
1145    /// ```
1146    /// use caches::{Cache, TwoQueueCache};
1147    ///
1148    /// let mut cache = TwoQueueCache::new(3).unwrap();
1149    /// cache.put("a", 1);
1150    /// cache.put("b", 2);
1151    /// cache.put("c", 3);
1152    ///
1153    /// for val in cache.ghost_values_lru() {
1154    ///     println!("val: {}", val);
1155    /// }
1156    /// ```
1157    pub fn ghost_values_lru(&self) -> ValuesLRUIter<'_, K, V> {
1158        self.ghost.values_lru()
1159    }
1160
1161    /// An iterator visiting all values of ghost LRU in most-recently used order. The iterator element type is
1162    /// `&'a mut V`.
1163    ///
1164    /// # Examples
1165    ///
1166    /// ```
1167    /// use caches::{Cache, TwoQueueCache};
1168    ///
1169    /// let mut cache = TwoQueueCache::new(3).unwrap();
1170    /// cache.put("a", 1);
1171    /// cache.put("b", 2);
1172    /// cache.put("c", 3);
1173    ///
1174    /// for val in cache.ghost_values_mut() {
1175    ///     println!("val: {}", val);
1176    /// }
1177    /// ```
1178    pub fn ghost_values_mut(&mut self) -> ValuesMRUIterMut<'_, K, V> {
1179        self.ghost.values_mut()
1180    }
1181
1182    /// An iterator visiting all values of ghost LRU in less-recently used order. The iterator element type is
1183    /// `&'a mut V`.
1184    ///
1185    /// # Examples
1186    ///
1187    /// ```
1188    /// use caches::{Cache, TwoQueueCache};
1189    ///
1190    /// let mut cache = TwoQueueCache::new(3).unwrap();
1191    /// cache.put("a", 1);
1192    /// cache.put("b", 2);
1193    /// cache.put("c", 3);
1194    ///
1195    /// for val in cache.ghost_values_lru_mut() {
1196    ///     println!("val: {}", val);
1197    /// }
1198    /// ```
1199    pub fn ghost_values_lru_mut(&mut self) -> ValuesLRUIterMut<'_, K, V> {
1200        self.ghost.values_lru_mut()
1201    }
1202
1203    /// An iterator visiting all entries of ghost LRU in most-recently used order. The iterator element type is
1204    /// `(&'a K, &'a V)`.
1205    ///
1206    /// # Examples
1207    ///
1208    /// ```
1209    /// use caches::{Cache, TwoQueueCache};
1210    ///
1211    /// let mut cache = TwoQueueCache::new(3).unwrap();
1212    /// cache.put("a", 1);
1213    /// cache.put("b", 2);
1214    /// cache.put("c", 3);
1215    ///
1216    /// for (key, val) in cache.ghost_iter() {
1217    ///     println!("key: {} val: {}", key, val);
1218    /// }
1219    /// ```
1220    pub fn ghost_iter(&self) -> MRUIter<'_, K, V> {
1221        self.ghost.iter()
1222    }
1223
1224    /// An iterator visiting all entries of ghost LRU in less-recently used order. The iterator element type is
1225    /// `(&'a K, &'a V)`.
1226    ///
1227    /// # Examples
1228    ///
1229    /// ```
1230    /// use caches::{Cache, TwoQueueCache};
1231    ///
1232    /// let mut cache = TwoQueueCache::new(3).unwrap();
1233    /// cache.put("a", 1);
1234    /// cache.put("b", 2);
1235    /// cache.put("c", 3);
1236    ///
1237    /// for (key, val) in cache.ghost_iter_lru() {
1238    ///     println!("key: {} val: {}", key, val);
1239    /// }
1240    /// ```
1241    pub fn ghost_iter_lru(&self) -> LRUIter<'_, K, V> {
1242        self.ghost.iter_lru()
1243    }
1244
1245    /// An iterator visiting all entries of ghost LRU in most-recently-used order, giving a mutable reference on
1246    /// V.  The iterator element type is `(&'a K, &'a mut V)`.
1247    ///
1248    /// # Examples
1249    ///
1250    /// ```
1251    /// use caches::{Cache, TwoQueueCache};
1252    ///
1253    /// struct HddBlock {
1254    ///     idx: u64,
1255    ///     dirty: bool,
1256    ///     data: [u8; 512]
1257    /// }
1258    ///
1259    /// let mut cache = TwoQueueCache::new(3).unwrap();
1260    ///
1261    /// // put in recent list
1262    /// cache.put(0, HddBlock { idx: 0, dirty: false, data: [0x00; 512]});
1263    /// cache.put(1, HddBlock { idx: 1, dirty: true,  data: [0x55; 512]});
1264    /// cache.put(2, HddBlock { idx: 2, dirty: true,  data: [0x77; 512]});
1265    ///
1266    /// // upgrade to frequent list
1267    /// cache.put(0, HddBlock { idx: 0, dirty: false, data: [0x00; 512]});
1268    /// cache.put(1, HddBlock { idx: 1, dirty: true,  data: [0x55; 512]});
1269    /// cache.put(2, HddBlock { idx: 2, dirty: true,  data: [0x77; 512]});
1270    ///
1271    /// let mut ctr = 2i32;
1272    /// // write dirty blocks to disk.
1273    /// for (block_id, block) in cache.ghost_iter_mut() {
1274    ///     if block.dirty {
1275    ///         // write block to disk
1276    ///         block.dirty = false
1277    ///     }
1278    ///     assert_eq!(*block_id, ctr);
1279    ///     ctr -= 1;
1280    /// }
1281    /// ```
1282    pub fn ghost_iter_mut(&mut self) -> MRUIterMut<'_, K, V> {
1283        self.ghost.iter_mut()
1284    }
1285
1286    /// An iterator visiting all entries of ghost LRU in less-recently-used order, giving a mutable reference on
1287    /// V.  The iterator element type is `(&'a K, &'a mut V)`.
1288    ///
1289    /// # Examples
1290    ///
1291    /// ```
1292    /// use caches::{Cache, TwoQueueCache};
1293    ///
1294    /// struct HddBlock {
1295    ///     idx: u64,
1296    ///     dirty: bool,
1297    ///     data: [u8; 512]
1298    /// }
1299    ///
1300    /// let mut cache = TwoQueueCache::new(3).unwrap();
1301    ///
1302    /// // put in recent list
1303    /// cache.put(0, HddBlock { idx: 0, dirty: false, data: [0x00; 512]});
1304    /// cache.put(1, HddBlock { idx: 1, dirty: true,  data: [0x55; 512]});
1305    /// cache.put(2, HddBlock { idx: 2, dirty: true,  data: [0x77; 512]});
1306    ///
1307    /// // upgrade to frequent list
1308    /// cache.put(0, HddBlock { idx: 0, dirty: false, data: [0x00; 512]});
1309    /// cache.put(1, HddBlock { idx: 1, dirty: true,  data: [0x55; 512]});
1310    /// cache.put(2, HddBlock { idx: 2, dirty: true,  data: [0x77; 512]});
1311    ///
1312    /// let mut ctr = 0i32;
1313    ///
1314    /// // write dirty blocks to disk.
1315    /// for (block_id, block) in cache.frequent_iter_lru_mut() {
1316    ///     if block.dirty {
1317    ///         // write block to disk
1318    ///         block.dirty = false
1319    ///     }
1320    ///     assert_eq!(*block_id, ctr);
1321    ///     ctr += 1;
1322    /// }
1323    /// ```
1324    pub fn ghost_iter_lru_mut(&mut self) -> LRUIterMut<'_, K, V> {
1325        self.ghost.iter_lru_mut()
1326    }
1327
1328    /// An iterator visiting all keys of frequent LRU in most-recently used order. The iterator element type is
1329    /// `&'a K`.
1330    ///
1331    /// # Examples
1332    ///
1333    /// ```
1334    /// use caches::{Cache, TwoQueueCache};
1335    ///
1336    /// let mut cache = TwoQueueCache::new(3).unwrap();
1337    /// cache.put("a", 1);
1338    /// cache.put("b", 2);
1339    /// cache.put("c", 3);
1340    ///
1341    /// for key in cache.frequent_keys() {
1342    ///     println!("key: {}", key);
1343    /// }
1344    /// ```
1345    pub fn frequent_keys(&self) -> KeysMRUIter<'_, K, V> {
1346        self.frequent.keys()
1347    }
1348
1349    /// An iterator visiting all keys of frequent LRU in less-recently used order. The iterator element type is
1350    /// `&'a K`.
1351    ///
1352    /// # Examples
1353    ///
1354    /// ```
1355    /// use caches::{Cache, TwoQueueCache};
1356    ///
1357    /// let mut cache = TwoQueueCache::new(3).unwrap();
1358    /// cache.put("a", 1);
1359    /// cache.put("b", 2);
1360    /// cache.put("c", 3);
1361    ///
1362    /// for key in cache.frequent_keys_lru() {
1363    ///     println!("key: {}", key);
1364    /// }
1365    /// ```
1366    pub fn frequent_keys_lru(&self) -> KeysLRUIter<'_, K, V> {
1367        self.frequent.keys_lru()
1368    }
1369
1370    /// An iterator visiting all values of frequent LRU in most-recently used order. The iterator element type is
1371    /// `&'a V`.
1372    ///
1373    /// # Examples
1374    ///
1375    /// ```
1376    /// use caches::{Cache, TwoQueueCache};
1377    ///
1378    /// let mut cache = TwoQueueCache::new(3).unwrap();
1379    /// cache.put("a", 1);
1380    /// cache.put("b", 2);
1381    /// cache.put("c", 3);
1382    ///
1383    /// for val in cache.frequent_values() {
1384    ///     println!("val: {}",  val);
1385    /// }
1386    /// ```
1387    pub fn frequent_values(&self) -> ValuesMRUIter<'_, K, V> {
1388        self.frequent.values()
1389    }
1390
1391    /// An iterator visiting all values of frequent LRU in less-recently used order. The iterator element type is
1392    /// `&'a V`.
1393    ///
1394    /// # Examples
1395    ///
1396    /// ```
1397    /// use caches::{Cache, TwoQueueCache};
1398    ///
1399    /// let mut cache = TwoQueueCache::new(3).unwrap();
1400    /// cache.put("a", 1);
1401    /// cache.put("b", 2);
1402    /// cache.put("c", 3);
1403    ///
1404    /// for val in cache.frequent_values_lru() {
1405    ///     println!("val: {}", val);
1406    /// }
1407    /// ```
1408    pub fn frequent_values_lru(&self) -> ValuesLRUIter<'_, K, V> {
1409        self.frequent.values_lru()
1410    }
1411
1412    /// An iterator visiting all values of frequent LRU in most-recently used order. The iterator element type is
1413    /// `&'a mut V`.
1414    ///
1415    /// # Examples
1416    ///
1417    /// ```
1418    /// use caches::{Cache, TwoQueueCache};
1419    ///
1420    /// let mut cache = TwoQueueCache::new(3).unwrap();
1421    /// cache.put("a", 1);
1422    /// cache.put("b", 2);
1423    /// cache.put("c", 3);
1424    ///
1425    /// for val in cache.frequent_values_mut() {
1426    ///     println!("val: {}", val);
1427    /// }
1428    /// ```
1429    pub fn frequent_values_mut(&mut self) -> ValuesMRUIterMut<'_, K, V> {
1430        self.frequent.values_mut()
1431    }
1432
1433    /// An iterator visiting all values of frequent LRU in less-recently used order. The iterator element type is
1434    /// `&'a mut V`.
1435    ///
1436    /// # Examples
1437    ///
1438    /// ```
1439    /// use caches::{Cache, TwoQueueCache};
1440    ///
1441    /// let mut cache = TwoQueueCache::new(3).unwrap();
1442    /// cache.put("a", 1);
1443    /// cache.put("b", 2);
1444    /// cache.put("c", 3);
1445    ///
1446    /// for val in cache.frequent_values_lru_mut() {
1447    ///     println!("val: {}", val);
1448    /// }
1449    /// ```
1450    pub fn frequent_values_lru_mut(&mut self) -> ValuesLRUIterMut<'_, K, V> {
1451        self.frequent.values_lru_mut()
1452    }
1453
1454    /// An iterator visiting all entries of frequent LRU in most-recently used order. The iterator element type is
1455    /// `(&'a K, &'a V)`.
1456    ///
1457    /// # Examples
1458    ///
1459    /// ```
1460    /// use caches::{Cache, TwoQueueCache};
1461    ///
1462    /// let mut cache = TwoQueueCache::new(3).unwrap();
1463    /// cache.put("a", 1);
1464    /// cache.put("b", 2);
1465    /// cache.put("c", 3);
1466    ///
1467    /// for (key, val) in cache.frequent_iter() {
1468    ///     println!("key: {} val: {}", key, val);
1469    /// }
1470    /// ```
1471    pub fn frequent_iter(&self) -> MRUIter<'_, K, V> {
1472        self.frequent.iter()
1473    }
1474
1475    /// An iterator visiting all entries of frequent LRU in less-recently used order. The iterator element type is
1476    /// `(&'a K, &'a V)`.
1477    ///
1478    /// # Examples
1479    ///
1480    /// ```
1481    /// use caches::{Cache, TwoQueueCache};
1482    ///
1483    /// let mut cache = TwoQueueCache::new(3).unwrap();
1484    /// cache.put("a", 1);
1485    /// cache.put("b", 2);
1486    /// cache.put("c", 3);
1487    ///
1488    /// for (key, val) in cache.frequent_iter_lru() {
1489    ///     println!("key: {} val: {}", key, val);
1490    /// }
1491    /// ```
1492    pub fn frequent_iter_lru(&self) -> LRUIter<'_, K, V> {
1493        self.frequent.iter_lru()
1494    }
1495
1496    /// An iterator visiting all entries of frequent LRU in most-recently-used order, giving a mutable reference on
1497    /// V.  The iterator element type is `(&'a K, &'a mut V)`.
1498    ///
1499    /// # Examples
1500    ///
1501    /// ```
1502    /// use caches::{Cache, TwoQueueCache};
1503    ///
1504    /// struct HddBlock {
1505    ///     idx: u64,
1506    ///     dirty: bool,
1507    ///     data: [u8; 512]
1508    /// }
1509    ///
1510    /// let mut cache = TwoQueueCache::new(3).unwrap();
1511    ///
1512    /// // put in recent list
1513    /// cache.put(0, HddBlock { idx: 0, dirty: false, data: [0x00; 512]});
1514    /// cache.put(1, HddBlock { idx: 1, dirty: true,  data: [0x55; 512]});
1515    /// cache.put(2, HddBlock { idx: 2, dirty: true,  data: [0x77; 512]});
1516    ///
1517    /// // upgrade to frequent list
1518    /// cache.put(0, HddBlock { idx: 0, dirty: false, data: [0x00; 512]});
1519    /// cache.put(1, HddBlock { idx: 1, dirty: true,  data: [0x55; 512]});
1520    /// cache.put(2, HddBlock { idx: 2, dirty: true,  data: [0x77; 512]});
1521    ///
1522    /// let mut ctr = 2i32;
1523    /// // write dirty blocks to disk.
1524    /// for (block_id, block) in cache.frequent_iter_mut() {
1525    ///     if block.dirty {
1526    ///         // write block to disk
1527    ///         block.dirty = false
1528    ///     }
1529    ///     assert_eq!(*block_id, ctr);
1530    ///     ctr -= 1;
1531    /// }
1532    /// ```
1533    pub fn frequent_iter_mut(&mut self) -> MRUIterMut<'_, K, V> {
1534        self.frequent.iter_mut()
1535    }
1536
1537    /// An iterator visiting all entries of frequent LRU in less-recently-used order, giving a mutable reference on
1538    /// V.  The iterator element type is `(&'a K, &'a mut V)`.
1539    ///
1540    /// # Examples
1541    ///
1542    /// ```
1543    /// use caches::{Cache, TwoQueueCache};
1544    ///
1545    /// struct HddBlock {
1546    ///     idx: u64,
1547    ///     dirty: bool,
1548    ///     data: [u8; 512]
1549    /// }
1550    ///
1551    /// let mut cache = TwoQueueCache::new(3).unwrap();
1552    ///
1553    /// // put in recent list
1554    /// cache.put(0, HddBlock { idx: 0, dirty: false, data: [0x00; 512]});
1555    /// cache.put(1, HddBlock { idx: 1, dirty: true,  data: [0x55; 512]});
1556    /// cache.put(2, HddBlock { idx: 2, dirty: true,  data: [0x77; 512]});
1557    ///
1558    /// // upgrade to frequent list
1559    /// cache.put(0, HddBlock { idx: 0, dirty: false, data: [0x00; 512]});
1560    /// cache.put(1, HddBlock { idx: 1, dirty: true,  data: [0x55; 512]});
1561    /// cache.put(2, HddBlock { idx: 2, dirty: true,  data: [0x77; 512]});
1562    ///
1563    /// let mut ctr = 0i32;
1564    ///
1565    /// // write dirty blocks to disk.
1566    /// for (block_id, block) in cache.frequent_iter_lru_mut() {
1567    ///     if block.dirty {
1568    ///         // write block to disk
1569    ///         block.dirty = false
1570    ///     }
1571    ///     assert_eq!(*block_id, ctr);
1572    ///     ctr += 1;
1573    /// }
1574    /// ```
1575    pub fn frequent_iter_lru_mut(&mut self) -> LRUIterMut<'_, K, V> {
1576        self.frequent.iter_lru_mut()
1577    }
1578
1579    fn move_to_frequent<T, Q>(&mut self, k: &Q, v: T) -> Option<T>
1580    where
1581        K: Borrow<Q>,
1582        Q: Hash + Eq + ?Sized,
1583    {
1584        // remove the element from the recent LRU
1585        // and put it in frequent LRU.
1586        if let Some(ent) = self.recent.remove_and_return_ent(k) {
1587            match self.frequent.put_or_evict_nonnull(ent) {
1588                None => Some(v),
1589                // the Some branch will not reach, because we remove one from
1590                // recent LRU, and add this one to frequent LRU, the total size
1591                // of the cache is not changed. We still keep this for good measure.
1592                Some(_) => Some(v),
1593            }
1594        } else {
1595            None
1596        }
1597    }
1598}
1599
1600impl<K: Hash + Eq, V, RH: BuildHasher, FH: BuildHasher, GH: BuildHasher> fmt::Debug
1601    for TwoQueueCache<K, V, RH, FH, GH>
1602{
1603    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1604        f.debug_struct("TwoQueueCache")
1605            .field("len", &self.len())
1606            .field("cap", &self.cap())
1607            .finish()
1608    }
1609}
1610
1611#[cfg(test)]
1612mod test {
1613    use crate::lru::two_queue::TwoQueueCache;
1614    use crate::lru::CacheError;
1615    use crate::{Cache, PutResult};
1616    use alloc::vec::Vec;
1617    use rand::seq::SliceRandom;
1618    use rand::{thread_rng, Rng};
1619    use std::format;
1620
1621    #[cfg_attr(miri, ignore)]
1622    #[test]
1623    fn test_2q_cache_random_ops() {
1624        let size = 128;
1625        let mut rng = thread_rng();
1626        let mut cases: Vec<u64> = (0..200_000).collect();
1627        cases.shuffle(&mut rng);
1628
1629        let mut cache = TwoQueueCache::new(size).unwrap();
1630
1631        (0..200_000).for_each(|_i| {
1632            let k = rng.gen::<i64>() % 512;
1633            let r: i64 = rng.gen();
1634
1635            match r % 3 {
1636                0 => {
1637                    let _ = cache.put(k, k);
1638                }
1639                1 => {
1640                    let _ = cache.get(&k);
1641                }
1642                2 => {
1643                    let _ = cache.remove(&k);
1644                }
1645                _ => {}
1646            }
1647
1648            assert!(cache.recent.len() + cache.frequent.len() <= size)
1649        })
1650    }
1651
1652    #[test]
1653    fn test_cache_error() {
1654        let cache = TwoQueueCache::<usize, usize>::with_ghost_ratio(0, 3.0).unwrap_err();
1655        assert_eq!(CacheError::InvalidSize(0), cache);
1656
1657        let cache = TwoQueueCache::<usize, usize>::with_ghost_ratio(3, 3.0).unwrap_err();
1658        assert_eq!(CacheError::InvalidGhostRatio(3.0), cache);
1659
1660        let cache = TwoQueueCache::<usize, usize>::with_recent_ratio(3, 3.0).unwrap_err();
1661        assert_eq!(CacheError::InvalidRecentRatio(3.0), cache);
1662    }
1663
1664    #[test]
1665    fn test_2q_cache_get_recent_to_freq() {
1666        let mut cache = TwoQueueCache::new(128).unwrap();
1667        (0..128).for_each(|i| {
1668            let _ = cache.put(i, i);
1669        });
1670
1671        assert_eq!(cache.recent.len(), 128);
1672        assert_eq!(cache.frequent.len(), 0);
1673
1674        (0..128).for_each(|i| {
1675            let v = cache.get(&i);
1676            assert_ne!(v, None, "missing: {}", i);
1677        });
1678
1679        assert_eq!(cache.recent.len(), 0);
1680        assert_eq!(cache.frequent.len(), 128);
1681    }
1682
1683    #[test]
1684    fn test_2q_cache_put_recent_to_freq() {
1685        let mut cache = TwoQueueCache::new(128).unwrap();
1686
1687        // Add initially to recent
1688        cache.put(1, 1);
1689        assert_eq!(cache.recent.len(), 1);
1690        assert_eq!(cache.frequent.len(), 0);
1691
1692        // Add should upgrade to frequent
1693        cache.put(1, 1);
1694        assert_eq!(cache.recent.len(), 0);
1695        assert_eq!(cache.frequent.len(), 1);
1696
1697        // Add should remain in frequent
1698        cache.put(1, 1);
1699        assert_eq!(cache.recent.len(), 0);
1700        assert_eq!(cache.frequent.len(), 1);
1701    }
1702
1703    #[test]
1704    fn test_2q_cache_put() {
1705        let mut cache = TwoQueueCache::new(4).unwrap();
1706
1707        // Add 1,2,3,4,5 -> Evict 1
1708        cache.put(1, 1);
1709        cache.put(2, 2);
1710        cache.put(3, 3);
1711        cache.put(4, 4);
1712        cache.put(5, 5);
1713        assert_eq!(cache.recent.len(), 4);
1714        assert_eq!(cache.ghost.len(), 1,);
1715        assert_eq!(cache.frequent.len(), 0);
1716
1717        // Pull in the recently evicted
1718        assert_eq!(cache.put(1, 1), PutResult::Update(1));
1719        assert_eq!(cache.recent.len(), 3);
1720        assert_eq!(cache.ghost.len(), 1,);
1721        assert_eq!(cache.frequent.len(), 1);
1722
1723        // Add 6, should cause another recent evict
1724        assert_eq!(
1725            format!("{:?}", cache.put(6, 6).clone()),
1726            format!("{:?}", PutResult::<i32, i32>::Put)
1727        );
1728        assert_eq!(cache.recent.len(), 3);
1729        assert_eq!(cache.ghost.len(), 2,);
1730        assert_eq!(cache.frequent.len(), 1);
1731
1732        // Add 7, should evict an entry from ghost LRU.
1733        assert_eq!(cache.put(7, 7), PutResult::Evicted { key: 2, value: 2 });
1734        assert_eq!(cache.recent.len(), 3);
1735        assert_eq!(cache.ghost.len(), 2,);
1736        assert_eq!(cache.frequent.len(), 1);
1737
1738        // Add 2, should evict an entry from ghost LRU
1739        assert_eq!(
1740            format!("{:?}", cache.put(2, 11).clone()),
1741            format!("{:?}", PutResult::Evicted { key: 3, value: 3 })
1742        );
1743        assert_eq!(cache.recent.len(), 3);
1744        assert_eq!(cache.ghost.len(), 2,);
1745        assert_eq!(cache.frequent.len(), 1);
1746
1747        // Add 4, should put the entry from ghost LRU to freq LRU
1748        assert_eq!(cache.put(4, 11), PutResult::Update(4));
1749        assert_eq!(cache.recent.len(), 2);
1750        assert_eq!(cache.ghost.len(), 2,);
1751        assert_eq!(cache.frequent.len(), 2);
1752
1753        // move all entry in recent to freq.
1754        assert_eq!(cache.put(2, 22).clone(), PutResult::Update(11));
1755        assert_eq!(cache.recent.len(), 1);
1756        assert_eq!(cache.ghost.len(), 2,);
1757        assert_eq!(cache.frequent.len(), 3);
1758
1759        assert_eq!(
1760            format!("{:?}", cache.put(7, 77)),
1761            format!("{:?}", PutResult::<i32, i32>::Update(7))
1762        );
1763        assert_eq!(cache.recent.len(), 0);
1764        assert_eq!(cache.ghost.len(), 2);
1765        assert_eq!(cache.frequent.len(), 4);
1766
1767        // Add 6, should put the entry from ghost LRU to freq LRU, and evicted one
1768        // entry
1769        assert_eq!(
1770            format!("{:?}", cache.put(6, 66).clone()),
1771            format!(
1772                "{:?}",
1773                PutResult::EvictedAndUpdate {
1774                    evicted: (5, 5),
1775                    update: 6
1776                }
1777            )
1778        );
1779        assert_eq!(cache.recent.len(), 0);
1780        assert_eq!(cache.ghost.len(), 1);
1781        assert_eq!(cache.frequent.len(), 4);
1782    }
1783
1784    #[test]
1785    fn test_2q_cache() {
1786        let mut cache = TwoQueueCache::new(128).unwrap();
1787
1788        (0..256u64).for_each(|i| {
1789            cache.put(i, i);
1790        });
1791
1792        assert_eq!(cache.len(), 128);
1793
1794        let rst = cache
1795            .frequent
1796            .keys_lru()
1797            .chain(cache.recent.keys_lru())
1798            .enumerate()
1799            .map(|(idx, k)| (idx as u64, *k))
1800            .collect::<Vec<(u64, u64)>>();
1801
1802        rst.into_iter().for_each(|(idx, k)| match cache.get(&k) {
1803            None => panic!("bad: {}", k),
1804            Some(val) => assert_eq!(*val, idx + 128),
1805        });
1806
1807        (0..128).for_each(|k| {
1808            assert_eq!(cache.get(&k), None);
1809        });
1810
1811        (128..256).for_each(|k| {
1812            assert_ne!(cache.get(&k), None);
1813        });
1814
1815        (128..192).for_each(|k| {
1816            cache.remove(&k);
1817            assert_eq!(cache.get(&k), None);
1818        });
1819
1820        cache.purge();
1821        assert_eq!(cache.len(), 0);
1822        assert_eq!(cache.get(&200), None);
1823    }
1824
1825    #[test]
1826    fn test_2q_cache_contains() {
1827        let mut cache = TwoQueueCache::new(2).unwrap();
1828        cache.put(1, 1);
1829        cache.put(2, 2);
1830
1831        assert!(cache.contains(&1));
1832        cache.put(3, 3);
1833        assert!(
1834            !cache.contains(&1),
1835            "should be in ghost LRU, and the elements in the ghost is not counted as in cache"
1836        );
1837    }
1838
1839    #[test]
1840    fn test_2q_cache_peek() {
1841        let mut cache = TwoQueueCache::new(2).unwrap();
1842        cache.put(1, 1);
1843        cache.put(2, 2);
1844
1845        assert_eq!(cache.peek(&1), Some(&1));
1846        cache.put(3, 3);
1847        assert!(!cache.contains(&1));
1848    }
1849}