Skip to main content

lru/
lib.rs

1// MIT License
2
3// Copyright (c) 2016 Jerome Froelich
4
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to deal
7// in the Software without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11
12// The above copyright notice and this permission notice shall be included in all
13// copies or substantial portions of the Software.
14
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21// SOFTWARE.
22
23//! An implementation of a LRU cache. The cache supports `get`, `get_mut`, `put`,
24//! and `pop` operations, all of which are O(1). This crate was heavily influenced
25//! by the [LRU Cache implementation in an earlier version of Rust's std::collections crate](https://doc.rust-lang.org/0.12.0/std/collections/lru_cache/struct.LruCache.html).
26//!
27//! ## Example
28//!
29//! ```rust
30//! extern crate lru;
31//!
32//! use lru::LruCache;
33//! use std::num::NonZeroUsize;
34//!
35//! fn main() {
36//!         let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
37//!         cache.put("apple", 3);
38//!         cache.put("banana", 2);
39//!
40//!         assert_eq!(*cache.get(&"apple").unwrap(), 3);
41//!         assert_eq!(*cache.get(&"banana").unwrap(), 2);
42//!         assert!(cache.get(&"pear").is_none());
43//!
44//!         assert_eq!(cache.put("banana", 4), Some(2));
45//!         assert_eq!(cache.put("pear", 5), None);
46//!
47//!         assert_eq!(*cache.get(&"pear").unwrap(), 5);
48//!         assert_eq!(*cache.get(&"banana").unwrap(), 4);
49//!         assert!(cache.get(&"apple").is_none());
50//!
51//!         {
52//!             let v = cache.get_mut(&"banana").unwrap();
53//!             *v = 6;
54//!         }
55//!
56//!         assert_eq!(*cache.get(&"banana").unwrap(), 6);
57//! }
58//! ```
59
60#![no_std]
61
62#[cfg(feature = "hashbrown")]
63extern crate hashbrown;
64
65#[cfg(test)]
66extern crate scoped_threadpool;
67
68use alloc::borrow::Borrow;
69use alloc::boxed::Box;
70use core::fmt;
71use core::hash::{BuildHasher, Hash, Hasher};
72use core::iter::FusedIterator;
73use core::marker::PhantomData;
74use core::mem;
75use core::num::NonZeroUsize;
76use core::ptr::{self, NonNull};
77
78#[cfg(any(test, not(feature = "hashbrown")))]
79extern crate std;
80
81#[cfg(feature = "hashbrown")]
82use hashbrown::HashMap;
83#[cfg(not(feature = "hashbrown"))]
84use std::collections::HashMap;
85
86extern crate alloc;
87
88// Struct used to hold a reference to a key
89struct KeyRef<K> {
90    k: *const K,
91}
92
93impl<K: Hash> Hash for KeyRef<K> {
94    fn hash<H: Hasher>(&self, state: &mut H) {
95        unsafe { (*self.k).hash(state) }
96    }
97}
98
99impl<K: PartialEq> PartialEq for KeyRef<K> {
100    // NB: The unconditional_recursion lint was added in 1.76.0 and can be removed
101    // once the current stable version of Rust is 1.76.0 or higher.
102    #![allow(unknown_lints)]
103    #[allow(clippy::unconditional_recursion)]
104    fn eq(&self, other: &KeyRef<K>) -> bool {
105        unsafe { (*self.k).eq(&*other.k) }
106    }
107}
108
109impl<K: Eq> Eq for KeyRef<K> {}
110
111// This type exists to allow a "blanket" Borrow impl for KeyRef without conflicting with the
112//  stdlib blanket impl
113#[repr(transparent)]
114struct KeyWrapper<K: ?Sized>(K);
115
116impl<K: ?Sized> KeyWrapper<K> {
117    fn from_ref(key: &K) -> &Self {
118        // safety: KeyWrapper is transparent, so casting the ref like this is allowable
119        unsafe { &*(key as *const K as *const KeyWrapper<K>) }
120    }
121}
122
123impl<K: ?Sized + Hash> Hash for KeyWrapper<K> {
124    fn hash<H: Hasher>(&self, state: &mut H) {
125        self.0.hash(state)
126    }
127}
128
129impl<K: ?Sized + PartialEq> PartialEq for KeyWrapper<K> {
130    // NB: The unconditional_recursion lint was added in 1.76.0 and can be removed
131    // once the current stable version of Rust is 1.76.0 or higher.
132    #![allow(unknown_lints)]
133    #[allow(clippy::unconditional_recursion)]
134    fn eq(&self, other: &Self) -> bool {
135        self.0.eq(&other.0)
136    }
137}
138
139impl<K: ?Sized + Eq> Eq for KeyWrapper<K> {}
140
141impl<K, Q> Borrow<KeyWrapper<Q>> for KeyRef<K>
142where
143    K: Borrow<Q>,
144    Q: ?Sized,
145{
146    fn borrow(&self) -> &KeyWrapper<Q> {
147        let key = unsafe { &*self.k }.borrow();
148        KeyWrapper::from_ref(key)
149    }
150}
151
152// Struct used to hold a key value pair. Also contains references to previous and next entries
153// so we can maintain the entries in a linked list ordered by their use.
154struct LruEntry<K, V> {
155    key: mem::MaybeUninit<K>,
156    val: mem::MaybeUninit<V>,
157    prev: *mut LruEntry<K, V>,
158    next: *mut LruEntry<K, V>,
159}
160
161impl<K, V> LruEntry<K, V> {
162    fn new(key: K, val: V) -> Self {
163        LruEntry {
164            key: mem::MaybeUninit::new(key),
165            val: mem::MaybeUninit::new(val),
166            prev: ptr::null_mut(),
167            next: ptr::null_mut(),
168        }
169    }
170
171    fn new_sigil() -> Self {
172        LruEntry {
173            key: mem::MaybeUninit::uninit(),
174            val: mem::MaybeUninit::uninit(),
175            prev: ptr::null_mut(),
176            next: ptr::null_mut(),
177        }
178    }
179}
180
181#[cfg(feature = "hashbrown")]
182pub type DefaultHasher = hashbrown::DefaultHashBuilder;
183#[cfg(not(feature = "hashbrown"))]
184pub type DefaultHasher = std::collections::hash_map::RandomState;
185
186/// An LRU Cache
187pub struct LruCache<K, V, S = DefaultHasher> {
188    map: HashMap<KeyRef<K>, NonNull<LruEntry<K, V>>, S>,
189    cap: NonZeroUsize,
190
191    // head and tail are sigil nodes to facilitate inserting entries
192    head: *mut LruEntry<K, V>,
193    tail: *mut LruEntry<K, V>,
194}
195
196impl<K, V, S> Clone for LruCache<K, V, S>
197where
198    K: Hash + PartialEq + Eq + Clone,
199    V: Clone,
200    S: BuildHasher + Clone,
201{
202    fn clone(&self) -> Self {
203        let map_cap = if self.is_unbounded() {
204            self.len()
205        } else {
206            self.cap().get()
207        };
208        let mut new_lru = LruCache::construct(
209            self.cap(),
210            HashMap::with_capacity_and_hasher(map_cap, self.map.hasher().clone()),
211        );
212
213        for (key, value) in self.iter().rev() {
214            new_lru.push(key.clone(), value.clone());
215        }
216
217        new_lru
218    }
219}
220
221impl<K: Hash + Eq, V> LruCache<K, V> {
222    /// Creates a new LRU Cache that holds at most `cap` items.
223    ///
224    /// # Example
225    ///
226    /// ```
227    /// use lru::LruCache;
228    /// use std::num::NonZeroUsize;
229    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(10).unwrap());
230    /// ```
231    pub fn new(cap: NonZeroUsize) -> LruCache<K, V> {
232        LruCache::construct(cap, HashMap::with_capacity(cap.get()))
233    }
234
235    /// Creates a new LRU Cache that never automatically evicts items.
236    ///
237    /// # Example
238    ///
239    /// ```
240    /// use lru::LruCache;
241    /// use std::num::NonZeroUsize;
242    /// let mut cache: LruCache<isize, &str> = LruCache::unbounded();
243    /// ```
244    pub fn unbounded() -> LruCache<K, V> {
245        LruCache::construct(NonZeroUsize::MAX, HashMap::default())
246    }
247}
248
249impl<K: Hash + Eq, V, S: BuildHasher> LruCache<K, V, S> {
250    /// Creates a new LRU Cache that holds at most `cap` items and
251    /// uses the provided hash builder to hash keys.
252    ///
253    /// # Example
254    ///
255    /// ```
256    /// use lru::{LruCache, DefaultHasher};
257    /// use std::num::NonZeroUsize;
258    ///
259    /// let s = DefaultHasher::default();
260    /// let mut cache: LruCache<isize, &str> = LruCache::with_hasher(NonZeroUsize::new(10).unwrap(), s);
261    /// ```
262    pub fn with_hasher(cap: NonZeroUsize, hash_builder: S) -> LruCache<K, V, S> {
263        LruCache::construct(
264            cap,
265            HashMap::with_capacity_and_hasher(cap.into(), hash_builder),
266        )
267    }
268
269    /// Creates a new LRU Cache that never automatically evicts items and
270    /// uses the provided hash builder to hash keys.
271    ///
272    /// # Example
273    ///
274    /// ```
275    /// use lru::{LruCache, DefaultHasher};
276    ///
277    /// let s = DefaultHasher::default();
278    /// let mut cache: LruCache<isize, &str> = LruCache::unbounded_with_hasher(s);
279    /// ```
280    pub fn unbounded_with_hasher(hash_builder: S) -> LruCache<K, V, S> {
281        LruCache::construct(NonZeroUsize::MAX, HashMap::with_hasher(hash_builder))
282    }
283
284    /// Creates a new LRU Cache with the given capacity.
285    fn construct(
286        cap: NonZeroUsize,
287        map: HashMap<KeyRef<K>, NonNull<LruEntry<K, V>>, S>,
288    ) -> LruCache<K, V, S> {
289        // NB: The compiler warns that cache does not need to be marked as mutable if we
290        // declare it as such since we only mutate it inside the unsafe block.
291        let cache = LruCache {
292            map,
293            cap,
294            head: Box::into_raw(Box::new(LruEntry::new_sigil())),
295            tail: Box::into_raw(Box::new(LruEntry::new_sigil())),
296        };
297
298        unsafe {
299            (*cache.head).next = cache.tail;
300            (*cache.tail).prev = cache.head;
301        }
302
303        cache
304    }
305
306    /// Whether this LRU cache is unbounded.
307    fn is_unbounded(&self) -> bool {
308        self.cap() == NonZeroUsize::MAX
309    }
310
311    /// Puts a key-value pair into cache. If the key already exists in the cache, then it updates
312    /// the key's value and returns the old value. Otherwise, `None` is returned.
313    ///
314    /// # Example
315    ///
316    /// ```
317    /// use lru::LruCache;
318    /// use std::num::NonZeroUsize;
319    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
320    ///
321    /// assert_eq!(None, cache.put(1, "a"));
322    /// assert_eq!(None, cache.put(2, "b"));
323    /// assert_eq!(Some("b"), cache.put(2, "beta"));
324    ///
325    /// assert_eq!(cache.get(&1), Some(&"a"));
326    /// assert_eq!(cache.get(&2), Some(&"beta"));
327    /// ```
328    pub fn put(&mut self, k: K, v: V) -> Option<V> {
329        self.capturing_put(k, v, false).map(|(_, v)| v)
330    }
331
332    /// Pushes a key-value pair into the cache. If an entry with key `k` already exists in
333    /// the cache or another cache entry is removed (due to the lru's capacity),
334    /// then it returns the old entry's key-value pair. Otherwise, returns `None`.
335    ///
336    /// # Example
337    ///
338    /// ```
339    /// use lru::LruCache;
340    /// use std::num::NonZeroUsize;
341    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
342    ///
343    /// assert_eq!(None, cache.push(1, "a"));
344    /// assert_eq!(None, cache.push(2, "b"));
345    ///
346    /// // This push call returns (2, "b") because that was previously 2's entry in the cache.
347    /// assert_eq!(Some((2, "b")), cache.push(2, "beta"));
348    ///
349    /// // This push call returns (1, "a") because the cache is at capacity and 1's entry was the lru entry.
350    /// assert_eq!(Some((1, "a")), cache.push(3, "alpha"));
351    ///
352    /// assert_eq!(cache.get(&1), None);
353    /// assert_eq!(cache.get(&2), Some(&"beta"));
354    /// assert_eq!(cache.get(&3), Some(&"alpha"));
355    /// ```
356    pub fn push(&mut self, k: K, v: V) -> Option<(K, V)> {
357        self.capturing_put(k, v, true)
358    }
359
360    // Used internally by `put` and `push` to add a new entry to the lru.
361    // Takes ownership of and returns entries replaced due to the cache's capacity
362    // when `capture` is true.
363    fn capturing_put(&mut self, k: K, mut v: V, capture: bool) -> Option<(K, V)> {
364        let node_ref = self.map.get_mut(&KeyRef { k: &k });
365
366        match node_ref {
367            Some(node_ref) => {
368                // if the key is already in the cache just update its value and move it to the
369                // front of the list
370                let node_ptr: *mut LruEntry<K, V> = node_ref.as_ptr();
371
372                // gets a reference to the node to perform a swap and drops it right after
373                let node_ref = unsafe { &mut (*(*node_ptr).val.as_mut_ptr()) };
374                mem::swap(&mut v, node_ref);
375                let _ = node_ref;
376
377                self.detach(node_ptr);
378                self.attach(node_ptr);
379                Some((k, v))
380            }
381            None => {
382                let (replaced, node) = self.replace_or_create_node(k, v);
383                let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
384
385                self.attach(node_ptr);
386
387                let keyref = unsafe { (*node_ptr).key.as_ptr() };
388                self.map.insert(KeyRef { k: keyref }, node);
389
390                replaced.filter(|_| capture)
391            }
392        }
393    }
394
395    // Used internally to swap out a node if the cache is full or to create a new node if space
396    // is available. Shared between `put`, `push`, `get_or_insert`, and `get_or_insert_mut`.
397    #[allow(clippy::type_complexity)]
398    fn replace_or_create_node(&mut self, k: K, v: V) -> (Option<(K, V)>, NonNull<LruEntry<K, V>>) {
399        if self.len() == self.cap().get() {
400            // if the cache is full, remove the last entry so we can use it for the new key
401            let old_key = KeyRef {
402                k: unsafe { &(*(*(*self.tail).prev).key.as_ptr()) },
403            };
404            let old_node = self.map.remove(&old_key).unwrap();
405            let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
406
407            // read out the node's old key and value and then replace it
408            let replaced = unsafe {
409                (
410                    mem::replace(&mut (*node_ptr).key, mem::MaybeUninit::new(k)).assume_init(),
411                    mem::replace(&mut (*node_ptr).val, mem::MaybeUninit::new(v)).assume_init(),
412                )
413            };
414
415            self.detach(node_ptr);
416
417            (Some(replaced), old_node)
418        } else {
419            // if the cache is not full allocate a new LruEntry
420            // Safety: We allocate, turn into raw, and get NonNull all in one step.
421            (None, unsafe {
422                NonNull::new_unchecked(Box::into_raw(Box::new(LruEntry::new(k, v))))
423            })
424        }
425    }
426
427    /// Returns a reference to the value of the key in the cache or `None` if it is not
428    /// present in the cache. Moves the key to the head of the LRU list if it exists.
429    ///
430    /// # Example
431    ///
432    /// ```
433    /// use lru::LruCache;
434    /// use std::num::NonZeroUsize;
435    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
436    ///
437    /// cache.put(1, "a");
438    /// cache.put(2, "b");
439    /// cache.put(2, "c");
440    /// cache.put(3, "d");
441    ///
442    /// assert_eq!(cache.get(&1), None);
443    /// assert_eq!(cache.get(&2), Some(&"c"));
444    /// assert_eq!(cache.get(&3), Some(&"d"));
445    /// ```
446    pub fn get<'a, Q>(&'a mut self, k: &Q) -> Option<&'a V>
447    where
448        K: Borrow<Q>,
449        Q: Hash + Eq + ?Sized,
450    {
451        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
452            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
453
454            self.detach(node_ptr);
455            self.attach(node_ptr);
456
457            Some(unsafe { &*(*node_ptr).val.as_ptr() })
458        } else {
459            None
460        }
461    }
462
463    /// Returns a mutable reference to the value of the key in the cache or `None` if it
464    /// is not present in the cache. Moves the key to the head of the LRU list if it exists.
465    ///
466    /// # Example
467    ///
468    /// ```
469    /// use lru::LruCache;
470    /// use std::num::NonZeroUsize;
471    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
472    ///
473    /// cache.put("apple", 8);
474    /// cache.put("banana", 4);
475    /// cache.put("banana", 6);
476    /// cache.put("pear", 2);
477    ///
478    /// assert_eq!(cache.get_mut(&"apple"), None);
479    /// assert_eq!(cache.get_mut(&"banana"), Some(&mut 6));
480    /// assert_eq!(cache.get_mut(&"pear"), Some(&mut 2));
481    /// ```
482    pub fn get_mut<'a, Q>(&'a mut self, k: &Q) -> Option<&'a mut V>
483    where
484        K: Borrow<Q>,
485        Q: Hash + Eq + ?Sized,
486    {
487        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
488            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
489
490            self.detach(node_ptr);
491            self.attach(node_ptr);
492
493            Some(unsafe { &mut *(*node_ptr).val.as_mut_ptr() })
494        } else {
495            None
496        }
497    }
498
499    /// Returns a key-value references pair of the key in the cache or `None` if it is not
500    /// present in the cache. Moves the key to the head of the LRU list if it exists.
501    ///
502    /// # Example
503    ///
504    /// ```
505    /// use lru::LruCache;
506    /// use std::num::NonZeroUsize;
507    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
508    ///
509    /// cache.put(String::from("1"), "a");
510    /// cache.put(String::from("2"), "b");
511    /// cache.put(String::from("2"), "c");
512    /// cache.put(String::from("3"), "d");
513    ///
514    /// assert_eq!(cache.get_key_value("1"), None);
515    /// assert_eq!(cache.get_key_value("2"), Some((&String::from("2"), &"c")));
516    /// assert_eq!(cache.get_key_value("3"), Some((&String::from("3"), &"d")));
517    /// ```
518    pub fn get_key_value<'a, Q>(&'a mut self, k: &Q) -> Option<(&'a K, &'a V)>
519    where
520        K: Borrow<Q>,
521        Q: Hash + Eq + ?Sized,
522    {
523        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
524            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
525
526            self.detach(node_ptr);
527            self.attach(node_ptr);
528
529            Some(unsafe { (&*(*node_ptr).key.as_ptr(), &*(*node_ptr).val.as_ptr()) })
530        } else {
531            None
532        }
533    }
534
535    /// Returns a key-value references pair of the key in the cache or `None` if it is not
536    /// present in the cache. The reference to the value of the key is mutable. Moves the key to
537    /// the head of the LRU list if it exists.
538    ///
539    /// # Example
540    ///
541    /// ```
542    /// use lru::LruCache;
543    /// use std::num::NonZeroUsize;
544    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
545    ///
546    /// cache.put(1, "a");
547    /// cache.put(2, "b");
548    /// let (k, v) = cache.get_key_value_mut(&1).unwrap();
549    /// assert_eq!(k, &1);
550    /// assert_eq!(v, &mut "a");
551    /// *v = "aa";
552    /// cache.put(3, "c");
553    /// assert_eq!(cache.get_key_value(&2), None);
554    /// assert_eq!(cache.get_key_value(&1), Some((&1, &"aa")));
555    /// assert_eq!(cache.get_key_value(&3), Some((&3, &"c")));
556    /// ```
557    pub fn get_key_value_mut<'a, Q>(&'a mut self, k: &Q) -> Option<(&'a K, &'a mut V)>
558    where
559        K: Borrow<Q>,
560        Q: Hash + Eq + ?Sized,
561    {
562        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
563            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
564
565            self.detach(node_ptr);
566            self.attach(node_ptr);
567
568            Some(unsafe {
569                (
570                    &*(*node_ptr).key.as_ptr(),
571                    &mut *(*node_ptr).val.as_mut_ptr(),
572                )
573            })
574        } else {
575            None
576        }
577    }
578
579    /// Returns a reference to the value of the key in the cache if it is
580    /// present in the cache and moves the key to the head of the LRU list.
581    /// If the key does not exist the provided `FnOnce` is used to populate
582    /// the list and a reference is returned.
583    ///
584    /// # Example
585    ///
586    /// ```
587    /// use lru::LruCache;
588    /// use std::num::NonZeroUsize;
589    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
590    ///
591    /// cache.put(1, "a");
592    /// cache.put(2, "b");
593    /// cache.put(2, "c");
594    /// cache.put(3, "d");
595    ///
596    /// assert_eq!(cache.get_or_insert(2, ||"a"), &"c");
597    /// assert_eq!(cache.get_or_insert(3, ||"a"), &"d");
598    /// assert_eq!(cache.get_or_insert(1, ||"a"), &"a");
599    /// assert_eq!(cache.get_or_insert(1, ||"b"), &"a");
600    /// ```
601    pub fn get_or_insert<F>(&mut self, k: K, f: F) -> &V
602    where
603        F: FnOnce() -> V,
604    {
605        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
606            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
607
608            self.detach(node_ptr);
609            self.attach(node_ptr);
610
611            unsafe { &*(*node_ptr).val.as_ptr() }
612        } else {
613            let v = f();
614            let (_, node) = self.replace_or_create_node(k, v);
615            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
616
617            self.attach(node_ptr);
618
619            let keyref = unsafe { (*node_ptr).key.as_ptr() };
620            self.map.insert(KeyRef { k: keyref }, node);
621            unsafe { &*(*node_ptr).val.as_ptr() }
622        }
623    }
624
625    /// Returns a reference to the value of the key in the cache if it is
626    /// present in the cache and moves the key to the head of the LRU list.
627    /// If the key does not exist the provided `FnOnce` is used to populate
628    /// the list and a reference is returned. The value referenced by the
629    /// key is only cloned (using `to_owned()`) if it doesn't exist in the
630    /// cache.
631    ///
632    /// # Example
633    ///
634    /// ```
635    /// use lru::LruCache;
636    /// use std::num::NonZeroUsize;
637    /// use std::rc::Rc;
638    ///
639    /// let key1 = Rc::new("1".to_owned());
640    /// let key2 = Rc::new("2".to_owned());
641    /// let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
642    /// assert_eq!(cache.get_or_insert_ref(&key1, ||"One".to_owned()), "One");
643    /// assert_eq!(cache.get_or_insert_ref(&key2, ||"Two".to_owned()), "Two");
644    /// assert_eq!(cache.get_or_insert_ref(&key2, ||"Not two".to_owned()), "Two");
645    /// assert_eq!(cache.get_or_insert_ref(&key2, ||"Again not two".to_owned()), "Two");
646    /// assert_eq!(Rc::strong_count(&key1), 2);
647    /// assert_eq!(Rc::strong_count(&key2), 2); // key2 was only cloned once even though we
648    ///                                         // queried it 3 times
649    /// ```
650    pub fn get_or_insert_ref<'a, Q, F>(&'a mut self, k: &'_ Q, f: F) -> &'a V
651    where
652        K: Borrow<Q>,
653        Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
654        F: FnOnce() -> V,
655    {
656        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
657            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
658
659            self.detach(node_ptr);
660            self.attach(node_ptr);
661
662            unsafe { &*(*node_ptr).val.as_ptr() }
663        } else {
664            let v = f();
665            let (_, node) = self.replace_or_create_node(k.to_owned(), v);
666            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
667
668            self.attach(node_ptr);
669
670            let keyref = unsafe { (*node_ptr).key.as_ptr() };
671            self.map.insert(KeyRef { k: keyref }, node);
672            unsafe { &*(*node_ptr).val.as_ptr() }
673        }
674    }
675
676    /// Returns a reference to the value of the key in the cache if it is
677    /// present in the cache and moves the key to the head of the LRU list.
678    /// If the key does not exist the provided `FnOnce` is used to populate
679    /// the list and a reference is returned. If `FnOnce` returns `Err`,
680    /// returns the `Err`.
681    ///
682    /// # Example
683    ///
684    /// ```
685    /// use lru::LruCache;
686    /// use std::num::NonZeroUsize;
687    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
688    ///
689    /// cache.put(1, "a");
690    /// cache.put(2, "b");
691    /// cache.put(2, "c");
692    /// cache.put(3, "d");
693    ///
694    /// let f = ||->Result<&str, String> {Err("failed".to_owned())};
695    /// let a = ||->Result<&str, String> {Ok("a")};
696    /// let b = ||->Result<&str, String> {Ok("b")};
697    /// assert_eq!(cache.try_get_or_insert(2, a), Ok(&"c"));
698    /// assert_eq!(cache.try_get_or_insert(3, a), Ok(&"d"));
699    /// assert_eq!(cache.try_get_or_insert(4, f), Err("failed".to_owned()));
700    /// assert_eq!(cache.try_get_or_insert(5, b), Ok(&"b"));
701    /// assert_eq!(cache.try_get_or_insert(5, a), Ok(&"b"));
702    /// ```
703    pub fn try_get_or_insert<F, E>(&mut self, k: K, f: F) -> Result<&V, E>
704    where
705        F: FnOnce() -> Result<V, E>,
706    {
707        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
708            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
709
710            self.detach(node_ptr);
711            self.attach(node_ptr);
712
713            unsafe { Ok(&*(*node_ptr).val.as_ptr()) }
714        } else {
715            let v = f()?;
716            let (_, node) = self.replace_or_create_node(k, v);
717            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
718
719            self.attach(node_ptr);
720
721            let keyref = unsafe { (*node_ptr).key.as_ptr() };
722            self.map.insert(KeyRef { k: keyref }, node);
723            Ok(unsafe { &*(*node_ptr).val.as_ptr() })
724        }
725    }
726
727    /// Returns a reference to the value of the key in the cache if it is
728    /// present in the cache and moves the key to the head of the LRU list.
729    /// If the key does not exist the provided `FnOnce` is used to populate
730    /// the list and a reference is returned. If `FnOnce` returns `Err`,
731    /// returns the `Err`. The value referenced by the key is only cloned
732    /// (using `to_owned()`) if it doesn't exist in the cache and `FnOnce`
733    /// succeeds.
734    ///
735    /// # Example
736    ///
737    /// ```
738    /// use lru::LruCache;
739    /// use std::num::NonZeroUsize;
740    /// use std::rc::Rc;
741    ///
742    /// let key1 = Rc::new("1".to_owned());
743    /// let key2 = Rc::new("2".to_owned());
744    /// let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
745    /// let f = ||->Result<String, ()> {Err(())};
746    /// let a = ||->Result<String, ()> {Ok("One".to_owned())};
747    /// let b = ||->Result<String, ()> {Ok("Two".to_owned())};
748    /// assert_eq!(cache.try_get_or_insert_ref(&key1, a), Ok(&"One".to_owned()));
749    /// assert_eq!(cache.try_get_or_insert_ref(&key2, f), Err(()));
750    /// assert_eq!(cache.try_get_or_insert_ref(&key2, b), Ok(&"Two".to_owned()));
751    /// assert_eq!(cache.try_get_or_insert_ref(&key2, a), Ok(&"Two".to_owned()));
752    /// assert_eq!(Rc::strong_count(&key1), 2);
753    /// assert_eq!(Rc::strong_count(&key2), 2); // key2 was only cloned once even though we
754    ///                                         // queried it 3 times
755    /// ```
756    pub fn try_get_or_insert_ref<'a, Q, F, E>(&'a mut self, k: &'_ Q, f: F) -> Result<&'a V, E>
757    where
758        K: Borrow<Q>,
759        Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
760        F: FnOnce() -> Result<V, E>,
761    {
762        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
763            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
764
765            self.detach(node_ptr);
766            self.attach(node_ptr);
767
768            unsafe { Ok(&*(*node_ptr).val.as_ptr()) }
769        } else {
770            let v = f()?;
771            let (_, node) = self.replace_or_create_node(k.to_owned(), v);
772            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
773
774            self.attach(node_ptr);
775
776            let keyref = unsafe { (*node_ptr).key.as_ptr() };
777            self.map.insert(KeyRef { k: keyref }, node);
778            Ok(unsafe { &*(*node_ptr).val.as_ptr() })
779        }
780    }
781
782    /// Returns a mutable reference to the value of the key in the cache if it is
783    /// present in the cache and moves the key to the head of the LRU list.
784    /// If the key does not exist the provided `FnOnce` is used to populate
785    /// the list and a mutable reference is returned.
786    ///
787    /// # Example
788    ///
789    /// ```
790    /// use lru::LruCache;
791    /// use std::num::NonZeroUsize;
792    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
793    ///
794    /// cache.put(1, "a");
795    /// cache.put(2, "b");
796    ///
797    /// let v = cache.get_or_insert_mut(2, ||"c");
798    /// assert_eq!(v, &"b");
799    /// *v = "d";
800    /// assert_eq!(cache.get_or_insert_mut(2, ||"e"), &mut "d");
801    /// assert_eq!(cache.get_or_insert_mut(3, ||"f"), &mut "f");
802    /// assert_eq!(cache.get_or_insert_mut(3, ||"e"), &mut "f");
803    /// ```
804    pub fn get_or_insert_mut<F>(&mut self, k: K, f: F) -> &mut V
805    where
806        F: FnOnce() -> V,
807    {
808        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
809            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
810
811            self.detach(node_ptr);
812            self.attach(node_ptr);
813
814            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
815        } else {
816            let v = f();
817            let (_, node) = self.replace_or_create_node(k, v);
818            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
819
820            self.attach(node_ptr);
821
822            let keyref = unsafe { (*node_ptr).key.as_ptr() };
823            self.map.insert(KeyRef { k: keyref }, node);
824            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
825        }
826    }
827
828    /// Returns a mutable reference to the value of the key in the cache if it is
829    /// present in the cache and moves the key to the head of the LRU list.
830    /// If the key does not exist the provided `FnOnce` is used to populate
831    /// the list and a mutable reference is returned. The value referenced by the
832    /// key is only cloned (using `to_owned()`) if it doesn't exist in the cache.
833    ///
834    /// # Example
835    ///
836    /// ```
837    /// use lru::LruCache;
838    /// use std::num::NonZeroUsize;
839    /// use std::rc::Rc;
840    ///
841    /// let key1 = Rc::new("1".to_owned());
842    /// let key2 = Rc::new("2".to_owned());
843    /// let mut cache = LruCache::<Rc<String>, &'static str>::new(NonZeroUsize::new(2).unwrap());
844    /// cache.get_or_insert_mut_ref(&key1, ||"One");
845    /// let v = cache.get_or_insert_mut_ref(&key2, ||"Two");
846    /// *v = "New two";
847    /// assert_eq!(cache.get_or_insert_mut_ref(&key2, ||"Two"), &mut "New two");
848    /// assert_eq!(Rc::strong_count(&key1), 2);
849    /// assert_eq!(Rc::strong_count(&key2), 2); // key2 was only cloned once even though we
850    ///                                         // queried it 2 times
851    /// ```
852    pub fn get_or_insert_mut_ref<'a, Q, F>(&mut self, k: &'_ Q, f: F) -> &'a mut V
853    where
854        K: Borrow<Q>,
855        Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
856        F: FnOnce() -> V,
857    {
858        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
859            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
860
861            self.detach(node_ptr);
862            self.attach(node_ptr);
863
864            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
865        } else {
866            let v = f();
867            let (_, node) = self.replace_or_create_node(k.to_owned(), v);
868            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
869
870            self.attach(node_ptr);
871
872            let keyref = unsafe { (*node_ptr).key.as_ptr() };
873            self.map.insert(KeyRef { k: keyref }, node);
874            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
875        }
876    }
877
878    /// Returns a mutable reference to the value of the key in the cache if it is
879    /// present in the cache and moves the key to the head of the LRU list.
880    /// If the key does not exist the provided `FnOnce` is used to populate
881    /// the list and a mutable reference is returned. If `FnOnce` returns `Err`,
882    /// returns the `Err`.
883    ///
884    /// # Example
885    ///
886    /// ```
887    /// use lru::LruCache;
888    /// use std::num::NonZeroUsize;
889    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
890    ///
891    /// cache.put(1, "a");
892    /// cache.put(2, "b");
893    /// cache.put(2, "c");
894    ///
895    /// let f = ||->Result<&str, String> {Err("failed".to_owned())};
896    /// let a = ||->Result<&str, String> {Ok("a")};
897    /// let b = ||->Result<&str, String> {Ok("b")};
898    /// if let Ok(v) = cache.try_get_or_insert_mut(2, a) {
899    ///     *v = "d";
900    /// }
901    /// assert_eq!(cache.try_get_or_insert_mut(2, a), Ok(&mut "d"));
902    /// assert_eq!(cache.try_get_or_insert_mut(3, f), Err("failed".to_owned()));
903    /// assert_eq!(cache.try_get_or_insert_mut(4, b), Ok(&mut "b"));
904    /// assert_eq!(cache.try_get_or_insert_mut(4, a), Ok(&mut "b"));
905    /// ```
906    pub fn try_get_or_insert_mut<F, E>(&mut self, k: K, f: F) -> Result<&mut V, E>
907    where
908        F: FnOnce() -> Result<V, E>,
909    {
910        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
911            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
912
913            self.detach(node_ptr);
914            self.attach(node_ptr);
915
916            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
917        } else {
918            let v = f()?;
919            let (_, node) = self.replace_or_create_node(k, v);
920            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
921
922            self.attach(node_ptr);
923
924            let keyref = unsafe { (*node_ptr).key.as_ptr() };
925            self.map.insert(KeyRef { k: keyref }, node);
926            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
927        }
928    }
929
930    /// Returns a mutable reference to the value of the key in the cache if it is
931    /// present in the cache and moves the key to the head of the LRU list.
932    /// If the key does not exist the provided `FnOnce` is used to populate
933    /// the list and a mutable reference is returned. If `FnOnce` returns `Err`,
934    /// returns the `Err`. The value referenced by the key is only cloned
935    /// (using `to_owned()`) if it doesn't exist in the cache and `FnOnce`
936    /// succeeds.
937    ///
938    /// # Example
939    ///
940    /// ```
941    /// use lru::LruCache;
942    /// use std::num::NonZeroUsize;
943    /// use std::rc::Rc;
944    ///
945    /// let key1 = Rc::new("1".to_owned());
946    /// let key2 = Rc::new("2".to_owned());
947    /// let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
948    /// let f = ||->Result<String, ()> {Err(())};
949    /// let a = ||->Result<String, ()> {Ok("One".to_owned())};
950    /// let b = ||->Result<String, ()> {Ok("Two".to_owned())};
951    /// assert_eq!(cache.try_get_or_insert_mut_ref(&key1, a), Ok(&mut "One".to_owned()));
952    /// assert_eq!(cache.try_get_or_insert_mut_ref(&key2, f), Err(()));
953    /// if let Ok(v) = cache.try_get_or_insert_mut_ref(&key2, b) {
954    ///     *v = "New two".to_owned();
955    /// }
956    /// assert_eq!(cache.try_get_or_insert_mut_ref(&key2, a), Ok(&mut "New two".to_owned()));
957    /// assert_eq!(Rc::strong_count(&key1), 2);
958    /// assert_eq!(Rc::strong_count(&key2), 2); // key2 was only cloned once even though we
959    ///                                         // queried it 3 times
960    /// ```
961    pub fn try_get_or_insert_mut_ref<'a, Q, F, E>(
962        &'a mut self,
963        k: &'_ Q,
964        f: F,
965    ) -> Result<&'a mut V, E>
966    where
967        K: Borrow<Q>,
968        Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
969        F: FnOnce() -> Result<V, E>,
970    {
971        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
972            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
973
974            self.detach(node_ptr);
975            self.attach(node_ptr);
976
977            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
978        } else {
979            let v = f()?;
980            let (_, node) = self.replace_or_create_node(k.to_owned(), v);
981            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
982
983            self.attach(node_ptr);
984
985            let keyref = unsafe { (*node_ptr).key.as_ptr() };
986            self.map.insert(KeyRef { k: keyref }, node);
987            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
988        }
989    }
990
991    /// Returns a reference to the value corresponding to the key in the cache or `None` if it is
992    /// not present in the cache. Unlike `get`, `peek` does not update the LRU list so the key's
993    /// position will be unchanged.
994    ///
995    /// # Example
996    ///
997    /// ```
998    /// use lru::LruCache;
999    /// use std::num::NonZeroUsize;
1000    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1001    ///
1002    /// cache.put(1, "a");
1003    /// cache.put(2, "b");
1004    ///
1005    /// assert_eq!(cache.peek(&1), Some(&"a"));
1006    /// assert_eq!(cache.peek(&2), Some(&"b"));
1007    /// ```
1008    pub fn peek<'a, Q>(&'a self, k: &Q) -> Option<&'a V>
1009    where
1010        K: Borrow<Q>,
1011        Q: Hash + Eq + ?Sized,
1012    {
1013        self.map
1014            .get(KeyWrapper::from_ref(k))
1015            .map(|node| unsafe { &*node.as_ref().val.as_ptr() })
1016    }
1017
1018    /// Returns a mutable reference to the value corresponding to the key in the cache or `None`
1019    /// if it is not present in the cache. Unlike `get_mut`, `peek_mut` does not update the LRU
1020    /// list so the key's position will be unchanged.
1021    ///
1022    /// # Example
1023    ///
1024    /// ```
1025    /// use lru::LruCache;
1026    /// use std::num::NonZeroUsize;
1027    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1028    ///
1029    /// cache.put(1, "a");
1030    /// cache.put(2, "b");
1031    ///
1032    /// assert_eq!(cache.peek_mut(&1), Some(&mut "a"));
1033    /// assert_eq!(cache.peek_mut(&2), Some(&mut "b"));
1034    /// ```
1035    pub fn peek_mut<'a, Q>(&'a mut self, k: &Q) -> Option<&'a mut V>
1036    where
1037        K: Borrow<Q>,
1038        Q: Hash + Eq + ?Sized,
1039    {
1040        match self.map.get_mut(KeyWrapper::from_ref(k)) {
1041            None => None,
1042            Some(node) => Some(unsafe { &mut *(*node.as_ptr()).val.as_mut_ptr() }),
1043        }
1044    }
1045
1046    /// Returns the value corresponding to the least recently used item or `None` if the
1047    /// cache is empty. Like `peek`, `peek_lru` does not update the LRU list so the item's
1048    /// position will be unchanged.
1049    ///
1050    /// # Example
1051    ///
1052    /// ```
1053    /// use lru::LruCache;
1054    /// use std::num::NonZeroUsize;
1055    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1056    ///
1057    /// cache.put(1, "a");
1058    /// cache.put(2, "b");
1059    ///
1060    /// assert_eq!(cache.peek_lru(), Some((&1, &"a")));
1061    /// ```
1062    pub fn peek_lru(&self) -> Option<(&K, &V)> {
1063        if self.is_empty() {
1064            return None;
1065        }
1066
1067        let (key, val);
1068        unsafe {
1069            let node = (*self.tail).prev;
1070            key = &(*(*node).key.as_ptr()) as &K;
1071            val = &(*(*node).val.as_ptr()) as &V;
1072        }
1073
1074        Some((key, val))
1075    }
1076
1077    /// Returns the value corresponding to the most recently used item or `None` if the
1078    /// cache is empty. Like `peek`, `peek_mru` does not update the LRU list so the item's
1079    /// position will be unchanged.
1080    ///
1081    /// # Example
1082    ///
1083    /// ```
1084    /// use lru::LruCache;
1085    /// use std::num::NonZeroUsize;
1086    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1087    ///
1088    /// cache.put(1, "a");
1089    /// cache.put(2, "b");
1090    ///
1091    /// assert_eq!(cache.peek_mru(), Some((&2, &"b")));
1092    /// ```
1093    pub fn peek_mru(&self) -> Option<(&K, &V)> {
1094        if self.is_empty() {
1095            return None;
1096        }
1097
1098        let (key, val);
1099        unsafe {
1100            let node: *mut LruEntry<K, V> = (*self.head).next;
1101            key = &(*(*node).key.as_ptr()) as &K;
1102            val = &(*(*node).val.as_ptr()) as &V;
1103        }
1104
1105        Some((key, val))
1106    }
1107
1108    /// Returns a bool indicating whether the given key is in the cache. Does not update the
1109    /// LRU list.
1110    ///
1111    /// # Example
1112    ///
1113    /// ```
1114    /// use lru::LruCache;
1115    /// use std::num::NonZeroUsize;
1116    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1117    ///
1118    /// cache.put(1, "a");
1119    /// cache.put(2, "b");
1120    /// cache.put(3, "c");
1121    ///
1122    /// assert!(!cache.contains(&1));
1123    /// assert!(cache.contains(&2));
1124    /// assert!(cache.contains(&3));
1125    /// ```
1126    pub fn contains<Q>(&self, k: &Q) -> bool
1127    where
1128        K: Borrow<Q>,
1129        Q: Hash + Eq + ?Sized,
1130    {
1131        self.map.contains_key(KeyWrapper::from_ref(k))
1132    }
1133
1134    /// Removes and returns the value corresponding to the key from the cache or
1135    /// `None` if it does not exist.
1136    ///
1137    /// # Example
1138    ///
1139    /// ```
1140    /// use lru::LruCache;
1141    /// use std::num::NonZeroUsize;
1142    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1143    ///
1144    /// cache.put(2, "a");
1145    ///
1146    /// assert_eq!(cache.pop(&1), None);
1147    /// assert_eq!(cache.pop(&2), Some("a"));
1148    /// assert_eq!(cache.pop(&2), None);
1149    /// assert_eq!(cache.len(), 0);
1150    /// ```
1151    pub fn pop<Q>(&mut self, k: &Q) -> Option<V>
1152    where
1153        K: Borrow<Q>,
1154        Q: Hash + Eq + ?Sized,
1155    {
1156        match self.map.remove(KeyWrapper::from_ref(k)) {
1157            None => None,
1158            Some(old_node) => {
1159                let mut old_node = unsafe {
1160                    let mut old_node = *Box::from_raw(old_node.as_ptr());
1161                    ptr::drop_in_place(old_node.key.as_mut_ptr());
1162
1163                    old_node
1164                };
1165
1166                self.detach(&mut old_node);
1167
1168                let LruEntry { key: _, val, .. } = old_node;
1169                unsafe { Some(val.assume_init()) }
1170            }
1171        }
1172    }
1173
1174    /// Removes and returns the key and the value corresponding to the key from the cache or
1175    /// `None` if it does not exist.
1176    ///
1177    /// # Example
1178    ///
1179    /// ```
1180    /// use lru::LruCache;
1181    /// use std::num::NonZeroUsize;
1182    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1183    ///
1184    /// cache.put(1, "a");
1185    /// cache.put(2, "a");
1186    ///
1187    /// assert_eq!(cache.pop(&1), Some("a"));
1188    /// assert_eq!(cache.pop_entry(&2), Some((2, "a")));
1189    /// assert_eq!(cache.pop(&1), None);
1190    /// assert_eq!(cache.pop_entry(&2), None);
1191    /// assert_eq!(cache.len(), 0);
1192    /// ```
1193    pub fn pop_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
1194    where
1195        K: Borrow<Q>,
1196        Q: Hash + Eq + ?Sized,
1197    {
1198        match self.map.remove(KeyWrapper::from_ref(k)) {
1199            None => None,
1200            Some(old_node) => {
1201                let mut old_node = unsafe { *Box::from_raw(old_node.as_ptr()) };
1202
1203                self.detach(&mut old_node);
1204
1205                let LruEntry { key, val, .. } = old_node;
1206                unsafe { Some((key.assume_init(), val.assume_init())) }
1207            }
1208        }
1209    }
1210
1211    /// Removes and returns the key and value corresponding to the least recently
1212    /// used item or `None` if the cache is empty.
1213    ///
1214    /// # Example
1215    ///
1216    /// ```
1217    /// use lru::LruCache;
1218    /// use std::num::NonZeroUsize;
1219    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1220    ///
1221    /// cache.put(2, "a");
1222    /// cache.put(3, "b");
1223    /// cache.put(4, "c");
1224    /// cache.get(&3);
1225    ///
1226    /// assert_eq!(cache.pop_lru(), Some((4, "c")));
1227    /// assert_eq!(cache.pop_lru(), Some((3, "b")));
1228    /// assert_eq!(cache.pop_lru(), None);
1229    /// assert_eq!(cache.len(), 0);
1230    /// ```
1231    pub fn pop_lru(&mut self) -> Option<(K, V)> {
1232        let node = self.remove_last()?;
1233        // N.B.: Can't destructure directly because of https://github.com/rust-lang/rust/issues/28536
1234        let node = *node;
1235        let LruEntry { key, val, .. } = node;
1236        unsafe { Some((key.assume_init(), val.assume_init())) }
1237    }
1238
1239    /// Removes and returns the key and value corresponding to the most recently
1240    /// used item or `None` if the cache is empty.
1241    ///
1242    /// # Example
1243    ///
1244    /// ```
1245    /// use lru::LruCache;
1246    /// use std::num::NonZeroUsize;
1247    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1248    ///
1249    /// cache.put(2, "a");
1250    /// cache.put(3, "b");
1251    /// cache.put(4, "c");
1252    /// cache.get(&3);
1253    ///
1254    /// assert_eq!(cache.pop_mru(), Some((3, "b")));
1255    /// assert_eq!(cache.pop_mru(), Some((4, "c")));
1256    /// assert_eq!(cache.pop_mru(), None);
1257    /// assert_eq!(cache.len(), 0);
1258    /// ```
1259    pub fn pop_mru(&mut self) -> Option<(K, V)> {
1260        let node = self.remove_first()?;
1261        // N.B.: Can't destructure directly because of https://github.com/rust-lang/rust/issues/28536
1262        let node = *node;
1263        let LruEntry { key, val, .. } = node;
1264        unsafe { Some((key.assume_init(), val.assume_init())) }
1265    }
1266
1267    /// Marks the key as the most recently used one. Returns true if the key
1268    /// was promoted because it exists in the cache, false otherwise.
1269    ///
1270    /// # Example
1271    ///
1272    /// ```
1273    /// use lru::LruCache;
1274    /// use std::num::NonZeroUsize;
1275    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1276    ///
1277    /// cache.put(1, "a");
1278    /// cache.put(2, "b");
1279    /// cache.put(3, "c");
1280    /// cache.get(&1);
1281    /// cache.get(&2);
1282    ///
1283    /// // If we do `pop_lru` now, we would pop 3.
1284    /// // assert_eq!(cache.pop_lru(), Some((3, "c")));
1285    ///
1286    /// // By promoting 3, we make sure it isn't popped.
1287    /// assert!(cache.promote(&3));
1288    /// assert_eq!(cache.pop_lru(), Some((1, "a")));
1289    ///
1290    /// // Promoting an entry that doesn't exist doesn't do anything.
1291    /// assert!(!cache.promote(&4));
1292    /// ```
1293    pub fn promote<Q>(&mut self, k: &Q) -> bool
1294    where
1295        K: Borrow<Q>,
1296        Q: Hash + Eq + ?Sized,
1297    {
1298        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
1299            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1300            self.detach(node_ptr);
1301            self.attach(node_ptr);
1302            true
1303        } else {
1304            false
1305        }
1306    }
1307
1308    /// Marks the key as the least recently used one. Returns true if the key was demoted
1309    /// because it exists in the cache, false otherwise.
1310    ///
1311    /// # Example
1312    ///
1313    /// ```
1314    /// use lru::LruCache;
1315    /// use std::num::NonZeroUsize;
1316    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1317    ///
1318    /// cache.put(1, "a");
1319    /// cache.put(2, "b");
1320    /// cache.put(3, "c");
1321    /// cache.get(&1);
1322    /// cache.get(&2);
1323    ///
1324    /// // If we do `pop_lru` now, we would pop 3.
1325    /// // assert_eq!(cache.pop_lru(), Some((3, "c")));
1326    ///
1327    /// // By demoting 1 and 2, we make sure those are popped first.
1328    /// assert!(cache.demote(&2));
1329    /// assert!(cache.demote(&1));
1330    /// assert_eq!(cache.pop_lru(), Some((1, "a")));
1331    /// assert_eq!(cache.pop_lru(), Some((2, "b")));
1332    ///
1333    /// // Demoting a key that doesn't exist does nothing.
1334    /// assert!(!cache.demote(&4));
1335    /// ```
1336    pub fn demote<Q>(&mut self, k: &Q) -> bool
1337    where
1338        K: Borrow<Q>,
1339        Q: Hash + Eq + ?Sized,
1340    {
1341        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
1342            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1343            self.detach(node_ptr);
1344            self.attach_last(node_ptr);
1345            true
1346        } else {
1347            false
1348        }
1349    }
1350
1351    /// Returns the number of key-value pairs that are currently in the the cache.
1352    ///
1353    /// # Example
1354    ///
1355    /// ```
1356    /// use lru::LruCache;
1357    /// use std::num::NonZeroUsize;
1358    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1359    /// assert_eq!(cache.len(), 0);
1360    ///
1361    /// cache.put(1, "a");
1362    /// assert_eq!(cache.len(), 1);
1363    ///
1364    /// cache.put(2, "b");
1365    /// assert_eq!(cache.len(), 2);
1366    ///
1367    /// cache.put(3, "c");
1368    /// assert_eq!(cache.len(), 2);
1369    /// ```
1370    pub fn len(&self) -> usize {
1371        self.map.len()
1372    }
1373
1374    /// Returns a bool indicating whether the cache is empty or not.
1375    ///
1376    /// # Example
1377    ///
1378    /// ```
1379    /// use lru::LruCache;
1380    /// use std::num::NonZeroUsize;
1381    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1382    /// assert!(cache.is_empty());
1383    ///
1384    /// cache.put(1, "a");
1385    /// assert!(!cache.is_empty());
1386    /// ```
1387    pub fn is_empty(&self) -> bool {
1388        self.map.len() == 0
1389    }
1390
1391    /// Returns the maximum number of key-value pairs the cache can hold.
1392    ///
1393    /// # Example
1394    ///
1395    /// ```
1396    /// use lru::LruCache;
1397    /// use std::num::NonZeroUsize;
1398    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
1399    /// assert_eq!(cache.cap().get(), 2);
1400    /// ```
1401    pub fn cap(&self) -> NonZeroUsize {
1402        self.cap
1403    }
1404
1405    /// Resizes the cache. If the new capacity is smaller than the size of the current
1406    /// cache any entries past the new capacity are discarded.
1407    ///
1408    /// # Example
1409    ///
1410    /// ```
1411    /// use lru::LruCache;
1412    /// use std::num::NonZeroUsize;
1413    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
1414    ///
1415    /// cache.put(1, "a");
1416    /// cache.put(2, "b");
1417    /// cache.resize(NonZeroUsize::new(4).unwrap());
1418    /// cache.put(3, "c");
1419    /// cache.put(4, "d");
1420    ///
1421    /// assert_eq!(cache.len(), 4);
1422    /// assert_eq!(cache.get(&1), Some(&"a"));
1423    /// assert_eq!(cache.get(&2), Some(&"b"));
1424    /// assert_eq!(cache.get(&3), Some(&"c"));
1425    /// assert_eq!(cache.get(&4), Some(&"d"));
1426    /// ```
1427    pub fn resize(&mut self, cap: NonZeroUsize) {
1428        // return early if capacity doesn't change
1429        if cap == self.cap {
1430            return;
1431        }
1432
1433        while self.map.len() > cap.get() {
1434            self.pop_lru();
1435        }
1436        self.map.shrink_to_fit();
1437
1438        self.cap = cap;
1439    }
1440
1441    /// Clears the contents of the cache.
1442    ///
1443    /// # Example
1444    ///
1445    /// ```
1446    /// use lru::LruCache;
1447    /// use std::num::NonZeroUsize;
1448    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
1449    /// assert_eq!(cache.len(), 0);
1450    ///
1451    /// cache.put(1, "a");
1452    /// assert_eq!(cache.len(), 1);
1453    ///
1454    /// cache.put(2, "b");
1455    /// assert_eq!(cache.len(), 2);
1456    ///
1457    /// cache.clear();
1458    /// assert_eq!(cache.len(), 0);
1459    /// ```
1460    pub fn clear(&mut self) {
1461        while self.pop_lru().is_some() {}
1462    }
1463
1464    /// An iterator visiting all entries in most-recently used order. The iterator element type is
1465    /// `(&K, &V)`.
1466    ///
1467    /// # Examples
1468    ///
1469    /// ```
1470    /// use lru::LruCache;
1471    /// use std::num::NonZeroUsize;
1472    ///
1473    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1474    /// cache.put("a", 1);
1475    /// cache.put("b", 2);
1476    /// cache.put("c", 3);
1477    ///
1478    /// for (key, val) in cache.iter() {
1479    ///     println!("key: {} val: {}", key, val);
1480    /// }
1481    /// ```
1482    pub fn iter(&self) -> Iter<'_, K, V> {
1483        Iter {
1484            len: self.len(),
1485            ptr: unsafe { (*self.head).next },
1486            end: unsafe { (*self.tail).prev },
1487            phantom: PhantomData,
1488        }
1489    }
1490
1491    /// An iterator visiting all entries in most-recently-used order, giving a mutable reference on
1492    /// V.  The iterator element type is `(&K, &mut V)`.
1493    ///
1494    /// # Examples
1495    ///
1496    /// ```
1497    /// use lru::LruCache;
1498    /// use std::num::NonZeroUsize;
1499    ///
1500    /// struct HddBlock {
1501    ///     dirty: bool,
1502    ///     data: [u8; 512]
1503    /// }
1504    ///
1505    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1506    /// cache.put(0, HddBlock { dirty: false, data: [0x00; 512]});
1507    /// cache.put(1, HddBlock { dirty: true,  data: [0x55; 512]});
1508    /// cache.put(2, HddBlock { dirty: true,  data: [0x77; 512]});
1509    ///
1510    /// // write dirty blocks to disk.
1511    /// for (block_id, block) in cache.iter_mut() {
1512    ///     if block.dirty {
1513    ///         // write block to disk
1514    ///         block.dirty = false
1515    ///     }
1516    /// }
1517    /// ```
1518    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
1519        IterMut {
1520            len: self.len(),
1521            ptr: unsafe { (*self.head).next },
1522            end: unsafe { (*self.tail).prev },
1523            phantom: PhantomData,
1524        }
1525    }
1526
1527    fn remove_first(&mut self) -> Option<Box<LruEntry<K, V>>> {
1528        let next;
1529        unsafe { next = (*self.head).next }
1530        if !core::ptr::eq(next, self.tail) {
1531            let old_key = KeyRef {
1532                k: unsafe { &(*(*(*self.head).next).key.as_ptr()) },
1533            };
1534            let old_node = self.map.remove(&old_key).unwrap();
1535            let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
1536            self.detach(node_ptr);
1537            unsafe { Some(Box::from_raw(node_ptr)) }
1538        } else {
1539            None
1540        }
1541    }
1542
1543    fn remove_last(&mut self) -> Option<Box<LruEntry<K, V>>> {
1544        let prev;
1545        unsafe { prev = (*self.tail).prev }
1546        if !core::ptr::eq(prev, self.head) {
1547            let old_key = KeyRef {
1548                k: unsafe { &(*(*(*self.tail).prev).key.as_ptr()) },
1549            };
1550            let old_node = self.map.remove(&old_key).unwrap();
1551            let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
1552            self.detach(node_ptr);
1553            unsafe { Some(Box::from_raw(node_ptr)) }
1554        } else {
1555            None
1556        }
1557    }
1558
1559    fn detach(&mut self, node: *mut LruEntry<K, V>) {
1560        unsafe {
1561            (*(*node).prev).next = (*node).next;
1562            (*(*node).next).prev = (*node).prev;
1563        }
1564    }
1565
1566    // Attaches `node` after the sigil `self.head` node.
1567    fn attach(&mut self, node: *mut LruEntry<K, V>) {
1568        unsafe {
1569            (*node).next = (*self.head).next;
1570            (*node).prev = self.head;
1571            (*self.head).next = node;
1572            (*(*node).next).prev = node;
1573        }
1574    }
1575
1576    // Attaches `node` before the sigil `self.tail` node.
1577    fn attach_last(&mut self, node: *mut LruEntry<K, V>) {
1578        unsafe {
1579            (*node).next = self.tail;
1580            (*node).prev = (*self.tail).prev;
1581            (*self.tail).prev = node;
1582            (*(*node).prev).next = node;
1583        }
1584    }
1585}
1586
1587impl<K, V, S> Drop for LruCache<K, V, S> {
1588    fn drop(&mut self) {
1589        self.map.drain().for_each(|(_, node)| unsafe {
1590            let mut node = *Box::from_raw(node.as_ptr());
1591            ptr::drop_in_place((node).key.as_mut_ptr());
1592            ptr::drop_in_place((node).val.as_mut_ptr());
1593        });
1594        // We rebox the head/tail, and because these are maybe-uninit
1595        // they do not have the absent k/v dropped.
1596
1597        let _head = unsafe { *Box::from_raw(self.head) };
1598        let _tail = unsafe { *Box::from_raw(self.tail) };
1599    }
1600}
1601
1602impl<'a, K: Hash + Eq, V, S: BuildHasher> IntoIterator for &'a LruCache<K, V, S> {
1603    type Item = (&'a K, &'a V);
1604    type IntoIter = Iter<'a, K, V>;
1605
1606    fn into_iter(self) -> Iter<'a, K, V> {
1607        self.iter()
1608    }
1609}
1610
1611impl<'a, K: Hash + Eq, V, S: BuildHasher> IntoIterator for &'a mut LruCache<K, V, S> {
1612    type Item = (&'a K, &'a mut V);
1613    type IntoIter = IterMut<'a, K, V>;
1614
1615    fn into_iter(self) -> IterMut<'a, K, V> {
1616        self.iter_mut()
1617    }
1618}
1619
1620// The compiler does not automatically derive Send and Sync for LruCache because it contains
1621// raw pointers. The raw pointers are safely encapsulated by LruCache though so we can
1622// implement Send and Sync for it below.
1623unsafe impl<K: Send, V: Send, S: Send> Send for LruCache<K, V, S> {}
1624unsafe impl<K: Sync, V: Sync, S: Sync> Sync for LruCache<K, V, S> {}
1625
1626impl<K: Hash + Eq, V, S: BuildHasher> fmt::Debug for LruCache<K, V, S> {
1627    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1628        f.debug_struct("LruCache")
1629            .field("len", &self.len())
1630            .field("cap", &self.cap())
1631            .finish()
1632    }
1633}
1634
1635/// An iterator over the entries of a `LruCache`.
1636///
1637/// This `struct` is created by the [`iter`] method on [`LruCache`][`LruCache`]. See its
1638/// documentation for more.
1639///
1640/// [`iter`]: struct.LruCache.html#method.iter
1641/// [`LruCache`]: struct.LruCache.html
1642pub struct Iter<'a, K: 'a, V: 'a> {
1643    len: usize,
1644
1645    ptr: *const LruEntry<K, V>,
1646    end: *const LruEntry<K, V>,
1647
1648    phantom: PhantomData<&'a K>,
1649}
1650
1651impl<'a, K, V> Iterator for Iter<'a, K, V> {
1652    type Item = (&'a K, &'a V);
1653
1654    fn next(&mut self) -> Option<(&'a K, &'a V)> {
1655        if self.len == 0 {
1656            return None;
1657        }
1658
1659        let key = unsafe { &(*(*self.ptr).key.as_ptr()) as &K };
1660        let val = unsafe { &(*(*self.ptr).val.as_ptr()) as &V };
1661
1662        self.len -= 1;
1663        self.ptr = unsafe { (*self.ptr).next };
1664
1665        Some((key, val))
1666    }
1667
1668    fn size_hint(&self) -> (usize, Option<usize>) {
1669        (self.len, Some(self.len))
1670    }
1671
1672    fn count(self) -> usize {
1673        self.len
1674    }
1675}
1676
1677impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
1678    fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
1679        if self.len == 0 {
1680            return None;
1681        }
1682
1683        let key = unsafe { &(*(*self.end).key.as_ptr()) as &K };
1684        let val = unsafe { &(*(*self.end).val.as_ptr()) as &V };
1685
1686        self.len -= 1;
1687        self.end = unsafe { (*self.end).prev };
1688
1689        Some((key, val))
1690    }
1691}
1692
1693impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {}
1694impl<'a, K, V> FusedIterator for Iter<'a, K, V> {}
1695
1696impl<'a, K, V> Clone for Iter<'a, K, V> {
1697    fn clone(&self) -> Iter<'a, K, V> {
1698        Iter {
1699            len: self.len,
1700            ptr: self.ptr,
1701            end: self.end,
1702            phantom: PhantomData,
1703        }
1704    }
1705}
1706
1707// The compiler does not automatically derive Send and Sync for Iter because it contains
1708// raw pointers.
1709unsafe impl<'a, K: Send, V: Send> Send for Iter<'a, K, V> {}
1710unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
1711
1712/// An iterator over mutables entries of a `LruCache`.
1713///
1714/// This `struct` is created by the [`iter_mut`] method on [`LruCache`][`LruCache`]. See its
1715/// documentation for more.
1716///
1717/// [`iter_mut`]: struct.LruCache.html#method.iter_mut
1718/// [`LruCache`]: struct.LruCache.html
1719pub struct IterMut<'a, K: 'a, V: 'a> {
1720    len: usize,
1721
1722    ptr: *mut LruEntry<K, V>,
1723    end: *mut LruEntry<K, V>,
1724
1725    phantom: PhantomData<&'a K>,
1726}
1727
1728impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1729    type Item = (&'a K, &'a mut V);
1730
1731    fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
1732        if self.len == 0 {
1733            return None;
1734        }
1735
1736        let key = unsafe { &(*(*self.ptr).key.as_ptr()) as &K };
1737        let val = unsafe { &mut (*(*self.ptr).val.as_mut_ptr()) as &mut V };
1738
1739        self.len -= 1;
1740        self.ptr = unsafe { (*self.ptr).next };
1741
1742        Some((key, val))
1743    }
1744
1745    fn size_hint(&self) -> (usize, Option<usize>) {
1746        (self.len, Some(self.len))
1747    }
1748
1749    fn count(self) -> usize {
1750        self.len
1751    }
1752}
1753
1754impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> {
1755    fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
1756        if self.len == 0 {
1757            return None;
1758        }
1759
1760        let key = unsafe { &(*(*self.end).key.as_ptr()) as &K };
1761        let val = unsafe { &mut (*(*self.end).val.as_mut_ptr()) as &mut V };
1762
1763        self.len -= 1;
1764        self.end = unsafe { (*self.end).prev };
1765
1766        Some((key, val))
1767    }
1768}
1769
1770impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {}
1771impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}
1772
1773// The compiler does not automatically derive Send and Sync for Iter because it contains
1774// raw pointers.
1775unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {}
1776unsafe impl<'a, K: Sync, V: Sync> Sync for IterMut<'a, K, V> {}
1777
1778/// An iterator that moves out of a `LruCache`.
1779///
1780/// This `struct` is created by the [`into_iter`] method on [`LruCache`][`LruCache`]. See its
1781/// documentation for more.
1782///
1783/// [`into_iter`]: struct.LruCache.html#method.into_iter
1784/// [`LruCache`]: struct.LruCache.html
1785pub struct IntoIter<K, V>
1786where
1787    K: Hash + Eq,
1788{
1789    cache: LruCache<K, V>,
1790}
1791
1792impl<K, V> Iterator for IntoIter<K, V>
1793where
1794    K: Hash + Eq,
1795{
1796    type Item = (K, V);
1797
1798    fn next(&mut self) -> Option<(K, V)> {
1799        self.cache.pop_lru()
1800    }
1801
1802    fn size_hint(&self) -> (usize, Option<usize>) {
1803        let len = self.cache.len();
1804        (len, Some(len))
1805    }
1806
1807    fn count(self) -> usize {
1808        self.cache.len()
1809    }
1810}
1811
1812impl<K, V> ExactSizeIterator for IntoIter<K, V> where K: Hash + Eq {}
1813impl<K, V> FusedIterator for IntoIter<K, V> where K: Hash + Eq {}
1814
1815impl<K: Hash + Eq, V> IntoIterator for LruCache<K, V> {
1816    type Item = (K, V);
1817    type IntoIter = IntoIter<K, V>;
1818
1819    fn into_iter(self) -> IntoIter<K, V> {
1820        IntoIter { cache: self }
1821    }
1822}
1823
1824#[cfg(test)]
1825mod tests {
1826    use super::LruCache;
1827    use core::{fmt::Debug, num::NonZeroUsize};
1828    use scoped_threadpool::Pool;
1829    use std::rc::Rc;
1830    use std::sync::atomic::{AtomicUsize, Ordering};
1831
1832    fn assert_opt_eq<V: PartialEq + Debug>(opt: Option<&V>, v: V) {
1833        assert!(opt.is_some());
1834        assert_eq!(opt.unwrap(), &v);
1835    }
1836
1837    fn assert_opt_eq_mut<V: PartialEq + Debug>(opt: Option<&mut V>, v: V) {
1838        assert!(opt.is_some());
1839        assert_eq!(opt.unwrap(), &v);
1840    }
1841
1842    fn assert_opt_eq_tuple<K: PartialEq + Debug, V: PartialEq + Debug>(
1843        opt: Option<(&K, &V)>,
1844        kv: (K, V),
1845    ) {
1846        assert!(opt.is_some());
1847        let res = opt.unwrap();
1848        assert_eq!(res.0, &kv.0);
1849        assert_eq!(res.1, &kv.1);
1850    }
1851
1852    fn assert_opt_eq_mut_tuple<K: PartialEq + Debug, V: PartialEq + Debug>(
1853        opt: Option<(&K, &mut V)>,
1854        kv: (K, V),
1855    ) {
1856        assert!(opt.is_some());
1857        let res = opt.unwrap();
1858        assert_eq!(res.0, &kv.0);
1859        assert_eq!(res.1, &kv.1);
1860    }
1861
1862    #[test]
1863    fn test_unbounded() {
1864        let mut cache = LruCache::unbounded();
1865        for i in 0..13370 {
1866            cache.put(i, ());
1867        }
1868        assert_eq!(cache.len(), 13370);
1869    }
1870
1871    #[test]
1872    #[cfg(feature = "hashbrown")]
1873    fn test_with_hasher() {
1874        use core::num::NonZeroUsize;
1875
1876        use hashbrown::DefaultHashBuilder;
1877
1878        let s = DefaultHashBuilder::default();
1879        let mut cache = LruCache::with_hasher(NonZeroUsize::new(16).unwrap(), s);
1880
1881        for i in 0..13370 {
1882            cache.put(i, ());
1883        }
1884        assert_eq!(cache.len(), 16);
1885    }
1886
1887    #[test]
1888    fn test_put_and_get() {
1889        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1890        assert!(cache.is_empty());
1891
1892        assert_eq!(cache.put("apple", "red"), None);
1893        assert_eq!(cache.put("banana", "yellow"), None);
1894
1895        assert_eq!(cache.cap().get(), 2);
1896        assert_eq!(cache.len(), 2);
1897        assert!(!cache.is_empty());
1898        assert_opt_eq(cache.get(&"apple"), "red");
1899        assert_opt_eq(cache.get(&"banana"), "yellow");
1900    }
1901
1902    #[test]
1903    fn test_put_and_get_or_insert() {
1904        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1905        assert!(cache.is_empty());
1906
1907        assert_eq!(cache.put("apple", "red"), None);
1908        assert_eq!(cache.put("banana", "yellow"), None);
1909
1910        assert_eq!(cache.cap().get(), 2);
1911        assert_eq!(cache.len(), 2);
1912        assert!(!cache.is_empty());
1913        assert_eq!(cache.get_or_insert("apple", || "orange"), &"red");
1914        assert_eq!(cache.get_or_insert("banana", || "orange"), &"yellow");
1915        assert_eq!(cache.get_or_insert("lemon", || "orange"), &"orange");
1916        assert_eq!(cache.get_or_insert("lemon", || "red"), &"orange");
1917    }
1918
1919    #[test]
1920    fn test_get_or_insert_ref() {
1921        use alloc::borrow::ToOwned;
1922        use alloc::string::String;
1923
1924        let key1 = Rc::new("1".to_owned());
1925        let key2 = Rc::new("2".to_owned());
1926        let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
1927        assert!(cache.is_empty());
1928        assert_eq!(cache.get_or_insert_ref(&key1, || "One".to_owned()), "One");
1929        assert_eq!(cache.get_or_insert_ref(&key2, || "Two".to_owned()), "Two");
1930        assert_eq!(cache.len(), 2);
1931        assert!(!cache.is_empty());
1932        assert_eq!(
1933            cache.get_or_insert_ref(&key2, || "Not two".to_owned()),
1934            "Two"
1935        );
1936        assert_eq!(
1937            cache.get_or_insert_ref(&key2, || "Again not two".to_owned()),
1938            "Two"
1939        );
1940        assert_eq!(Rc::strong_count(&key1), 2);
1941        assert_eq!(Rc::strong_count(&key2), 2);
1942    }
1943
1944    #[test]
1945    fn test_try_get_or_insert() {
1946        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1947
1948        assert_eq!(
1949            cache.try_get_or_insert::<_, &str>("apple", || Ok("red")),
1950            Ok(&"red")
1951        );
1952        assert_eq!(
1953            cache.try_get_or_insert::<_, &str>("apple", || Err("failed")),
1954            Ok(&"red")
1955        );
1956        assert_eq!(
1957            cache.try_get_or_insert::<_, &str>("banana", || Ok("orange")),
1958            Ok(&"orange")
1959        );
1960        assert_eq!(
1961            cache.try_get_or_insert::<_, &str>("lemon", || Err("failed")),
1962            Err("failed")
1963        );
1964        assert_eq!(
1965            cache.try_get_or_insert::<_, &str>("banana", || Err("failed")),
1966            Ok(&"orange")
1967        );
1968    }
1969
1970    #[test]
1971    fn test_try_get_or_insert_ref() {
1972        use alloc::borrow::ToOwned;
1973        use alloc::string::String;
1974
1975        let key1 = Rc::new("1".to_owned());
1976        let key2 = Rc::new("2".to_owned());
1977        let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
1978        let f = || -> Result<String, ()> { Err(()) };
1979        let a = || -> Result<String, ()> { Ok("One".to_owned()) };
1980        let b = || -> Result<String, ()> { Ok("Two".to_owned()) };
1981        assert_eq!(cache.try_get_or_insert_ref(&key1, a), Ok(&"One".to_owned()));
1982        assert_eq!(cache.try_get_or_insert_ref(&key2, f), Err(()));
1983        assert_eq!(cache.try_get_or_insert_ref(&key2, b), Ok(&"Two".to_owned()));
1984        assert_eq!(cache.try_get_or_insert_ref(&key2, a), Ok(&"Two".to_owned()));
1985        assert_eq!(cache.len(), 2);
1986        assert_eq!(Rc::strong_count(&key1), 2);
1987        assert_eq!(Rc::strong_count(&key2), 2);
1988    }
1989
1990    #[test]
1991    fn test_put_and_get_or_insert_mut() {
1992        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1993        assert!(cache.is_empty());
1994
1995        assert_eq!(cache.put("apple", "red"), None);
1996        assert_eq!(cache.put("banana", "yellow"), None);
1997
1998        assert_eq!(cache.cap().get(), 2);
1999        assert_eq!(cache.len(), 2);
2000
2001        let v = cache.get_or_insert_mut("apple", || "orange");
2002        assert_eq!(v, &"red");
2003        *v = "blue";
2004
2005        assert_eq!(cache.get_or_insert_mut("apple", || "orange"), &"blue");
2006        assert_eq!(cache.get_or_insert_mut("banana", || "orange"), &"yellow");
2007        assert_eq!(cache.get_or_insert_mut("lemon", || "orange"), &"orange");
2008        assert_eq!(cache.get_or_insert_mut("lemon", || "red"), &"orange");
2009    }
2010
2011    #[test]
2012    fn test_get_or_insert_mut_ref() {
2013        use alloc::borrow::ToOwned;
2014        use alloc::string::String;
2015
2016        let key1 = Rc::new("1".to_owned());
2017        let key2 = Rc::new("2".to_owned());
2018        let mut cache = LruCache::<Rc<String>, &'static str>::new(NonZeroUsize::new(2).unwrap());
2019        assert_eq!(cache.get_or_insert_mut_ref(&key1, || "One"), &mut "One");
2020        let v = cache.get_or_insert_mut_ref(&key2, || "Two");
2021        *v = "New two";
2022        assert_eq!(cache.get_or_insert_mut_ref(&key2, || "Two"), &mut "New two");
2023        assert_eq!(Rc::strong_count(&key1), 2);
2024        assert_eq!(Rc::strong_count(&key2), 2);
2025    }
2026
2027    #[test]
2028    fn test_try_get_or_insert_mut() {
2029        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2030
2031        cache.put(1, "a");
2032        cache.put(2, "b");
2033        cache.put(2, "c");
2034
2035        let f = || -> Result<&str, &str> { Err("failed") };
2036        let a = || -> Result<&str, &str> { Ok("a") };
2037        let b = || -> Result<&str, &str> { Ok("b") };
2038        if let Ok(v) = cache.try_get_or_insert_mut(2, a) {
2039            *v = "d";
2040        }
2041        assert_eq!(cache.try_get_or_insert_mut(2, a), Ok(&mut "d"));
2042        assert_eq!(cache.try_get_or_insert_mut(3, f), Err("failed"));
2043        assert_eq!(cache.try_get_or_insert_mut(4, b), Ok(&mut "b"));
2044        assert_eq!(cache.try_get_or_insert_mut(4, a), Ok(&mut "b"));
2045    }
2046
2047    #[test]
2048    fn test_try_get_or_insert_mut_ref() {
2049        use alloc::borrow::ToOwned;
2050        use alloc::string::String;
2051
2052        let key1 = Rc::new("1".to_owned());
2053        let key2 = Rc::new("2".to_owned());
2054        let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
2055        let f = || -> Result<String, ()> { Err(()) };
2056        let a = || -> Result<String, ()> { Ok("One".to_owned()) };
2057        let b = || -> Result<String, ()> { Ok("Two".to_owned()) };
2058        assert_eq!(
2059            cache.try_get_or_insert_mut_ref(&key1, a),
2060            Ok(&mut "One".to_owned())
2061        );
2062        assert_eq!(cache.try_get_or_insert_mut_ref(&key2, f), Err(()));
2063        if let Ok(v) = cache.try_get_or_insert_mut_ref(&key2, b) {
2064            assert_eq!(v, &mut "Two");
2065            *v = "New two".to_owned();
2066        }
2067        assert_eq!(
2068            cache.try_get_or_insert_mut_ref(&key2, a),
2069            Ok(&mut "New two".to_owned())
2070        );
2071        assert_eq!(Rc::strong_count(&key1), 2);
2072        assert_eq!(Rc::strong_count(&key2), 2);
2073    }
2074
2075    #[test]
2076    fn test_put_and_get_mut() {
2077        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2078
2079        cache.put("apple", "red");
2080        cache.put("banana", "yellow");
2081
2082        assert_eq!(cache.cap().get(), 2);
2083        assert_eq!(cache.len(), 2);
2084        assert_opt_eq_mut(cache.get_mut(&"apple"), "red");
2085        assert_opt_eq_mut(cache.get_mut(&"banana"), "yellow");
2086    }
2087
2088    #[test]
2089    fn test_get_mut_and_update() {
2090        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2091
2092        cache.put("apple", 1);
2093        cache.put("banana", 3);
2094
2095        {
2096            let v = cache.get_mut(&"apple").unwrap();
2097            *v = 4;
2098        }
2099
2100        assert_eq!(cache.cap().get(), 2);
2101        assert_eq!(cache.len(), 2);
2102        assert_opt_eq_mut(cache.get_mut(&"apple"), 4);
2103        assert_opt_eq_mut(cache.get_mut(&"banana"), 3);
2104    }
2105
2106    #[test]
2107    fn test_put_update() {
2108        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2109
2110        assert_eq!(cache.put("apple", "red"), None);
2111        assert_eq!(cache.put("apple", "green"), Some("red"));
2112
2113        assert_eq!(cache.len(), 1);
2114        assert_opt_eq(cache.get(&"apple"), "green");
2115    }
2116
2117    #[test]
2118    fn test_put_removes_oldest() {
2119        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2120
2121        assert_eq!(cache.put("apple", "red"), None);
2122        assert_eq!(cache.put("banana", "yellow"), None);
2123        assert_eq!(cache.put("pear", "green"), None);
2124
2125        assert!(cache.get(&"apple").is_none());
2126        assert_opt_eq(cache.get(&"banana"), "yellow");
2127        assert_opt_eq(cache.get(&"pear"), "green");
2128
2129        // Even though we inserted "apple" into the cache earlier it has since been removed from
2130        // the cache so there is no current value for `put` to return.
2131        assert_eq!(cache.put("apple", "green"), None);
2132        assert_eq!(cache.put("tomato", "red"), None);
2133
2134        assert!(cache.get(&"pear").is_none());
2135        assert_opt_eq(cache.get(&"apple"), "green");
2136        assert_opt_eq(cache.get(&"tomato"), "red");
2137    }
2138
2139    #[test]
2140    fn test_peek() {
2141        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2142
2143        cache.put("apple", "red");
2144        cache.put("banana", "yellow");
2145
2146        assert_opt_eq(cache.peek(&"banana"), "yellow");
2147        assert_opt_eq(cache.peek(&"apple"), "red");
2148
2149        cache.put("pear", "green");
2150
2151        assert!(cache.peek(&"apple").is_none());
2152        assert_opt_eq(cache.peek(&"banana"), "yellow");
2153        assert_opt_eq(cache.peek(&"pear"), "green");
2154    }
2155
2156    #[test]
2157    fn test_peek_mut() {
2158        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2159
2160        cache.put("apple", "red");
2161        cache.put("banana", "yellow");
2162
2163        assert_opt_eq_mut(cache.peek_mut(&"banana"), "yellow");
2164        assert_opt_eq_mut(cache.peek_mut(&"apple"), "red");
2165        assert!(cache.peek_mut(&"pear").is_none());
2166
2167        cache.put("pear", "green");
2168
2169        assert!(cache.peek_mut(&"apple").is_none());
2170        assert_opt_eq_mut(cache.peek_mut(&"banana"), "yellow");
2171        assert_opt_eq_mut(cache.peek_mut(&"pear"), "green");
2172
2173        {
2174            let v = cache.peek_mut(&"banana").unwrap();
2175            *v = "green";
2176        }
2177
2178        assert_opt_eq_mut(cache.peek_mut(&"banana"), "green");
2179    }
2180
2181    #[test]
2182    fn test_peek_lru() {
2183        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2184
2185        assert!(cache.peek_lru().is_none());
2186
2187        cache.put("apple", "red");
2188        cache.put("banana", "yellow");
2189        assert_opt_eq_tuple(cache.peek_lru(), ("apple", "red"));
2190
2191        cache.get(&"apple");
2192        assert_opt_eq_tuple(cache.peek_lru(), ("banana", "yellow"));
2193
2194        cache.clear();
2195        assert!(cache.peek_lru().is_none());
2196    }
2197
2198    #[test]
2199    fn test_peek_mru() {
2200        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2201
2202        assert!(cache.peek_mru().is_none());
2203
2204        cache.put("apple", "red");
2205        cache.put("banana", "yellow");
2206        assert_opt_eq_tuple(cache.peek_mru(), ("banana", "yellow"));
2207
2208        cache.get(&"apple");
2209        assert_opt_eq_tuple(cache.peek_mru(), ("apple", "red"));
2210
2211        cache.clear();
2212        assert!(cache.peek_mru().is_none());
2213    }
2214
2215    #[test]
2216    fn test_contains() {
2217        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2218
2219        cache.put("apple", "red");
2220        cache.put("banana", "yellow");
2221        cache.put("pear", "green");
2222
2223        assert!(!cache.contains(&"apple"));
2224        assert!(cache.contains(&"banana"));
2225        assert!(cache.contains(&"pear"));
2226    }
2227
2228    #[test]
2229    fn test_pop() {
2230        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2231
2232        cache.put("apple", "red");
2233        cache.put("banana", "yellow");
2234
2235        assert_eq!(cache.len(), 2);
2236        assert_opt_eq(cache.get(&"apple"), "red");
2237        assert_opt_eq(cache.get(&"banana"), "yellow");
2238
2239        let popped = cache.pop(&"apple");
2240        assert!(popped.is_some());
2241        assert_eq!(popped.unwrap(), "red");
2242        assert_eq!(cache.len(), 1);
2243        assert!(cache.get(&"apple").is_none());
2244        assert_opt_eq(cache.get(&"banana"), "yellow");
2245    }
2246
2247    #[test]
2248    fn test_pop_entry() {
2249        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2250        cache.put("apple", "red");
2251        cache.put("banana", "yellow");
2252
2253        assert_eq!(cache.len(), 2);
2254        assert_opt_eq(cache.get(&"apple"), "red");
2255        assert_opt_eq(cache.get(&"banana"), "yellow");
2256
2257        let popped = cache.pop_entry(&"apple");
2258        assert!(popped.is_some());
2259        assert_eq!(popped.unwrap(), ("apple", "red"));
2260        assert_eq!(cache.len(), 1);
2261        assert!(cache.get(&"apple").is_none());
2262        assert_opt_eq(cache.get(&"banana"), "yellow");
2263    }
2264
2265    #[test]
2266    fn test_pop_lru() {
2267        let mut cache = LruCache::new(NonZeroUsize::new(200).unwrap());
2268
2269        for i in 0..75 {
2270            cache.put(i, "A");
2271        }
2272        for i in 0..75 {
2273            cache.put(i + 100, "B");
2274        }
2275        for i in 0..75 {
2276            cache.put(i + 200, "C");
2277        }
2278        assert_eq!(cache.len(), 200);
2279
2280        for i in 0..75 {
2281            assert_opt_eq(cache.get(&(74 - i + 100)), "B");
2282        }
2283        assert_opt_eq(cache.get(&25), "A");
2284
2285        for i in 26..75 {
2286            assert_eq!(cache.pop_lru(), Some((i, "A")));
2287        }
2288        for i in 0..75 {
2289            assert_eq!(cache.pop_lru(), Some((i + 200, "C")));
2290        }
2291        for i in 0..75 {
2292            assert_eq!(cache.pop_lru(), Some((74 - i + 100, "B")));
2293        }
2294        assert_eq!(cache.pop_lru(), Some((25, "A")));
2295        for _ in 0..50 {
2296            assert_eq!(cache.pop_lru(), None);
2297        }
2298    }
2299
2300    #[test]
2301    fn test_pop_mru() {
2302        let mut cache = LruCache::new(NonZeroUsize::new(200).unwrap());
2303
2304        for i in 0..75 {
2305            cache.put(i, "A");
2306        }
2307        for i in 0..75 {
2308            cache.put(i + 100, "B");
2309        }
2310        for i in 0..75 {
2311            cache.put(i + 200, "C");
2312        }
2313        assert_eq!(cache.len(), 200);
2314
2315        for i in 0..75 {
2316            assert_opt_eq(cache.get(&(74 - i + 100)), "B");
2317        }
2318        assert_opt_eq(cache.get(&25), "A");
2319
2320        assert_eq!(cache.pop_mru(), Some((25, "A")));
2321        for i in 0..75 {
2322            assert_eq!(cache.pop_mru(), Some((i + 100, "B")));
2323        }
2324        for i in 0..75 {
2325            assert_eq!(cache.pop_mru(), Some((74 - i + 200, "C")));
2326        }
2327        for i in (26..75).into_iter().rev() {
2328            assert_eq!(cache.pop_mru(), Some((i, "A")));
2329        }
2330        for _ in 0..50 {
2331            assert_eq!(cache.pop_mru(), None);
2332        }
2333    }
2334
2335    #[test]
2336    fn test_clear() {
2337        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2338
2339        cache.put("apple", "red");
2340        cache.put("banana", "yellow");
2341
2342        assert_eq!(cache.len(), 2);
2343        assert_opt_eq(cache.get(&"apple"), "red");
2344        assert_opt_eq(cache.get(&"banana"), "yellow");
2345
2346        cache.clear();
2347        assert_eq!(cache.len(), 0);
2348    }
2349
2350    #[test]
2351    fn test_resize_larger() {
2352        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2353
2354        cache.put(1, "a");
2355        cache.put(2, "b");
2356        cache.resize(NonZeroUsize::new(4).unwrap());
2357        cache.put(3, "c");
2358        cache.put(4, "d");
2359
2360        assert_eq!(cache.len(), 4);
2361        assert_eq!(cache.get(&1), Some(&"a"));
2362        assert_eq!(cache.get(&2), Some(&"b"));
2363        assert_eq!(cache.get(&3), Some(&"c"));
2364        assert_eq!(cache.get(&4), Some(&"d"));
2365    }
2366
2367    #[test]
2368    fn test_resize_smaller() {
2369        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2370
2371        cache.put(1, "a");
2372        cache.put(2, "b");
2373        cache.put(3, "c");
2374        cache.put(4, "d");
2375
2376        cache.resize(NonZeroUsize::new(2).unwrap());
2377
2378        assert_eq!(cache.len(), 2);
2379        assert!(cache.get(&1).is_none());
2380        assert!(cache.get(&2).is_none());
2381        assert_eq!(cache.get(&3), Some(&"c"));
2382        assert_eq!(cache.get(&4), Some(&"d"));
2383    }
2384
2385    #[test]
2386    fn test_send() {
2387        use std::thread;
2388
2389        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2390        cache.put(1, "a");
2391
2392        let handle = thread::spawn(move || {
2393            assert_eq!(cache.get(&1), Some(&"a"));
2394        });
2395
2396        assert!(handle.join().is_ok());
2397    }
2398
2399    #[test]
2400    fn test_multiple_threads() {
2401        let mut pool = Pool::new(1);
2402        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2403        cache.put(1, "a");
2404
2405        let cache_ref = &cache;
2406        pool.scoped(|scoped| {
2407            scoped.execute(move || {
2408                assert_eq!(cache_ref.peek(&1), Some(&"a"));
2409            });
2410        });
2411
2412        assert_eq!((cache_ref).peek(&1), Some(&"a"));
2413    }
2414
2415    #[test]
2416    fn test_iter_forwards() {
2417        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2418        cache.put("a", 1);
2419        cache.put("b", 2);
2420        cache.put("c", 3);
2421
2422        {
2423            // iter const
2424            let mut iter = cache.iter();
2425            assert_eq!(iter.len(), 3);
2426            assert_opt_eq_tuple(iter.next(), ("c", 3));
2427
2428            assert_eq!(iter.len(), 2);
2429            assert_opt_eq_tuple(iter.next(), ("b", 2));
2430
2431            assert_eq!(iter.len(), 1);
2432            assert_opt_eq_tuple(iter.next(), ("a", 1));
2433
2434            assert_eq!(iter.len(), 0);
2435            assert_eq!(iter.next(), None);
2436        }
2437        {
2438            // iter mut
2439            let mut iter = cache.iter_mut();
2440            assert_eq!(iter.len(), 3);
2441            assert_opt_eq_mut_tuple(iter.next(), ("c", 3));
2442
2443            assert_eq!(iter.len(), 2);
2444            assert_opt_eq_mut_tuple(iter.next(), ("b", 2));
2445
2446            assert_eq!(iter.len(), 1);
2447            assert_opt_eq_mut_tuple(iter.next(), ("a", 1));
2448
2449            assert_eq!(iter.len(), 0);
2450            assert_eq!(iter.next(), None);
2451        }
2452    }
2453
2454    #[test]
2455    fn test_iter_backwards() {
2456        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2457        cache.put("a", 1);
2458        cache.put("b", 2);
2459        cache.put("c", 3);
2460
2461        {
2462            // iter const
2463            let mut iter = cache.iter();
2464            assert_eq!(iter.len(), 3);
2465            assert_opt_eq_tuple(iter.next_back(), ("a", 1));
2466
2467            assert_eq!(iter.len(), 2);
2468            assert_opt_eq_tuple(iter.next_back(), ("b", 2));
2469
2470            assert_eq!(iter.len(), 1);
2471            assert_opt_eq_tuple(iter.next_back(), ("c", 3));
2472
2473            assert_eq!(iter.len(), 0);
2474            assert_eq!(iter.next_back(), None);
2475        }
2476
2477        {
2478            // iter mut
2479            let mut iter = cache.iter_mut();
2480            assert_eq!(iter.len(), 3);
2481            assert_opt_eq_mut_tuple(iter.next_back(), ("a", 1));
2482
2483            assert_eq!(iter.len(), 2);
2484            assert_opt_eq_mut_tuple(iter.next_back(), ("b", 2));
2485
2486            assert_eq!(iter.len(), 1);
2487            assert_opt_eq_mut_tuple(iter.next_back(), ("c", 3));
2488
2489            assert_eq!(iter.len(), 0);
2490            assert_eq!(iter.next_back(), None);
2491        }
2492    }
2493
2494    #[test]
2495    fn test_iter_forwards_and_backwards() {
2496        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2497        cache.put("a", 1);
2498        cache.put("b", 2);
2499        cache.put("c", 3);
2500
2501        {
2502            // iter const
2503            let mut iter = cache.iter();
2504            assert_eq!(iter.len(), 3);
2505            assert_opt_eq_tuple(iter.next(), ("c", 3));
2506
2507            assert_eq!(iter.len(), 2);
2508            assert_opt_eq_tuple(iter.next_back(), ("a", 1));
2509
2510            assert_eq!(iter.len(), 1);
2511            assert_opt_eq_tuple(iter.next(), ("b", 2));
2512
2513            assert_eq!(iter.len(), 0);
2514            assert_eq!(iter.next_back(), None);
2515        }
2516        {
2517            // iter mut
2518            let mut iter = cache.iter_mut();
2519            assert_eq!(iter.len(), 3);
2520            assert_opt_eq_mut_tuple(iter.next(), ("c", 3));
2521
2522            assert_eq!(iter.len(), 2);
2523            assert_opt_eq_mut_tuple(iter.next_back(), ("a", 1));
2524
2525            assert_eq!(iter.len(), 1);
2526            assert_opt_eq_mut_tuple(iter.next(), ("b", 2));
2527
2528            assert_eq!(iter.len(), 0);
2529            assert_eq!(iter.next_back(), None);
2530        }
2531    }
2532
2533    #[test]
2534    fn test_iter_multiple_threads() {
2535        let mut pool = Pool::new(1);
2536        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2537        cache.put("a", 1);
2538        cache.put("b", 2);
2539        cache.put("c", 3);
2540
2541        let mut iter = cache.iter();
2542        assert_eq!(iter.len(), 3);
2543        assert_opt_eq_tuple(iter.next(), ("c", 3));
2544
2545        {
2546            let iter_ref = &mut iter;
2547            pool.scoped(|scoped| {
2548                scoped.execute(move || {
2549                    assert_eq!(iter_ref.len(), 2);
2550                    assert_opt_eq_tuple(iter_ref.next(), ("b", 2));
2551                });
2552            });
2553        }
2554
2555        assert_eq!(iter.len(), 1);
2556        assert_opt_eq_tuple(iter.next(), ("a", 1));
2557
2558        assert_eq!(iter.len(), 0);
2559        assert_eq!(iter.next(), None);
2560    }
2561
2562    #[test]
2563    fn test_iter_clone() {
2564        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2565        cache.put("a", 1);
2566        cache.put("b", 2);
2567
2568        let mut iter = cache.iter();
2569        let mut iter_clone = iter.clone();
2570
2571        assert_eq!(iter.len(), 2);
2572        assert_opt_eq_tuple(iter.next(), ("b", 2));
2573        assert_eq!(iter_clone.len(), 2);
2574        assert_opt_eq_tuple(iter_clone.next(), ("b", 2));
2575
2576        assert_eq!(iter.len(), 1);
2577        assert_opt_eq_tuple(iter.next(), ("a", 1));
2578        assert_eq!(iter_clone.len(), 1);
2579        assert_opt_eq_tuple(iter_clone.next(), ("a", 1));
2580
2581        assert_eq!(iter.len(), 0);
2582        assert_eq!(iter.next(), None);
2583        assert_eq!(iter_clone.len(), 0);
2584        assert_eq!(iter_clone.next(), None);
2585    }
2586
2587    #[test]
2588    fn test_into_iter() {
2589        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2590        cache.put("a", 1);
2591        cache.put("b", 2);
2592        cache.put("c", 3);
2593
2594        let mut iter = cache.into_iter();
2595        assert_eq!(iter.len(), 3);
2596        assert_eq!(iter.next(), Some(("a", 1)));
2597
2598        assert_eq!(iter.len(), 2);
2599        assert_eq!(iter.next(), Some(("b", 2)));
2600
2601        assert_eq!(iter.len(), 1);
2602        assert_eq!(iter.next(), Some(("c", 3)));
2603
2604        assert_eq!(iter.len(), 0);
2605        assert_eq!(iter.next(), None);
2606    }
2607
2608    #[test]
2609    fn test_that_pop_actually_detaches_node() {
2610        let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
2611
2612        cache.put("a", 1);
2613        cache.put("b", 2);
2614        cache.put("c", 3);
2615        cache.put("d", 4);
2616        cache.put("e", 5);
2617
2618        assert_eq!(cache.pop(&"c"), Some(3));
2619
2620        cache.put("f", 6);
2621
2622        let mut iter = cache.iter();
2623        assert_opt_eq_tuple(iter.next(), ("f", 6));
2624        assert_opt_eq_tuple(iter.next(), ("e", 5));
2625        assert_opt_eq_tuple(iter.next(), ("d", 4));
2626        assert_opt_eq_tuple(iter.next(), ("b", 2));
2627        assert_opt_eq_tuple(iter.next(), ("a", 1));
2628        assert!(iter.next().is_none());
2629    }
2630
2631    #[test]
2632    fn test_get_with_borrow() {
2633        use alloc::string::String;
2634
2635        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2636
2637        let key = String::from("apple");
2638        cache.put(key, "red");
2639
2640        assert_opt_eq(cache.get("apple"), "red");
2641    }
2642
2643    #[test]
2644    fn test_get_mut_with_borrow() {
2645        use alloc::string::String;
2646
2647        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2648
2649        let key = String::from("apple");
2650        cache.put(key, "red");
2651
2652        assert_opt_eq_mut(cache.get_mut("apple"), "red");
2653    }
2654
2655    #[test]
2656    fn test_no_memory_leaks() {
2657        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2658
2659        struct DropCounter;
2660
2661        impl Drop for DropCounter {
2662            fn drop(&mut self) {
2663                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2664            }
2665        }
2666
2667        let n = 100;
2668        for _ in 0..n {
2669            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2670            for i in 0..n {
2671                cache.put(i, DropCounter {});
2672            }
2673        }
2674        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
2675    }
2676
2677    #[test]
2678    fn test_no_memory_leaks_with_clear() {
2679        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2680
2681        struct DropCounter;
2682
2683        impl Drop for DropCounter {
2684            fn drop(&mut self) {
2685                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2686            }
2687        }
2688
2689        let n = 100;
2690        for _ in 0..n {
2691            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2692            for i in 0..n {
2693                cache.put(i, DropCounter {});
2694            }
2695            cache.clear();
2696        }
2697        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
2698    }
2699
2700    #[test]
2701    fn test_no_memory_leaks_with_resize() {
2702        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2703
2704        struct DropCounter;
2705
2706        impl Drop for DropCounter {
2707            fn drop(&mut self) {
2708                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2709            }
2710        }
2711
2712        let n = 100;
2713        for _ in 0..n {
2714            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2715            for i in 0..n {
2716                cache.put(i, DropCounter {});
2717            }
2718            cache.clear();
2719        }
2720        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
2721    }
2722
2723    #[test]
2724    fn test_no_memory_leaks_with_pop() {
2725        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2726
2727        #[derive(Hash, Eq)]
2728        struct KeyDropCounter(usize);
2729
2730        impl PartialEq for KeyDropCounter {
2731            fn eq(&self, other: &Self) -> bool {
2732                self.0.eq(&other.0)
2733            }
2734        }
2735
2736        impl Drop for KeyDropCounter {
2737            fn drop(&mut self) {
2738                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2739            }
2740        }
2741
2742        let n = 100;
2743        for _ in 0..n {
2744            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2745
2746            for i in 0..100 {
2747                cache.put(KeyDropCounter(i), i);
2748                cache.pop(&KeyDropCounter(i));
2749            }
2750        }
2751
2752        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n * 2);
2753    }
2754
2755    #[test]
2756    fn test_promote_and_demote() {
2757        let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
2758        for i in 0..5 {
2759            cache.push(i, i);
2760        }
2761        cache.promote(&1);
2762        cache.promote(&0);
2763        cache.demote(&3);
2764        cache.demote(&4);
2765        assert_eq!(cache.pop_lru(), Some((4, 4)));
2766        assert_eq!(cache.pop_lru(), Some((3, 3)));
2767        assert_eq!(cache.pop_lru(), Some((2, 2)));
2768        assert_eq!(cache.pop_lru(), Some((1, 1)));
2769        assert_eq!(cache.pop_lru(), Some((0, 0)));
2770        assert_eq!(cache.pop_lru(), None);
2771    }
2772
2773    #[test]
2774    fn test_get_key_value() {
2775        use alloc::string::String;
2776
2777        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2778
2779        let key = String::from("apple");
2780        cache.put(key, "red");
2781
2782        assert_eq!(
2783            cache.get_key_value("apple"),
2784            Some((&String::from("apple"), &"red"))
2785        );
2786        assert_eq!(cache.get_key_value("banana"), None);
2787    }
2788
2789    #[test]
2790    fn test_get_key_value_mut() {
2791        use alloc::string::String;
2792
2793        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2794
2795        let key = String::from("apple");
2796        cache.put(key, "red");
2797
2798        let (k, v) = cache.get_key_value_mut("apple").unwrap();
2799        assert_eq!(k, &String::from("apple"));
2800        assert_eq!(v, &mut "red");
2801        *v = "green";
2802
2803        assert_eq!(
2804            cache.get_key_value("apple"),
2805            Some((&String::from("apple"), &"green"))
2806        );
2807        assert_eq!(cache.get_key_value("banana"), None);
2808    }
2809
2810    #[test]
2811    fn test_clone() {
2812        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2813        cache.put("a", 1);
2814        cache.put("b", 2);
2815        cache.put("c", 3);
2816
2817        let mut cloned = cache.clone();
2818
2819        assert_eq!(cache.pop_lru(), Some(("a", 1)));
2820        assert_eq!(cloned.pop_lru(), Some(("a", 1)));
2821
2822        assert_eq!(cache.pop_lru(), Some(("b", 2)));
2823        assert_eq!(cloned.pop_lru(), Some(("b", 2)));
2824
2825        assert_eq!(cache.pop_lru(), Some(("c", 3)));
2826        assert_eq!(cloned.pop_lru(), Some(("c", 3)));
2827
2828        assert_eq!(cache.pop_lru(), None);
2829        assert_eq!(cloned.pop_lru(), None);
2830    }
2831
2832    #[test]
2833    fn test_clone_unbounded() {
2834        let mut cache = LruCache::unbounded();
2835        cache.put("a", 1);
2836        cache.put("b", 2);
2837        cache.put("c", 3);
2838
2839        let mut cloned = cache.clone();
2840
2841        assert_eq!(cache.pop_lru(), Some(("a", 1)));
2842        assert_eq!(cloned.pop_lru(), Some(("a", 1)));
2843
2844        assert_eq!(cache.pop_lru(), Some(("b", 2)));
2845        assert_eq!(cloned.pop_lru(), Some(("b", 2)));
2846
2847        assert_eq!(cache.pop_lru(), Some(("c", 3)));
2848        assert_eq!(cloned.pop_lru(), Some(("c", 3)));
2849
2850        assert_eq!(cache.pop_lru(), None);
2851        assert_eq!(cloned.pop_lru(), None);
2852    }
2853
2854    #[test]
2855    fn iter_mut_stacked_borrows_violation() {
2856        let mut cache: LruCache<i32, i32> = LruCache::new(NonZeroUsize::new(3).unwrap());
2857        cache.put(1, 10);
2858        cache.put(2, 20);
2859        cache.put(3, 30);
2860
2861        for (_k, v) in cache.iter_mut() {
2862            *v *= 2;
2863        }
2864
2865        assert_eq!(cache.get(&1), Some(&20));
2866        assert_eq!(cache.get(&2), Some(&40));
2867        assert_eq!(cache.get(&3), Some(&60));
2868    }
2869}
2870
2871/// Doctests for what should *not* compile
2872///
2873/// ```compile_fail
2874/// let mut cache = lru::LruCache::<u32, u32>::unbounded();
2875/// let _: &'static u32 = cache.get_or_insert(0, || 92);
2876/// ```
2877///
2878/// ```compile_fail
2879/// let mut cache = lru::LruCache::<u32, u32>::unbounded();
2880/// let _: Option<(&'static u32, _)> = cache.peek_lru();
2881/// let _: Option<(_, &'static u32)> = cache.peek_lru();
2882/// ```
2883fn _test_lifetimes() {}