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        self.get_or_insert_with_key(k, |_| f())
606    }
607
608    /// Returns a reference to the value of the key in the cache if it is
609    /// present in the cache and moves the key to the head of the LRU list.
610    /// If the key does not exist the provided `FnOnce` is used by passing
611    /// a reference to the key to populate the list and a reference is returned.
612    ///
613    /// # Example
614    ///
615    /// ```
616    /// use lru::LruCache;
617    /// use std::num::NonZeroUsize;
618    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
619    ///
620    /// cache.put("One", 1);
621    /// cache.put("Two", 2);
622    /// cache.put("Two", 3);
623    /// cache.put("Three", 4);
624    ///
625    /// assert_eq!(cache.get_or_insert_with_key("Two", |_|1), &3);
626    /// assert_eq!(cache.get_or_insert_with_key("Three", |k|k.len()), &4);
627    /// assert_eq!(cache.get_or_insert_with_key("One", |_|1), &1);
628    /// assert_eq!(cache.get_or_insert_with_key("One", |k|k.len()), &1);
629    /// ```
630    pub fn get_or_insert_with_key<F>(&mut self, k: K, f: F) -> &V
631    where
632        F: FnOnce(&K) -> V,
633    {
634        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
635            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
636
637            self.detach(node_ptr);
638            self.attach(node_ptr);
639
640            unsafe { &*(*node_ptr).val.as_ptr() }
641        } else {
642            let v = f(&k);
643            let (_, node) = self.replace_or_create_node(k, v);
644            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
645
646            self.attach(node_ptr);
647
648            let keyref = unsafe { (*node_ptr).key.as_ptr() };
649            self.map.insert(KeyRef { k: keyref }, node);
650            unsafe { &*(*node_ptr).val.as_ptr() }
651        }
652    }
653
654    /// Returns a reference to the value of the key in the cache if it is
655    /// present in the cache and moves the key to the head of the LRU list.
656    /// If the key does not exist the provided `FnOnce` is used to populate
657    /// the list and a reference is returned. The value referenced by the
658    /// key is only cloned (using `to_owned()`) if it doesn't exist in the
659    /// cache.
660    ///
661    /// # Example
662    ///
663    /// ```
664    /// use lru::LruCache;
665    /// use std::num::NonZeroUsize;
666    /// use std::rc::Rc;
667    ///
668    /// let key1 = Rc::new("1".to_owned());
669    /// let key2 = Rc::new("2".to_owned());
670    /// let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
671    /// assert_eq!(cache.get_or_insert_ref(&key1, ||"One".to_owned()), "One");
672    /// assert_eq!(cache.get_or_insert_ref(&key2, ||"Two".to_owned()), "Two");
673    /// assert_eq!(cache.get_or_insert_ref(&key2, ||"Not two".to_owned()), "Two");
674    /// assert_eq!(cache.get_or_insert_ref(&key2, ||"Again not two".to_owned()), "Two");
675    /// assert_eq!(Rc::strong_count(&key1), 2);
676    /// assert_eq!(Rc::strong_count(&key2), 2); // key2 was only cloned once even though we
677    ///                                         // queried it 3 times
678    /// ```
679    pub fn get_or_insert_ref<'a, Q, F>(&'a mut self, k: &'_ Q, f: F) -> &'a V
680    where
681        K: Borrow<Q>,
682        Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
683        F: FnOnce() -> V,
684    {
685        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
686            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
687
688            self.detach(node_ptr);
689            self.attach(node_ptr);
690
691            unsafe { &*(*node_ptr).val.as_ptr() }
692        } else {
693            let v = f();
694            let (_, node) = self.replace_or_create_node(k.to_owned(), v);
695            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
696
697            self.attach(node_ptr);
698
699            let keyref = unsafe { (*node_ptr).key.as_ptr() };
700            self.map.insert(KeyRef { k: keyref }, node);
701            unsafe { &*(*node_ptr).val.as_ptr() }
702        }
703    }
704
705    /// Returns a reference to the value of the key in the cache if it is
706    /// present in the cache and moves the key to the head of the LRU list.
707    /// If the key does not exist the provided `FnOnce` is used to populate
708    /// the list and a reference is returned. If `FnOnce` returns `Err`,
709    /// returns the `Err`.
710    ///
711    /// # Example
712    ///
713    /// ```
714    /// use lru::LruCache;
715    /// use std::num::NonZeroUsize;
716    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
717    ///
718    /// cache.put(1, "a");
719    /// cache.put(2, "b");
720    /// cache.put(2, "c");
721    /// cache.put(3, "d");
722    ///
723    /// let f = ||->Result<&str, String> {Err("failed".to_owned())};
724    /// let a = ||->Result<&str, String> {Ok("a")};
725    /// let b = ||->Result<&str, String> {Ok("b")};
726    /// assert_eq!(cache.try_get_or_insert(2, a), Ok(&"c"));
727    /// assert_eq!(cache.try_get_or_insert(3, a), Ok(&"d"));
728    /// assert_eq!(cache.try_get_or_insert(4, f), Err("failed".to_owned()));
729    /// assert_eq!(cache.try_get_or_insert(5, b), Ok(&"b"));
730    /// assert_eq!(cache.try_get_or_insert(5, a), Ok(&"b"));
731    /// ```
732    pub fn try_get_or_insert<F, E>(&mut self, k: K, f: F) -> Result<&V, E>
733    where
734        F: FnOnce() -> Result<V, E>,
735    {
736        self.try_get_or_insert_with_key(k, |_| f())
737    }
738
739    /// Returns a reference to the value of the key in the cache if it is
740    /// present in the cache and moves the key to the head of the LRU list.
741    /// If the key does not exist the provided `FnOnce` is used by passing
742    /// a reference to the key to populate the list and a reference is returned.
743    /// If `FnOnce` returns `Err`, returns the `Err`.
744    ///
745    /// # Example
746    ///
747    /// ```
748    /// use lru::LruCache;
749    /// use std::num::NonZeroUsize;
750    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
751    ///
752    /// cache.put("One", 1);
753    /// cache.put("Two", 2);
754    /// cache.put("Two", 3);
755    /// cache.put("Three", 4);
756    ///
757    /// let f = |_: &&str|->Result<usize, String> {Err("failed".to_owned())};
758    /// let len = |k: &&str|->Result<usize, String> {Ok(k.len())};
759    /// let zero = |_: &&str|->Result<usize, String> {Ok(0)};
760    /// assert_eq!(cache.try_get_or_insert_with_key("Two", len), Ok(&3));
761    /// assert_eq!(cache.try_get_or_insert_with_key("Three", len), Ok(&4));
762    /// assert_eq!(cache.try_get_or_insert_with_key("Four", f), Err("failed".to_owned()));
763    /// assert_eq!(cache.try_get_or_insert_with_key("Five", len), Ok(&4));
764    /// assert_eq!(cache.try_get_or_insert_with_key("Five", zero), Ok(&4));
765    /// ```
766    pub fn try_get_or_insert_with_key<F, E>(&mut self, k: K, f: F) -> Result<&V, E>
767    where
768        F: FnOnce(&K) -> Result<V, E>,
769    {
770        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
771            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
772
773            self.detach(node_ptr);
774            self.attach(node_ptr);
775
776            unsafe { Ok(&*(*node_ptr).val.as_ptr()) }
777        } else {
778            let v = f(&k)?;
779            let (_, node) = self.replace_or_create_node(k, v);
780            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
781
782            self.attach(node_ptr);
783
784            let keyref = unsafe { (*node_ptr).key.as_ptr() };
785            self.map.insert(KeyRef { k: keyref }, node);
786            Ok(unsafe { &*(*node_ptr).val.as_ptr() })
787        }
788    }
789
790    /// Returns a reference to the value of the key in the cache if it is
791    /// present in the cache and moves the key to the head of the LRU list.
792    /// If the key does not exist the provided `FnOnce` is used to populate
793    /// the list and a reference is returned. If `FnOnce` returns `Err`,
794    /// returns the `Err`. The value referenced by the key is only cloned
795    /// (using `to_owned()`) if it doesn't exist in the cache and `FnOnce`
796    /// succeeds.
797    ///
798    /// # Example
799    ///
800    /// ```
801    /// use lru::LruCache;
802    /// use std::num::NonZeroUsize;
803    /// use std::rc::Rc;
804    ///
805    /// let key1 = Rc::new("1".to_owned());
806    /// let key2 = Rc::new("2".to_owned());
807    /// let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
808    /// let f = ||->Result<String, ()> {Err(())};
809    /// let a = ||->Result<String, ()> {Ok("One".to_owned())};
810    /// let b = ||->Result<String, ()> {Ok("Two".to_owned())};
811    /// assert_eq!(cache.try_get_or_insert_ref(&key1, a), Ok(&"One".to_owned()));
812    /// assert_eq!(cache.try_get_or_insert_ref(&key2, f), Err(()));
813    /// assert_eq!(cache.try_get_or_insert_ref(&key2, b), Ok(&"Two".to_owned()));
814    /// assert_eq!(cache.try_get_or_insert_ref(&key2, a), Ok(&"Two".to_owned()));
815    /// assert_eq!(Rc::strong_count(&key1), 2);
816    /// assert_eq!(Rc::strong_count(&key2), 2); // key2 was only cloned once even though we
817    ///                                         // queried it 3 times
818    /// ```
819    pub fn try_get_or_insert_ref<'a, Q, F, E>(&'a mut self, k: &'_ Q, f: F) -> Result<&'a V, E>
820    where
821        K: Borrow<Q>,
822        Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
823        F: FnOnce() -> Result<V, E>,
824    {
825        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
826            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
827
828            self.detach(node_ptr);
829            self.attach(node_ptr);
830
831            unsafe { Ok(&*(*node_ptr).val.as_ptr()) }
832        } else {
833            let v = f()?;
834            let (_, node) = self.replace_or_create_node(k.to_owned(), v);
835            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
836
837            self.attach(node_ptr);
838
839            let keyref = unsafe { (*node_ptr).key.as_ptr() };
840            self.map.insert(KeyRef { k: keyref }, node);
841            Ok(unsafe { &*(*node_ptr).val.as_ptr() })
842        }
843    }
844
845    /// Returns a mutable reference to the value of the key in the cache if it is
846    /// present in the cache and moves the key to the head of the LRU list.
847    /// If the key does not exist the provided `FnOnce` is used to populate
848    /// the list and a mutable reference is returned.
849    ///
850    /// # Example
851    ///
852    /// ```
853    /// use lru::LruCache;
854    /// use std::num::NonZeroUsize;
855    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
856    ///
857    /// cache.put(1, "a");
858    /// cache.put(2, "b");
859    ///
860    /// let v = cache.get_or_insert_mut(2, ||"c");
861    /// assert_eq!(v, &"b");
862    /// *v = "d";
863    /// assert_eq!(cache.get_or_insert_mut(2, ||"e"), &mut "d");
864    /// assert_eq!(cache.get_or_insert_mut(3, ||"f"), &mut "f");
865    /// assert_eq!(cache.get_or_insert_mut(3, ||"e"), &mut "f");
866    /// ```
867    pub fn get_or_insert_mut<F>(&mut self, k: K, f: F) -> &mut V
868    where
869        F: FnOnce() -> V,
870    {
871        self.get_or_insert_mut_with_key(k, |_| f())
872    }
873
874    /// Returns a mutable reference to the value of the key in the cache if it is
875    /// present in the cache and moves the key to the head of the LRU list.
876    /// If the key does not exist the provided `FnOnce` is used by passing
877    /// a reference to the key to populate the list and a mutable reference
878    /// is returned.
879    ///
880    /// # Example
881    ///
882    /// ```
883    /// use lru::LruCache;
884    /// use std::num::NonZeroUsize;
885    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
886    ///
887    /// cache.put("One", 1);
888    /// cache.put("Two", 2);
889    /// cache.put("Two", 3);
890    /// cache.put("Three", 4);
891    ///
892    /// assert_eq!(cache.get_or_insert_mut_with_key("Two", |_|1), &mut 3);
893    /// assert_eq!(cache.get_or_insert_mut_with_key("Three", |k|k.len()), &mut 4);
894    /// assert_eq!(cache.get_or_insert_mut_with_key("One", |_|1), &mut 1);
895    /// assert_eq!(cache.get_or_insert_mut_with_key("One", |k|k.len()), &mut 1);
896    /// ```
897    pub fn get_or_insert_mut_with_key<F>(&mut self, k: K, f: F) -> &mut V
898    where
899        F: FnOnce(&K) -> V,
900    {
901        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
902            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
903
904            self.detach(node_ptr);
905            self.attach(node_ptr);
906
907            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
908        } else {
909            let v = f(&k);
910            let (_, node) = self.replace_or_create_node(k, v);
911            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
912
913            self.attach(node_ptr);
914
915            let keyref = unsafe { (*node_ptr).key.as_ptr() };
916            self.map.insert(KeyRef { k: keyref }, node);
917            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
918        }
919    }
920
921    /// Returns a mutable reference to the value of the key in the cache if it is
922    /// present in the cache and moves the key to the head of the LRU list.
923    /// If the key does not exist the provided `FnOnce` is used to populate
924    /// the list and a mutable reference is returned. The value referenced by the
925    /// key is only cloned (using `to_owned()`) if it doesn't exist in the cache.
926    ///
927    /// # Example
928    ///
929    /// ```
930    /// use lru::LruCache;
931    /// use std::num::NonZeroUsize;
932    /// use std::rc::Rc;
933    ///
934    /// let key1 = Rc::new("1".to_owned());
935    /// let key2 = Rc::new("2".to_owned());
936    /// let mut cache = LruCache::<Rc<String>, &'static str>::new(NonZeroUsize::new(2).unwrap());
937    /// cache.get_or_insert_mut_ref(&key1, ||"One");
938    /// let v = cache.get_or_insert_mut_ref(&key2, ||"Two");
939    /// *v = "New two";
940    /// assert_eq!(cache.get_or_insert_mut_ref(&key2, ||"Two"), &mut "New two");
941    /// assert_eq!(Rc::strong_count(&key1), 2);
942    /// assert_eq!(Rc::strong_count(&key2), 2); // key2 was only cloned once even though we
943    ///                                         // queried it 2 times
944    /// ```
945    pub fn get_or_insert_mut_ref<'a, Q, F>(&mut self, k: &'_ Q, f: F) -> &'a mut V
946    where
947        K: Borrow<Q>,
948        Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
949        F: FnOnce() -> V,
950    {
951        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
952            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
953
954            self.detach(node_ptr);
955            self.attach(node_ptr);
956
957            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
958        } else {
959            let v = f();
960            let (_, node) = self.replace_or_create_node(k.to_owned(), v);
961            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
962
963            self.attach(node_ptr);
964
965            let keyref = unsafe { (*node_ptr).key.as_ptr() };
966            self.map.insert(KeyRef { k: keyref }, node);
967            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
968        }
969    }
970
971    /// Returns a mutable reference to the value of the key in the cache if it is
972    /// present in the cache and moves the key to the head of the LRU list.
973    /// If the key does not exist the provided `FnOnce` is used to populate
974    /// the list and a mutable reference is returned. If `FnOnce` returns `Err`,
975    /// returns the `Err`.
976    ///
977    /// # Example
978    ///
979    /// ```
980    /// use lru::LruCache;
981    /// use std::num::NonZeroUsize;
982    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
983    ///
984    /// cache.put(1, "a");
985    /// cache.put(2, "b");
986    /// cache.put(2, "c");
987    ///
988    /// let f = ||->Result<&str, String> {Err("failed".to_owned())};
989    /// let a = ||->Result<&str, String> {Ok("a")};
990    /// let b = ||->Result<&str, String> {Ok("b")};
991    /// if let Ok(v) = cache.try_get_or_insert_mut(2, a) {
992    ///     *v = "d";
993    /// }
994    /// assert_eq!(cache.try_get_or_insert_mut(2, a), Ok(&mut "d"));
995    /// assert_eq!(cache.try_get_or_insert_mut(3, f), Err("failed".to_owned()));
996    /// assert_eq!(cache.try_get_or_insert_mut(4, b), Ok(&mut "b"));
997    /// assert_eq!(cache.try_get_or_insert_mut(4, a), Ok(&mut "b"));
998    /// ```
999    pub fn try_get_or_insert_mut<F, E>(&mut self, k: K, f: F) -> Result<&mut V, E>
1000    where
1001        F: FnOnce() -> Result<V, E>,
1002    {
1003        self.try_get_or_insert_mut_with_key(k, |_| f())
1004    }
1005
1006    /// Returns a mutable reference to the value of the key in the cache if it is
1007    /// present in the cache and moves the key to the head of the LRU list.
1008    /// If the key does not exist the provided `FnOnce` is used by passing
1009    /// a reference to the key to populate the list and a mutable reference
1010    /// is returned. If `FnOnce` returns `Err`, returns the `Err`.
1011    ///
1012    /// # Example
1013    ///
1014    /// ```
1015    /// use lru::LruCache;
1016    /// use std::num::NonZeroUsize;
1017    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1018    ///
1019    /// cache.put("One", 1);
1020    /// cache.put("Two", 2);
1021    /// cache.put("Two", 3);
1022    /// cache.put("Three", 4);
1023    ///
1024    /// let f = |_: &&str|->Result<usize, String> {Err("failed".to_owned())};
1025    /// let len = |k: &&str|->Result<usize, String> {Ok(k.len())};
1026    /// let zero = |_: &&str|->Result<usize, String> {Ok(0)};
1027    /// assert_eq!(cache.try_get_or_insert_mut_with_key("Two", len), Ok(&mut 3));
1028    /// assert_eq!(cache.try_get_or_insert_mut_with_key("Three", len), Ok(&mut 4));
1029    /// assert_eq!(cache.try_get_or_insert_mut_with_key("Four", f), Err("failed".to_owned()));
1030    /// assert_eq!(cache.try_get_or_insert_mut_with_key("Five", len), Ok(&mut 4));
1031    /// assert_eq!(cache.try_get_or_insert_mut_with_key("Five", zero), Ok(&mut 4));
1032    /// ```
1033    pub fn try_get_or_insert_mut_with_key<F, E>(&mut self, k: K, f: F) -> Result<&mut V, E>
1034    where
1035        F: FnOnce(&K) -> Result<V, E>,
1036    {
1037        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
1038            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1039
1040            self.detach(node_ptr);
1041            self.attach(node_ptr);
1042
1043            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
1044        } else {
1045            let v = f(&k)?;
1046            let (_, node) = self.replace_or_create_node(k, v);
1047            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1048
1049            self.attach(node_ptr);
1050
1051            let keyref = unsafe { (*node_ptr).key.as_ptr() };
1052            self.map.insert(KeyRef { k: keyref }, node);
1053            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
1054        }
1055    }
1056
1057    /// Returns a mutable reference to the value of the key in the cache if it is
1058    /// present in the cache and moves the key to the head of the LRU list.
1059    /// If the key does not exist the provided `FnOnce` is used to populate
1060    /// the list and a mutable reference is returned. If `FnOnce` returns `Err`,
1061    /// returns the `Err`. The value referenced by the key is only cloned
1062    /// (using `to_owned()`) if it doesn't exist in the cache and `FnOnce`
1063    /// succeeds.
1064    ///
1065    /// # Example
1066    ///
1067    /// ```
1068    /// use lru::LruCache;
1069    /// use std::num::NonZeroUsize;
1070    /// use std::rc::Rc;
1071    ///
1072    /// let key1 = Rc::new("1".to_owned());
1073    /// let key2 = Rc::new("2".to_owned());
1074    /// let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
1075    /// let f = ||->Result<String, ()> {Err(())};
1076    /// let a = ||->Result<String, ()> {Ok("One".to_owned())};
1077    /// let b = ||->Result<String, ()> {Ok("Two".to_owned())};
1078    /// assert_eq!(cache.try_get_or_insert_mut_ref(&key1, a), Ok(&mut "One".to_owned()));
1079    /// assert_eq!(cache.try_get_or_insert_mut_ref(&key2, f), Err(()));
1080    /// if let Ok(v) = cache.try_get_or_insert_mut_ref(&key2, b) {
1081    ///     *v = "New two".to_owned();
1082    /// }
1083    /// assert_eq!(cache.try_get_or_insert_mut_ref(&key2, a), Ok(&mut "New two".to_owned()));
1084    /// assert_eq!(Rc::strong_count(&key1), 2);
1085    /// assert_eq!(Rc::strong_count(&key2), 2); // key2 was only cloned once even though we
1086    ///                                         // queried it 3 times
1087    /// ```
1088    pub fn try_get_or_insert_mut_ref<'a, Q, F, E>(
1089        &'a mut self,
1090        k: &'_ Q,
1091        f: F,
1092    ) -> Result<&'a mut V, E>
1093    where
1094        K: Borrow<Q>,
1095        Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
1096        F: FnOnce() -> Result<V, E>,
1097    {
1098        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
1099            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1100
1101            self.detach(node_ptr);
1102            self.attach(node_ptr);
1103
1104            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
1105        } else {
1106            let v = f()?;
1107            let (_, node) = self.replace_or_create_node(k.to_owned(), v);
1108            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1109
1110            self.attach(node_ptr);
1111
1112            let keyref = unsafe { (*node_ptr).key.as_ptr() };
1113            self.map.insert(KeyRef { k: keyref }, node);
1114            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
1115        }
1116    }
1117
1118    /// Returns a reference to the value corresponding to the key in the cache or `None` if it is
1119    /// not present in the cache. Unlike `get`, `peek` does not update the LRU list so the key's
1120    /// position will be unchanged.
1121    ///
1122    /// # Example
1123    ///
1124    /// ```
1125    /// use lru::LruCache;
1126    /// use std::num::NonZeroUsize;
1127    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1128    ///
1129    /// cache.put(1, "a");
1130    /// cache.put(2, "b");
1131    ///
1132    /// assert_eq!(cache.peek(&1), Some(&"a"));
1133    /// assert_eq!(cache.peek(&2), Some(&"b"));
1134    /// ```
1135    pub fn peek<'a, Q>(&'a self, k: &Q) -> Option<&'a V>
1136    where
1137        K: Borrow<Q>,
1138        Q: Hash + Eq + ?Sized,
1139    {
1140        self.map
1141            .get(KeyWrapper::from_ref(k))
1142            .map(|node| unsafe { &*node.as_ref().val.as_ptr() })
1143    }
1144
1145    /// Returns a mutable reference to the value corresponding to the key in the cache or `None`
1146    /// if it is not present in the cache. Unlike `get_mut`, `peek_mut` does not update the LRU
1147    /// list so the key's position will be unchanged.
1148    ///
1149    /// # Example
1150    ///
1151    /// ```
1152    /// use lru::LruCache;
1153    /// use std::num::NonZeroUsize;
1154    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1155    ///
1156    /// cache.put(1, "a");
1157    /// cache.put(2, "b");
1158    ///
1159    /// assert_eq!(cache.peek_mut(&1), Some(&mut "a"));
1160    /// assert_eq!(cache.peek_mut(&2), Some(&mut "b"));
1161    /// ```
1162    pub fn peek_mut<'a, Q>(&'a mut self, k: &Q) -> Option<&'a mut V>
1163    where
1164        K: Borrow<Q>,
1165        Q: Hash + Eq + ?Sized,
1166    {
1167        match self.map.get_mut(KeyWrapper::from_ref(k)) {
1168            None => None,
1169            Some(node) => Some(unsafe { &mut *(*node.as_ptr()).val.as_mut_ptr() }),
1170        }
1171    }
1172
1173    /// Returns the value corresponding to the least recently used item or `None` if the
1174    /// cache is empty. Like `peek`, `peek_lru` does not update the LRU list so the item's
1175    /// position will be unchanged.
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, "b");
1186    ///
1187    /// assert_eq!(cache.peek_lru(), Some((&1, &"a")));
1188    /// ```
1189    pub fn peek_lru(&self) -> Option<(&K, &V)> {
1190        if self.is_empty() {
1191            return None;
1192        }
1193
1194        let (key, val);
1195        unsafe {
1196            let node = (*self.tail).prev;
1197            key = &(*(*node).key.as_ptr()) as &K;
1198            val = &(*(*node).val.as_ptr()) as &V;
1199        }
1200
1201        Some((key, val))
1202    }
1203
1204    /// Returns the value corresponding to the most recently used item or `None` if the
1205    /// cache is empty. Like `peek`, `peek_mru` does not update the LRU list so the item's
1206    /// position will be unchanged.
1207    ///
1208    /// # Example
1209    ///
1210    /// ```
1211    /// use lru::LruCache;
1212    /// use std::num::NonZeroUsize;
1213    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1214    ///
1215    /// cache.put(1, "a");
1216    /// cache.put(2, "b");
1217    ///
1218    /// assert_eq!(cache.peek_mru(), Some((&2, &"b")));
1219    /// ```
1220    pub fn peek_mru(&self) -> Option<(&K, &V)> {
1221        if self.is_empty() {
1222            return None;
1223        }
1224
1225        let (key, val);
1226        unsafe {
1227            let node: *mut LruEntry<K, V> = (*self.head).next;
1228            key = &(*(*node).key.as_ptr()) as &K;
1229            val = &(*(*node).val.as_ptr()) as &V;
1230        }
1231
1232        Some((key, val))
1233    }
1234
1235    /// Returns a bool indicating whether the given key is in the cache. Does not update the
1236    /// LRU list.
1237    ///
1238    /// # Example
1239    ///
1240    /// ```
1241    /// use lru::LruCache;
1242    /// use std::num::NonZeroUsize;
1243    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1244    ///
1245    /// cache.put(1, "a");
1246    /// cache.put(2, "b");
1247    /// cache.put(3, "c");
1248    ///
1249    /// assert!(!cache.contains(&1));
1250    /// assert!(cache.contains(&2));
1251    /// assert!(cache.contains(&3));
1252    /// ```
1253    pub fn contains<Q>(&self, k: &Q) -> bool
1254    where
1255        K: Borrow<Q>,
1256        Q: Hash + Eq + ?Sized,
1257    {
1258        self.map.contains_key(KeyWrapper::from_ref(k))
1259    }
1260
1261    /// Removes and returns the value corresponding to the key from the cache or
1262    /// `None` if it does not exist.
1263    ///
1264    /// # Example
1265    ///
1266    /// ```
1267    /// use lru::LruCache;
1268    /// use std::num::NonZeroUsize;
1269    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1270    ///
1271    /// cache.put(2, "a");
1272    ///
1273    /// assert_eq!(cache.pop(&1), None);
1274    /// assert_eq!(cache.pop(&2), Some("a"));
1275    /// assert_eq!(cache.pop(&2), None);
1276    /// assert_eq!(cache.len(), 0);
1277    /// ```
1278    pub fn pop<Q>(&mut self, k: &Q) -> Option<V>
1279    where
1280        K: Borrow<Q>,
1281        Q: Hash + Eq + ?Sized,
1282    {
1283        match self.map.remove(KeyWrapper::from_ref(k)) {
1284            None => None,
1285            Some(old_node) => {
1286                let mut old_node = unsafe {
1287                    let mut old_node = *Box::from_raw(old_node.as_ptr());
1288                    ptr::drop_in_place(old_node.key.as_mut_ptr());
1289
1290                    old_node
1291                };
1292
1293                self.detach(&mut old_node);
1294
1295                let LruEntry { key: _, val, .. } = old_node;
1296                unsafe { Some(val.assume_init()) }
1297            }
1298        }
1299    }
1300
1301    /// Removes and returns the key and the value corresponding to the key from the cache or
1302    /// `None` if it does not exist.
1303    ///
1304    /// # Example
1305    ///
1306    /// ```
1307    /// use lru::LruCache;
1308    /// use std::num::NonZeroUsize;
1309    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1310    ///
1311    /// cache.put(1, "a");
1312    /// cache.put(2, "a");
1313    ///
1314    /// assert_eq!(cache.pop(&1), Some("a"));
1315    /// assert_eq!(cache.pop_entry(&2), Some((2, "a")));
1316    /// assert_eq!(cache.pop(&1), None);
1317    /// assert_eq!(cache.pop_entry(&2), None);
1318    /// assert_eq!(cache.len(), 0);
1319    /// ```
1320    pub fn pop_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
1321    where
1322        K: Borrow<Q>,
1323        Q: Hash + Eq + ?Sized,
1324    {
1325        match self.map.remove(KeyWrapper::from_ref(k)) {
1326            None => None,
1327            Some(old_node) => {
1328                let mut old_node = unsafe { *Box::from_raw(old_node.as_ptr()) };
1329
1330                self.detach(&mut old_node);
1331
1332                let LruEntry { key, val, .. } = old_node;
1333                unsafe { Some((key.assume_init(), val.assume_init())) }
1334            }
1335        }
1336    }
1337
1338    /// Removes and returns the key and value corresponding to the least recently
1339    /// used item or `None` if the cache is empty.
1340    ///
1341    /// # Example
1342    ///
1343    /// ```
1344    /// use lru::LruCache;
1345    /// use std::num::NonZeroUsize;
1346    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1347    ///
1348    /// cache.put(2, "a");
1349    /// cache.put(3, "b");
1350    /// cache.put(4, "c");
1351    /// cache.get(&3);
1352    ///
1353    /// assert_eq!(cache.pop_lru(), Some((4, "c")));
1354    /// assert_eq!(cache.pop_lru(), Some((3, "b")));
1355    /// assert_eq!(cache.pop_lru(), None);
1356    /// assert_eq!(cache.len(), 0);
1357    /// ```
1358    pub fn pop_lru(&mut self) -> Option<(K, V)> {
1359        let node = self.remove_last()?;
1360        // N.B.: Can't destructure directly because of https://github.com/rust-lang/rust/issues/28536
1361        let node = *node;
1362        let LruEntry { key, val, .. } = node;
1363        unsafe { Some((key.assume_init(), val.assume_init())) }
1364    }
1365
1366    /// Removes and returns the key and value corresponding to the most recently
1367    /// used item or `None` if the cache is empty.
1368    ///
1369    /// # Example
1370    ///
1371    /// ```
1372    /// use lru::LruCache;
1373    /// use std::num::NonZeroUsize;
1374    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1375    ///
1376    /// cache.put(2, "a");
1377    /// cache.put(3, "b");
1378    /// cache.put(4, "c");
1379    /// cache.get(&3);
1380    ///
1381    /// assert_eq!(cache.pop_mru(), Some((3, "b")));
1382    /// assert_eq!(cache.pop_mru(), Some((4, "c")));
1383    /// assert_eq!(cache.pop_mru(), None);
1384    /// assert_eq!(cache.len(), 0);
1385    /// ```
1386    pub fn pop_mru(&mut self) -> Option<(K, V)> {
1387        let node = self.remove_first()?;
1388        // N.B.: Can't destructure directly because of https://github.com/rust-lang/rust/issues/28536
1389        let node = *node;
1390        let LruEntry { key, val, .. } = node;
1391        unsafe { Some((key.assume_init(), val.assume_init())) }
1392    }
1393
1394    /// Marks the key as the most recently used one. Returns true if the key
1395    /// was promoted because it exists in the cache, false otherwise.
1396    ///
1397    /// # Example
1398    ///
1399    /// ```
1400    /// use lru::LruCache;
1401    /// use std::num::NonZeroUsize;
1402    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1403    ///
1404    /// cache.put(1, "a");
1405    /// cache.put(2, "b");
1406    /// cache.put(3, "c");
1407    /// cache.get(&1);
1408    /// cache.get(&2);
1409    ///
1410    /// // If we do `pop_lru` now, we would pop 3.
1411    /// // assert_eq!(cache.pop_lru(), Some((3, "c")));
1412    ///
1413    /// // By promoting 3, we make sure it isn't popped.
1414    /// assert!(cache.promote(&3));
1415    /// assert_eq!(cache.pop_lru(), Some((1, "a")));
1416    ///
1417    /// // Promoting an entry that doesn't exist doesn't do anything.
1418    /// assert!(!cache.promote(&4));
1419    /// ```
1420    pub fn promote<Q>(&mut self, k: &Q) -> bool
1421    where
1422        K: Borrow<Q>,
1423        Q: Hash + Eq + ?Sized,
1424    {
1425        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
1426            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1427            self.detach(node_ptr);
1428            self.attach(node_ptr);
1429            true
1430        } else {
1431            false
1432        }
1433    }
1434
1435    /// Marks the key as the least recently used one. Returns true if the key was demoted
1436    /// because it exists in the cache, false otherwise.
1437    ///
1438    /// # Example
1439    ///
1440    /// ```
1441    /// use lru::LruCache;
1442    /// use std::num::NonZeroUsize;
1443    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1444    ///
1445    /// cache.put(1, "a");
1446    /// cache.put(2, "b");
1447    /// cache.put(3, "c");
1448    /// cache.get(&1);
1449    /// cache.get(&2);
1450    ///
1451    /// // If we do `pop_lru` now, we would pop 3.
1452    /// // assert_eq!(cache.pop_lru(), Some((3, "c")));
1453    ///
1454    /// // By demoting 1 and 2, we make sure those are popped first.
1455    /// assert!(cache.demote(&2));
1456    /// assert!(cache.demote(&1));
1457    /// assert_eq!(cache.pop_lru(), Some((1, "a")));
1458    /// assert_eq!(cache.pop_lru(), Some((2, "b")));
1459    ///
1460    /// // Demoting a key that doesn't exist does nothing.
1461    /// assert!(!cache.demote(&4));
1462    /// ```
1463    pub fn demote<Q>(&mut self, k: &Q) -> bool
1464    where
1465        K: Borrow<Q>,
1466        Q: Hash + Eq + ?Sized,
1467    {
1468        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
1469            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1470            self.detach(node_ptr);
1471            self.attach_last(node_ptr);
1472            true
1473        } else {
1474            false
1475        }
1476    }
1477
1478    /// Returns the number of key-value pairs that are currently in the the cache.
1479    ///
1480    /// # Example
1481    ///
1482    /// ```
1483    /// use lru::LruCache;
1484    /// use std::num::NonZeroUsize;
1485    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1486    /// assert_eq!(cache.len(), 0);
1487    ///
1488    /// cache.put(1, "a");
1489    /// assert_eq!(cache.len(), 1);
1490    ///
1491    /// cache.put(2, "b");
1492    /// assert_eq!(cache.len(), 2);
1493    ///
1494    /// cache.put(3, "c");
1495    /// assert_eq!(cache.len(), 2);
1496    /// ```
1497    pub fn len(&self) -> usize {
1498        self.map.len()
1499    }
1500
1501    /// Returns a bool indicating whether the cache is empty or not.
1502    ///
1503    /// # Example
1504    ///
1505    /// ```
1506    /// use lru::LruCache;
1507    /// use std::num::NonZeroUsize;
1508    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1509    /// assert!(cache.is_empty());
1510    ///
1511    /// cache.put(1, "a");
1512    /// assert!(!cache.is_empty());
1513    /// ```
1514    pub fn is_empty(&self) -> bool {
1515        self.map.len() == 0
1516    }
1517
1518    /// Returns the maximum number of key-value pairs the cache can hold.
1519    ///
1520    /// # Example
1521    ///
1522    /// ```
1523    /// use lru::LruCache;
1524    /// use std::num::NonZeroUsize;
1525    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
1526    /// assert_eq!(cache.cap().get(), 2);
1527    /// ```
1528    pub fn cap(&self) -> NonZeroUsize {
1529        self.cap
1530    }
1531
1532    /// Resizes the cache. If the new capacity is smaller than the size of the current
1533    /// cache any entries past the new capacity are discarded.
1534    ///
1535    /// # Example
1536    ///
1537    /// ```
1538    /// use lru::LruCache;
1539    /// use std::num::NonZeroUsize;
1540    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
1541    ///
1542    /// cache.put(1, "a");
1543    /// cache.put(2, "b");
1544    /// cache.resize(NonZeroUsize::new(4).unwrap());
1545    /// cache.put(3, "c");
1546    /// cache.put(4, "d");
1547    ///
1548    /// assert_eq!(cache.len(), 4);
1549    /// assert_eq!(cache.get(&1), Some(&"a"));
1550    /// assert_eq!(cache.get(&2), Some(&"b"));
1551    /// assert_eq!(cache.get(&3), Some(&"c"));
1552    /// assert_eq!(cache.get(&4), Some(&"d"));
1553    /// ```
1554    pub fn resize(&mut self, cap: NonZeroUsize) {
1555        // return early if capacity doesn't change
1556        if cap == self.cap {
1557            return;
1558        }
1559
1560        while self.map.len() > cap.get() {
1561            self.pop_lru();
1562        }
1563        self.map.shrink_to_fit();
1564
1565        self.cap = cap;
1566    }
1567
1568    /// Clears the contents of the cache.
1569    ///
1570    /// # Example
1571    ///
1572    /// ```
1573    /// use lru::LruCache;
1574    /// use std::num::NonZeroUsize;
1575    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
1576    /// assert_eq!(cache.len(), 0);
1577    ///
1578    /// cache.put(1, "a");
1579    /// assert_eq!(cache.len(), 1);
1580    ///
1581    /// cache.put(2, "b");
1582    /// assert_eq!(cache.len(), 2);
1583    ///
1584    /// cache.clear();
1585    /// assert_eq!(cache.len(), 0);
1586    /// ```
1587    pub fn clear(&mut self) {
1588        while self.pop_lru().is_some() {}
1589    }
1590
1591    /// An iterator visiting all entries in most-recently used order. The iterator element type is
1592    /// `(&K, &V)`.
1593    ///
1594    /// # Examples
1595    ///
1596    /// ```
1597    /// use lru::LruCache;
1598    /// use std::num::NonZeroUsize;
1599    ///
1600    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1601    /// cache.put("a", 1);
1602    /// cache.put("b", 2);
1603    /// cache.put("c", 3);
1604    ///
1605    /// for (key, val) in cache.iter() {
1606    ///     println!("key: {} val: {}", key, val);
1607    /// }
1608    /// ```
1609    pub fn iter(&self) -> Iter<'_, K, V> {
1610        Iter {
1611            len: self.len(),
1612            ptr: unsafe { (*self.head).next },
1613            end: unsafe { (*self.tail).prev },
1614            phantom: PhantomData,
1615        }
1616    }
1617
1618    /// An iterator visiting all entries in most-recently-used order, giving a mutable reference on
1619    /// V.  The iterator element type is `(&K, &mut V)`.
1620    ///
1621    /// # Examples
1622    ///
1623    /// ```
1624    /// use lru::LruCache;
1625    /// use std::num::NonZeroUsize;
1626    ///
1627    /// struct HddBlock {
1628    ///     dirty: bool,
1629    ///     data: [u8; 512]
1630    /// }
1631    ///
1632    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1633    /// cache.put(0, HddBlock { dirty: false, data: [0x00; 512]});
1634    /// cache.put(1, HddBlock { dirty: true,  data: [0x55; 512]});
1635    /// cache.put(2, HddBlock { dirty: true,  data: [0x77; 512]});
1636    ///
1637    /// // write dirty blocks to disk.
1638    /// for (block_id, block) in cache.iter_mut() {
1639    ///     if block.dirty {
1640    ///         // write block to disk
1641    ///         block.dirty = false
1642    ///     }
1643    /// }
1644    /// ```
1645    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
1646        IterMut {
1647            len: self.len(),
1648            ptr: unsafe { (*self.head).next },
1649            end: unsafe { (*self.tail).prev },
1650            phantom: PhantomData,
1651        }
1652    }
1653
1654    fn remove_first(&mut self) -> Option<Box<LruEntry<K, V>>> {
1655        let next;
1656        unsafe { next = (*self.head).next }
1657        if !core::ptr::eq(next, self.tail) {
1658            let old_key = KeyRef {
1659                k: unsafe { &(*(*(*self.head).next).key.as_ptr()) },
1660            };
1661            let old_node = self.map.remove(&old_key).unwrap();
1662            let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
1663            self.detach(node_ptr);
1664            unsafe { Some(Box::from_raw(node_ptr)) }
1665        } else {
1666            None
1667        }
1668    }
1669
1670    fn remove_last(&mut self) -> Option<Box<LruEntry<K, V>>> {
1671        let prev;
1672        unsafe { prev = (*self.tail).prev }
1673        if !core::ptr::eq(prev, self.head) {
1674            let old_key = KeyRef {
1675                k: unsafe { &(*(*(*self.tail).prev).key.as_ptr()) },
1676            };
1677            let old_node = self.map.remove(&old_key).unwrap();
1678            let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
1679            self.detach(node_ptr);
1680            unsafe { Some(Box::from_raw(node_ptr)) }
1681        } else {
1682            None
1683        }
1684    }
1685
1686    fn detach(&mut self, node: *mut LruEntry<K, V>) {
1687        unsafe {
1688            (*(*node).prev).next = (*node).next;
1689            (*(*node).next).prev = (*node).prev;
1690        }
1691    }
1692
1693    // Attaches `node` after the sigil `self.head` node.
1694    fn attach(&mut self, node: *mut LruEntry<K, V>) {
1695        unsafe {
1696            (*node).next = (*self.head).next;
1697            (*node).prev = self.head;
1698            (*self.head).next = node;
1699            (*(*node).next).prev = node;
1700        }
1701    }
1702
1703    // Attaches `node` before the sigil `self.tail` node.
1704    fn attach_last(&mut self, node: *mut LruEntry<K, V>) {
1705        unsafe {
1706            (*node).next = self.tail;
1707            (*node).prev = (*self.tail).prev;
1708            (*self.tail).prev = node;
1709            (*(*node).prev).next = node;
1710        }
1711    }
1712}
1713
1714impl<K, V, S> Drop for LruCache<K, V, S> {
1715    fn drop(&mut self) {
1716        self.map.drain().for_each(|(_, node)| unsafe {
1717            let mut node = *Box::from_raw(node.as_ptr());
1718            ptr::drop_in_place((node).key.as_mut_ptr());
1719            ptr::drop_in_place((node).val.as_mut_ptr());
1720        });
1721        // We rebox the head/tail, and because these are maybe-uninit
1722        // they do not have the absent k/v dropped.
1723
1724        let _head = unsafe { *Box::from_raw(self.head) };
1725        let _tail = unsafe { *Box::from_raw(self.tail) };
1726    }
1727}
1728
1729impl<'a, K: Hash + Eq, V, S: BuildHasher> IntoIterator for &'a LruCache<K, V, S> {
1730    type Item = (&'a K, &'a V);
1731    type IntoIter = Iter<'a, K, V>;
1732
1733    fn into_iter(self) -> Iter<'a, K, V> {
1734        self.iter()
1735    }
1736}
1737
1738impl<'a, K: Hash + Eq, V, S: BuildHasher> IntoIterator for &'a mut LruCache<K, V, S> {
1739    type Item = (&'a K, &'a mut V);
1740    type IntoIter = IterMut<'a, K, V>;
1741
1742    fn into_iter(self) -> IterMut<'a, K, V> {
1743        self.iter_mut()
1744    }
1745}
1746
1747// The compiler does not automatically derive Send and Sync for LruCache because it contains
1748// raw pointers. The raw pointers are safely encapsulated by LruCache though so we can
1749// implement Send and Sync for it below.
1750unsafe impl<K: Send, V: Send, S: Send> Send for LruCache<K, V, S> {}
1751unsafe impl<K: Sync, V: Sync, S: Sync> Sync for LruCache<K, V, S> {}
1752
1753impl<K: Hash + Eq, V, S: BuildHasher> fmt::Debug for LruCache<K, V, S> {
1754    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1755        f.debug_struct("LruCache")
1756            .field("len", &self.len())
1757            .field("cap", &self.cap())
1758            .finish()
1759    }
1760}
1761
1762/// An iterator over the entries of a `LruCache`.
1763///
1764/// This `struct` is created by the [`iter`] method on [`LruCache`][`LruCache`]. See its
1765/// documentation for more.
1766///
1767/// [`iter`]: struct.LruCache.html#method.iter
1768/// [`LruCache`]: struct.LruCache.html
1769pub struct Iter<'a, K: 'a, V: 'a> {
1770    len: usize,
1771
1772    ptr: *const LruEntry<K, V>,
1773    end: *const LruEntry<K, V>,
1774
1775    phantom: PhantomData<&'a K>,
1776}
1777
1778impl<'a, K, V> Iterator for Iter<'a, K, V> {
1779    type Item = (&'a K, &'a V);
1780
1781    fn next(&mut self) -> Option<(&'a K, &'a V)> {
1782        if self.len == 0 {
1783            return None;
1784        }
1785
1786        let key = unsafe { &(*(*self.ptr).key.as_ptr()) as &K };
1787        let val = unsafe { &(*(*self.ptr).val.as_ptr()) as &V };
1788
1789        self.len -= 1;
1790        self.ptr = unsafe { (*self.ptr).next };
1791
1792        Some((key, val))
1793    }
1794
1795    fn size_hint(&self) -> (usize, Option<usize>) {
1796        (self.len, Some(self.len))
1797    }
1798
1799    fn count(self) -> usize {
1800        self.len
1801    }
1802}
1803
1804impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
1805    fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
1806        if self.len == 0 {
1807            return None;
1808        }
1809
1810        let key = unsafe { &(*(*self.end).key.as_ptr()) as &K };
1811        let val = unsafe { &(*(*self.end).val.as_ptr()) as &V };
1812
1813        self.len -= 1;
1814        self.end = unsafe { (*self.end).prev };
1815
1816        Some((key, val))
1817    }
1818}
1819
1820impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {}
1821impl<'a, K, V> FusedIterator for Iter<'a, K, V> {}
1822
1823impl<'a, K, V> Clone for Iter<'a, K, V> {
1824    fn clone(&self) -> Iter<'a, K, V> {
1825        Iter {
1826            len: self.len,
1827            ptr: self.ptr,
1828            end: self.end,
1829            phantom: PhantomData,
1830        }
1831    }
1832}
1833
1834// The compiler does not automatically derive Send and Sync for Iter because it contains
1835// raw pointers.
1836unsafe impl<'a, K: Send, V: Send> Send for Iter<'a, K, V> {}
1837unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
1838
1839/// An iterator over mutables entries of a `LruCache`.
1840///
1841/// This `struct` is created by the [`iter_mut`] method on [`LruCache`][`LruCache`]. See its
1842/// documentation for more.
1843///
1844/// [`iter_mut`]: struct.LruCache.html#method.iter_mut
1845/// [`LruCache`]: struct.LruCache.html
1846pub struct IterMut<'a, K: 'a, V: 'a> {
1847    len: usize,
1848
1849    ptr: *mut LruEntry<K, V>,
1850    end: *mut LruEntry<K, V>,
1851
1852    phantom: PhantomData<&'a K>,
1853}
1854
1855impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1856    type Item = (&'a K, &'a mut V);
1857
1858    fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
1859        if self.len == 0 {
1860            return None;
1861        }
1862
1863        let key = unsafe { &(*(*self.ptr).key.as_ptr()) as &K };
1864        let val = unsafe { &mut (*(*self.ptr).val.as_mut_ptr()) as &mut V };
1865
1866        self.len -= 1;
1867        self.ptr = unsafe { (*self.ptr).next };
1868
1869        Some((key, val))
1870    }
1871
1872    fn size_hint(&self) -> (usize, Option<usize>) {
1873        (self.len, Some(self.len))
1874    }
1875
1876    fn count(self) -> usize {
1877        self.len
1878    }
1879}
1880
1881impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> {
1882    fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
1883        if self.len == 0 {
1884            return None;
1885        }
1886
1887        let key = unsafe { &(*(*self.end).key.as_ptr()) as &K };
1888        let val = unsafe { &mut (*(*self.end).val.as_mut_ptr()) as &mut V };
1889
1890        self.len -= 1;
1891        self.end = unsafe { (*self.end).prev };
1892
1893        Some((key, val))
1894    }
1895}
1896
1897impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {}
1898impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}
1899
1900// The compiler does not automatically derive Send and Sync for Iter because it contains
1901// raw pointers.
1902unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {}
1903unsafe impl<'a, K: Sync, V: Sync> Sync for IterMut<'a, K, V> {}
1904
1905/// An iterator that moves out of a `LruCache`.
1906///
1907/// This `struct` is created by the [`into_iter`] method on [`LruCache`][`LruCache`]. See its
1908/// documentation for more.
1909///
1910/// [`into_iter`]: struct.LruCache.html#method.into_iter
1911/// [`LruCache`]: struct.LruCache.html
1912pub struct IntoIter<K, V>
1913where
1914    K: Hash + Eq,
1915{
1916    cache: LruCache<K, V>,
1917}
1918
1919impl<K, V> Iterator for IntoIter<K, V>
1920where
1921    K: Hash + Eq,
1922{
1923    type Item = (K, V);
1924
1925    fn next(&mut self) -> Option<(K, V)> {
1926        self.cache.pop_lru()
1927    }
1928
1929    fn size_hint(&self) -> (usize, Option<usize>) {
1930        let len = self.cache.len();
1931        (len, Some(len))
1932    }
1933
1934    fn count(self) -> usize {
1935        self.cache.len()
1936    }
1937}
1938
1939impl<K, V> ExactSizeIterator for IntoIter<K, V> where K: Hash + Eq {}
1940impl<K, V> FusedIterator for IntoIter<K, V> where K: Hash + Eq {}
1941
1942impl<K: Hash + Eq, V> IntoIterator for LruCache<K, V> {
1943    type Item = (K, V);
1944    type IntoIter = IntoIter<K, V>;
1945
1946    fn into_iter(self) -> IntoIter<K, V> {
1947        IntoIter { cache: self }
1948    }
1949}
1950
1951#[cfg(test)]
1952mod tests {
1953    use super::LruCache;
1954    use core::{fmt::Debug, num::NonZeroUsize};
1955    use scoped_threadpool::Pool;
1956    use std::rc::Rc;
1957    use std::sync::atomic::{AtomicUsize, Ordering};
1958
1959    fn assert_opt_eq<V: PartialEq + Debug>(opt: Option<&V>, v: V) {
1960        assert!(opt.is_some());
1961        assert_eq!(opt.unwrap(), &v);
1962    }
1963
1964    fn assert_opt_eq_mut<V: PartialEq + Debug>(opt: Option<&mut V>, v: V) {
1965        assert!(opt.is_some());
1966        assert_eq!(opt.unwrap(), &v);
1967    }
1968
1969    fn assert_opt_eq_tuple<K: PartialEq + Debug, V: PartialEq + Debug>(
1970        opt: Option<(&K, &V)>,
1971        kv: (K, V),
1972    ) {
1973        assert!(opt.is_some());
1974        let res = opt.unwrap();
1975        assert_eq!(res.0, &kv.0);
1976        assert_eq!(res.1, &kv.1);
1977    }
1978
1979    fn assert_opt_eq_mut_tuple<K: PartialEq + Debug, V: PartialEq + Debug>(
1980        opt: Option<(&K, &mut V)>,
1981        kv: (K, V),
1982    ) {
1983        assert!(opt.is_some());
1984        let res = opt.unwrap();
1985        assert_eq!(res.0, &kv.0);
1986        assert_eq!(res.1, &kv.1);
1987    }
1988
1989    #[test]
1990    fn test_unbounded() {
1991        let mut cache = LruCache::unbounded();
1992        for i in 0..13370 {
1993            cache.put(i, ());
1994        }
1995        assert_eq!(cache.len(), 13370);
1996    }
1997
1998    #[test]
1999    #[cfg(feature = "hashbrown")]
2000    fn test_with_hasher() {
2001        use core::num::NonZeroUsize;
2002
2003        use hashbrown::DefaultHashBuilder;
2004
2005        let s = DefaultHashBuilder::default();
2006        let mut cache = LruCache::with_hasher(NonZeroUsize::new(16).unwrap(), s);
2007
2008        for i in 0..13370 {
2009            cache.put(i, ());
2010        }
2011        assert_eq!(cache.len(), 16);
2012    }
2013
2014    #[test]
2015    fn test_put_and_get() {
2016        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2017        assert!(cache.is_empty());
2018
2019        assert_eq!(cache.put("apple", "red"), None);
2020        assert_eq!(cache.put("banana", "yellow"), None);
2021
2022        assert_eq!(cache.cap().get(), 2);
2023        assert_eq!(cache.len(), 2);
2024        assert!(!cache.is_empty());
2025        assert_opt_eq(cache.get(&"apple"), "red");
2026        assert_opt_eq(cache.get(&"banana"), "yellow");
2027    }
2028
2029    #[test]
2030    fn test_put_and_get_or_insert() {
2031        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2032        assert!(cache.is_empty());
2033
2034        assert_eq!(cache.put("apple", "red"), None);
2035        assert_eq!(cache.put("banana", "yellow"), None);
2036
2037        assert_eq!(cache.cap().get(), 2);
2038        assert_eq!(cache.len(), 2);
2039        assert!(!cache.is_empty());
2040        assert_eq!(cache.get_or_insert("apple", || "orange"), &"red");
2041        assert_eq!(cache.get_or_insert("banana", || "orange"), &"yellow");
2042        assert_eq!(cache.get_or_insert("lemon", || "orange"), &"orange");
2043        assert_eq!(cache.get_or_insert("lemon", || "red"), &"orange");
2044    }
2045
2046    #[test]
2047    fn test_put_and_get_or_insert_with_key() {
2048        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2049        assert!(cache.is_empty());
2050
2051        assert_eq!(cache.put("apple", 2), None);
2052        assert_eq!(cache.put("banana", 8), None);
2053
2054        assert_eq!(cache.cap().get(), 2);
2055        assert_eq!(cache.len(), 2);
2056        assert!(!cache.is_empty());
2057        assert_eq!(cache.get_or_insert_with_key("apple", |k| k.len()), &2);
2058        assert_eq!(cache.get_or_insert_with_key("banana", |k| k.len()), &8);
2059        assert_eq!(cache.get_or_insert_with_key("lemon", |k| k.len()), &5);
2060        assert_eq!(cache.get_or_insert_with_key("lemon", |k| k.len() + 3), &5);
2061    }
2062
2063    #[test]
2064    fn test_get_or_insert_ref() {
2065        use alloc::borrow::ToOwned;
2066        use alloc::string::String;
2067
2068        let key1 = Rc::new("1".to_owned());
2069        let key2 = Rc::new("2".to_owned());
2070        let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
2071        assert!(cache.is_empty());
2072        assert_eq!(cache.get_or_insert_ref(&key1, || "One".to_owned()), "One");
2073        assert_eq!(cache.get_or_insert_ref(&key2, || "Two".to_owned()), "Two");
2074        assert_eq!(cache.len(), 2);
2075        assert!(!cache.is_empty());
2076        assert_eq!(
2077            cache.get_or_insert_ref(&key2, || "Not two".to_owned()),
2078            "Two"
2079        );
2080        assert_eq!(
2081            cache.get_or_insert_ref(&key2, || "Again not two".to_owned()),
2082            "Two"
2083        );
2084        assert_eq!(Rc::strong_count(&key1), 2);
2085        assert_eq!(Rc::strong_count(&key2), 2);
2086    }
2087
2088    #[test]
2089    fn test_try_get_or_insert() {
2090        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2091
2092        assert_eq!(
2093            cache.try_get_or_insert::<_, &str>("apple", || Ok("red")),
2094            Ok(&"red")
2095        );
2096        assert_eq!(
2097            cache.try_get_or_insert::<_, &str>("apple", || Err("failed")),
2098            Ok(&"red")
2099        );
2100        assert_eq!(
2101            cache.try_get_or_insert::<_, &str>("banana", || Ok("orange")),
2102            Ok(&"orange")
2103        );
2104        assert_eq!(
2105            cache.try_get_or_insert::<_, &str>("lemon", || Err("failed")),
2106            Err("failed")
2107        );
2108        assert_eq!(
2109            cache.try_get_or_insert::<_, &str>("banana", || Err("failed")),
2110            Ok(&"orange")
2111        );
2112    }
2113
2114    #[test]
2115    fn test_try_get_or_insert_with_key() {
2116        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2117
2118        assert_eq!(
2119            cache.try_get_or_insert_with_key::<_, &str>("apple", |k| Ok(k.len())),
2120            Ok(&5)
2121        );
2122        assert_eq!(
2123            cache.try_get_or_insert_with_key::<_, &str>("apple", |_| Err("failed")),
2124            Ok(&5)
2125        );
2126        assert_eq!(
2127            cache.try_get_or_insert_with_key::<_, &str>("banana", |k| Ok(k.len())),
2128            Ok(&6)
2129        );
2130        assert_eq!(
2131            cache.try_get_or_insert_with_key::<_, &str>("lemon", |_| Err("failed")),
2132            Err("failed")
2133        );
2134        assert_eq!(
2135            cache.try_get_or_insert_with_key::<_, &str>("banana", |_| Err("failed")),
2136            Ok(&6)
2137        );
2138    }
2139
2140    #[test]
2141    fn test_try_get_or_insert_ref() {
2142        use alloc::borrow::ToOwned;
2143        use alloc::string::String;
2144
2145        let key1 = Rc::new("1".to_owned());
2146        let key2 = Rc::new("2".to_owned());
2147        let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
2148        let f = || -> Result<String, ()> { Err(()) };
2149        let a = || -> Result<String, ()> { Ok("One".to_owned()) };
2150        let b = || -> Result<String, ()> { Ok("Two".to_owned()) };
2151        assert_eq!(cache.try_get_or_insert_ref(&key1, a), Ok(&"One".to_owned()));
2152        assert_eq!(cache.try_get_or_insert_ref(&key2, f), Err(()));
2153        assert_eq!(cache.try_get_or_insert_ref(&key2, b), Ok(&"Two".to_owned()));
2154        assert_eq!(cache.try_get_or_insert_ref(&key2, a), Ok(&"Two".to_owned()));
2155        assert_eq!(cache.len(), 2);
2156        assert_eq!(Rc::strong_count(&key1), 2);
2157        assert_eq!(Rc::strong_count(&key2), 2);
2158    }
2159
2160    #[test]
2161    fn test_put_and_get_or_insert_mut() {
2162        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2163        assert!(cache.is_empty());
2164
2165        assert_eq!(cache.put("apple", "red"), None);
2166        assert_eq!(cache.put("banana", "yellow"), None);
2167
2168        assert_eq!(cache.cap().get(), 2);
2169        assert_eq!(cache.len(), 2);
2170
2171        let v = cache.get_or_insert_mut("apple", || "orange");
2172        assert_eq!(v, &"red");
2173        *v = "blue";
2174
2175        assert_eq!(cache.get_or_insert_mut("apple", || "orange"), &"blue");
2176        assert_eq!(cache.get_or_insert_mut("banana", || "orange"), &"yellow");
2177        assert_eq!(cache.get_or_insert_mut("lemon", || "orange"), &"orange");
2178        assert_eq!(cache.get_or_insert_mut("lemon", || "red"), &"orange");
2179    }
2180
2181    #[test]
2182    fn test_put_and_get_or_insert_mut_with_key() {
2183        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2184        assert!(cache.is_empty());
2185
2186        assert_eq!(cache.put("apple", 2), None);
2187        assert_eq!(cache.put("banana", 8), None);
2188
2189        assert_eq!(cache.cap().get(), 2);
2190        assert_eq!(cache.len(), 2);
2191
2192        let v = cache.get_or_insert_mut_with_key("apple", |k| k.len());
2193        assert_eq!(v, &2);
2194        *v = 4;
2195
2196        assert_eq!(cache.get_or_insert_mut_with_key("apple", |k| k.len()), &4);
2197        assert_eq!(cache.get_or_insert_mut_with_key("banana", |k| k.len()), &8);
2198        assert_eq!(cache.get_or_insert_mut_with_key("lemon", |k| k.len()), &5);
2199        assert_eq!(cache.get_or_insert_mut_with_key("lemon", |_| 0), &5);
2200    }
2201
2202    #[test]
2203    fn test_get_or_insert_mut_ref() {
2204        use alloc::borrow::ToOwned;
2205        use alloc::string::String;
2206
2207        let key1 = Rc::new("1".to_owned());
2208        let key2 = Rc::new("2".to_owned());
2209        let mut cache = LruCache::<Rc<String>, &'static str>::new(NonZeroUsize::new(2).unwrap());
2210        assert_eq!(cache.get_or_insert_mut_ref(&key1, || "One"), &mut "One");
2211        let v = cache.get_or_insert_mut_ref(&key2, || "Two");
2212        *v = "New two";
2213        assert_eq!(cache.get_or_insert_mut_ref(&key2, || "Two"), &mut "New two");
2214        assert_eq!(Rc::strong_count(&key1), 2);
2215        assert_eq!(Rc::strong_count(&key2), 2);
2216    }
2217
2218    #[test]
2219    fn test_try_get_or_insert_mut() {
2220        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2221
2222        cache.put(1, "a");
2223        cache.put(2, "b");
2224        cache.put(2, "c");
2225
2226        let f = || -> Result<&str, &str> { Err("failed") };
2227        let a = || -> Result<&str, &str> { Ok("a") };
2228        let b = || -> Result<&str, &str> { Ok("b") };
2229        if let Ok(v) = cache.try_get_or_insert_mut(2, a) {
2230            *v = "d";
2231        }
2232        assert_eq!(cache.try_get_or_insert_mut(2, a), Ok(&mut "d"));
2233        assert_eq!(cache.try_get_or_insert_mut(3, f), Err("failed"));
2234        assert_eq!(cache.try_get_or_insert_mut(4, b), Ok(&mut "b"));
2235        assert_eq!(cache.try_get_or_insert_mut(4, a), Ok(&mut "b"));
2236    }
2237
2238    #[test]
2239    fn test_try_get_or_insert_mut_with_key() {
2240        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2241
2242        cache.put("One", 1);
2243        cache.put("Two", 2);
2244        cache.put("Two", 3);
2245
2246        let f = |_: &&str| -> Result<usize, &str> { Err("failed") };
2247        let len = |k: &&str| -> Result<usize, &str> { Ok(k.len()) };
2248        let zero = |_: &&str| -> Result<usize, &str> { Ok(0) };
2249        if let Ok(v) = cache.try_get_or_insert_mut_with_key("Two", f) {
2250            *v = 6;
2251        }
2252        assert_eq!(cache.try_get_or_insert_mut_with_key("Two", len), Ok(&mut 6));
2253        assert_eq!(
2254            cache.try_get_or_insert_mut_with_key("Three", f),
2255            Err("failed")
2256        );
2257        assert_eq!(
2258            cache.try_get_or_insert_mut_with_key("Four", len),
2259            Ok(&mut 4)
2260        );
2261        assert_eq!(
2262            cache.try_get_or_insert_mut_with_key("Four", zero),
2263            Ok(&mut 4)
2264        );
2265    }
2266
2267    #[test]
2268    fn test_try_get_or_insert_mut_ref() {
2269        use alloc::borrow::ToOwned;
2270        use alloc::string::String;
2271
2272        let key1 = Rc::new("1".to_owned());
2273        let key2 = Rc::new("2".to_owned());
2274        let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
2275        let f = || -> Result<String, ()> { Err(()) };
2276        let a = || -> Result<String, ()> { Ok("One".to_owned()) };
2277        let b = || -> Result<String, ()> { Ok("Two".to_owned()) };
2278        assert_eq!(
2279            cache.try_get_or_insert_mut_ref(&key1, a),
2280            Ok(&mut "One".to_owned())
2281        );
2282        assert_eq!(cache.try_get_or_insert_mut_ref(&key2, f), Err(()));
2283        if let Ok(v) = cache.try_get_or_insert_mut_ref(&key2, b) {
2284            assert_eq!(v, &mut "Two");
2285            *v = "New two".to_owned();
2286        }
2287        assert_eq!(
2288            cache.try_get_or_insert_mut_ref(&key2, a),
2289            Ok(&mut "New two".to_owned())
2290        );
2291        assert_eq!(Rc::strong_count(&key1), 2);
2292        assert_eq!(Rc::strong_count(&key2), 2);
2293    }
2294
2295    #[test]
2296    fn test_put_and_get_mut() {
2297        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2298
2299        cache.put("apple", "red");
2300        cache.put("banana", "yellow");
2301
2302        assert_eq!(cache.cap().get(), 2);
2303        assert_eq!(cache.len(), 2);
2304        assert_opt_eq_mut(cache.get_mut(&"apple"), "red");
2305        assert_opt_eq_mut(cache.get_mut(&"banana"), "yellow");
2306    }
2307
2308    #[test]
2309    fn test_get_mut_and_update() {
2310        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2311
2312        cache.put("apple", 1);
2313        cache.put("banana", 3);
2314
2315        {
2316            let v = cache.get_mut(&"apple").unwrap();
2317            *v = 4;
2318        }
2319
2320        assert_eq!(cache.cap().get(), 2);
2321        assert_eq!(cache.len(), 2);
2322        assert_opt_eq_mut(cache.get_mut(&"apple"), 4);
2323        assert_opt_eq_mut(cache.get_mut(&"banana"), 3);
2324    }
2325
2326    #[test]
2327    fn test_put_update() {
2328        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2329
2330        assert_eq!(cache.put("apple", "red"), None);
2331        assert_eq!(cache.put("apple", "green"), Some("red"));
2332
2333        assert_eq!(cache.len(), 1);
2334        assert_opt_eq(cache.get(&"apple"), "green");
2335    }
2336
2337    #[test]
2338    fn test_put_removes_oldest() {
2339        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2340
2341        assert_eq!(cache.put("apple", "red"), None);
2342        assert_eq!(cache.put("banana", "yellow"), None);
2343        assert_eq!(cache.put("pear", "green"), None);
2344
2345        assert!(cache.get(&"apple").is_none());
2346        assert_opt_eq(cache.get(&"banana"), "yellow");
2347        assert_opt_eq(cache.get(&"pear"), "green");
2348
2349        // Even though we inserted "apple" into the cache earlier it has since been removed from
2350        // the cache so there is no current value for `put` to return.
2351        assert_eq!(cache.put("apple", "green"), None);
2352        assert_eq!(cache.put("tomato", "red"), None);
2353
2354        assert!(cache.get(&"pear").is_none());
2355        assert_opt_eq(cache.get(&"apple"), "green");
2356        assert_opt_eq(cache.get(&"tomato"), "red");
2357    }
2358
2359    #[test]
2360    fn test_peek() {
2361        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2362
2363        cache.put("apple", "red");
2364        cache.put("banana", "yellow");
2365
2366        assert_opt_eq(cache.peek(&"banana"), "yellow");
2367        assert_opt_eq(cache.peek(&"apple"), "red");
2368
2369        cache.put("pear", "green");
2370
2371        assert!(cache.peek(&"apple").is_none());
2372        assert_opt_eq(cache.peek(&"banana"), "yellow");
2373        assert_opt_eq(cache.peek(&"pear"), "green");
2374    }
2375
2376    #[test]
2377    fn test_peek_mut() {
2378        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2379
2380        cache.put("apple", "red");
2381        cache.put("banana", "yellow");
2382
2383        assert_opt_eq_mut(cache.peek_mut(&"banana"), "yellow");
2384        assert_opt_eq_mut(cache.peek_mut(&"apple"), "red");
2385        assert!(cache.peek_mut(&"pear").is_none());
2386
2387        cache.put("pear", "green");
2388
2389        assert!(cache.peek_mut(&"apple").is_none());
2390        assert_opt_eq_mut(cache.peek_mut(&"banana"), "yellow");
2391        assert_opt_eq_mut(cache.peek_mut(&"pear"), "green");
2392
2393        {
2394            let v = cache.peek_mut(&"banana").unwrap();
2395            *v = "green";
2396        }
2397
2398        assert_opt_eq_mut(cache.peek_mut(&"banana"), "green");
2399    }
2400
2401    #[test]
2402    fn test_peek_lru() {
2403        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2404
2405        assert!(cache.peek_lru().is_none());
2406
2407        cache.put("apple", "red");
2408        cache.put("banana", "yellow");
2409        assert_opt_eq_tuple(cache.peek_lru(), ("apple", "red"));
2410
2411        cache.get(&"apple");
2412        assert_opt_eq_tuple(cache.peek_lru(), ("banana", "yellow"));
2413
2414        cache.clear();
2415        assert!(cache.peek_lru().is_none());
2416    }
2417
2418    #[test]
2419    fn test_peek_mru() {
2420        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2421
2422        assert!(cache.peek_mru().is_none());
2423
2424        cache.put("apple", "red");
2425        cache.put("banana", "yellow");
2426        assert_opt_eq_tuple(cache.peek_mru(), ("banana", "yellow"));
2427
2428        cache.get(&"apple");
2429        assert_opt_eq_tuple(cache.peek_mru(), ("apple", "red"));
2430
2431        cache.clear();
2432        assert!(cache.peek_mru().is_none());
2433    }
2434
2435    #[test]
2436    fn test_contains() {
2437        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2438
2439        cache.put("apple", "red");
2440        cache.put("banana", "yellow");
2441        cache.put("pear", "green");
2442
2443        assert!(!cache.contains(&"apple"));
2444        assert!(cache.contains(&"banana"));
2445        assert!(cache.contains(&"pear"));
2446    }
2447
2448    #[test]
2449    fn test_pop() {
2450        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2451
2452        cache.put("apple", "red");
2453        cache.put("banana", "yellow");
2454
2455        assert_eq!(cache.len(), 2);
2456        assert_opt_eq(cache.get(&"apple"), "red");
2457        assert_opt_eq(cache.get(&"banana"), "yellow");
2458
2459        let popped = cache.pop(&"apple");
2460        assert!(popped.is_some());
2461        assert_eq!(popped.unwrap(), "red");
2462        assert_eq!(cache.len(), 1);
2463        assert!(cache.get(&"apple").is_none());
2464        assert_opt_eq(cache.get(&"banana"), "yellow");
2465    }
2466
2467    #[test]
2468    fn test_pop_entry() {
2469        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2470        cache.put("apple", "red");
2471        cache.put("banana", "yellow");
2472
2473        assert_eq!(cache.len(), 2);
2474        assert_opt_eq(cache.get(&"apple"), "red");
2475        assert_opt_eq(cache.get(&"banana"), "yellow");
2476
2477        let popped = cache.pop_entry(&"apple");
2478        assert!(popped.is_some());
2479        assert_eq!(popped.unwrap(), ("apple", "red"));
2480        assert_eq!(cache.len(), 1);
2481        assert!(cache.get(&"apple").is_none());
2482        assert_opt_eq(cache.get(&"banana"), "yellow");
2483    }
2484
2485    #[test]
2486    fn test_pop_lru() {
2487        let mut cache = LruCache::new(NonZeroUsize::new(200).unwrap());
2488
2489        for i in 0..75 {
2490            cache.put(i, "A");
2491        }
2492        for i in 0..75 {
2493            cache.put(i + 100, "B");
2494        }
2495        for i in 0..75 {
2496            cache.put(i + 200, "C");
2497        }
2498        assert_eq!(cache.len(), 200);
2499
2500        for i in 0..75 {
2501            assert_opt_eq(cache.get(&(74 - i + 100)), "B");
2502        }
2503        assert_opt_eq(cache.get(&25), "A");
2504
2505        for i in 26..75 {
2506            assert_eq!(cache.pop_lru(), Some((i, "A")));
2507        }
2508        for i in 0..75 {
2509            assert_eq!(cache.pop_lru(), Some((i + 200, "C")));
2510        }
2511        for i in 0..75 {
2512            assert_eq!(cache.pop_lru(), Some((74 - i + 100, "B")));
2513        }
2514        assert_eq!(cache.pop_lru(), Some((25, "A")));
2515        for _ in 0..50 {
2516            assert_eq!(cache.pop_lru(), None);
2517        }
2518    }
2519
2520    #[test]
2521    fn test_pop_mru() {
2522        let mut cache = LruCache::new(NonZeroUsize::new(200).unwrap());
2523
2524        for i in 0..75 {
2525            cache.put(i, "A");
2526        }
2527        for i in 0..75 {
2528            cache.put(i + 100, "B");
2529        }
2530        for i in 0..75 {
2531            cache.put(i + 200, "C");
2532        }
2533        assert_eq!(cache.len(), 200);
2534
2535        for i in 0..75 {
2536            assert_opt_eq(cache.get(&(74 - i + 100)), "B");
2537        }
2538        assert_opt_eq(cache.get(&25), "A");
2539
2540        assert_eq!(cache.pop_mru(), Some((25, "A")));
2541        for i in 0..75 {
2542            assert_eq!(cache.pop_mru(), Some((i + 100, "B")));
2543        }
2544        for i in 0..75 {
2545            assert_eq!(cache.pop_mru(), Some((74 - i + 200, "C")));
2546        }
2547        for i in (26..75).into_iter().rev() {
2548            assert_eq!(cache.pop_mru(), Some((i, "A")));
2549        }
2550        for _ in 0..50 {
2551            assert_eq!(cache.pop_mru(), None);
2552        }
2553    }
2554
2555    #[test]
2556    fn test_clear() {
2557        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2558
2559        cache.put("apple", "red");
2560        cache.put("banana", "yellow");
2561
2562        assert_eq!(cache.len(), 2);
2563        assert_opt_eq(cache.get(&"apple"), "red");
2564        assert_opt_eq(cache.get(&"banana"), "yellow");
2565
2566        cache.clear();
2567        assert_eq!(cache.len(), 0);
2568    }
2569
2570    #[test]
2571    fn test_resize_larger() {
2572        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2573
2574        cache.put(1, "a");
2575        cache.put(2, "b");
2576        cache.resize(NonZeroUsize::new(4).unwrap());
2577        cache.put(3, "c");
2578        cache.put(4, "d");
2579
2580        assert_eq!(cache.len(), 4);
2581        assert_eq!(cache.get(&1), Some(&"a"));
2582        assert_eq!(cache.get(&2), Some(&"b"));
2583        assert_eq!(cache.get(&3), Some(&"c"));
2584        assert_eq!(cache.get(&4), Some(&"d"));
2585    }
2586
2587    #[test]
2588    fn test_resize_smaller() {
2589        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2590
2591        cache.put(1, "a");
2592        cache.put(2, "b");
2593        cache.put(3, "c");
2594        cache.put(4, "d");
2595
2596        cache.resize(NonZeroUsize::new(2).unwrap());
2597
2598        assert_eq!(cache.len(), 2);
2599        assert!(cache.get(&1).is_none());
2600        assert!(cache.get(&2).is_none());
2601        assert_eq!(cache.get(&3), Some(&"c"));
2602        assert_eq!(cache.get(&4), Some(&"d"));
2603    }
2604
2605    #[test]
2606    fn test_send() {
2607        use std::thread;
2608
2609        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2610        cache.put(1, "a");
2611
2612        let handle = thread::spawn(move || {
2613            assert_eq!(cache.get(&1), Some(&"a"));
2614        });
2615
2616        assert!(handle.join().is_ok());
2617    }
2618
2619    #[test]
2620    fn test_multiple_threads() {
2621        let mut pool = Pool::new(1);
2622        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2623        cache.put(1, "a");
2624
2625        let cache_ref = &cache;
2626        pool.scoped(|scoped| {
2627            scoped.execute(move || {
2628                assert_eq!(cache_ref.peek(&1), Some(&"a"));
2629            });
2630        });
2631
2632        assert_eq!((cache_ref).peek(&1), Some(&"a"));
2633    }
2634
2635    #[test]
2636    fn test_iter_forwards() {
2637        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2638        cache.put("a", 1);
2639        cache.put("b", 2);
2640        cache.put("c", 3);
2641
2642        {
2643            // iter const
2644            let mut iter = cache.iter();
2645            assert_eq!(iter.len(), 3);
2646            assert_opt_eq_tuple(iter.next(), ("c", 3));
2647
2648            assert_eq!(iter.len(), 2);
2649            assert_opt_eq_tuple(iter.next(), ("b", 2));
2650
2651            assert_eq!(iter.len(), 1);
2652            assert_opt_eq_tuple(iter.next(), ("a", 1));
2653
2654            assert_eq!(iter.len(), 0);
2655            assert_eq!(iter.next(), None);
2656        }
2657        {
2658            // iter mut
2659            let mut iter = cache.iter_mut();
2660            assert_eq!(iter.len(), 3);
2661            assert_opt_eq_mut_tuple(iter.next(), ("c", 3));
2662
2663            assert_eq!(iter.len(), 2);
2664            assert_opt_eq_mut_tuple(iter.next(), ("b", 2));
2665
2666            assert_eq!(iter.len(), 1);
2667            assert_opt_eq_mut_tuple(iter.next(), ("a", 1));
2668
2669            assert_eq!(iter.len(), 0);
2670            assert_eq!(iter.next(), None);
2671        }
2672    }
2673
2674    #[test]
2675    fn test_iter_backwards() {
2676        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2677        cache.put("a", 1);
2678        cache.put("b", 2);
2679        cache.put("c", 3);
2680
2681        {
2682            // iter const
2683            let mut iter = cache.iter();
2684            assert_eq!(iter.len(), 3);
2685            assert_opt_eq_tuple(iter.next_back(), ("a", 1));
2686
2687            assert_eq!(iter.len(), 2);
2688            assert_opt_eq_tuple(iter.next_back(), ("b", 2));
2689
2690            assert_eq!(iter.len(), 1);
2691            assert_opt_eq_tuple(iter.next_back(), ("c", 3));
2692
2693            assert_eq!(iter.len(), 0);
2694            assert_eq!(iter.next_back(), None);
2695        }
2696
2697        {
2698            // iter mut
2699            let mut iter = cache.iter_mut();
2700            assert_eq!(iter.len(), 3);
2701            assert_opt_eq_mut_tuple(iter.next_back(), ("a", 1));
2702
2703            assert_eq!(iter.len(), 2);
2704            assert_opt_eq_mut_tuple(iter.next_back(), ("b", 2));
2705
2706            assert_eq!(iter.len(), 1);
2707            assert_opt_eq_mut_tuple(iter.next_back(), ("c", 3));
2708
2709            assert_eq!(iter.len(), 0);
2710            assert_eq!(iter.next_back(), None);
2711        }
2712    }
2713
2714    #[test]
2715    fn test_iter_forwards_and_backwards() {
2716        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2717        cache.put("a", 1);
2718        cache.put("b", 2);
2719        cache.put("c", 3);
2720
2721        {
2722            // iter const
2723            let mut iter = cache.iter();
2724            assert_eq!(iter.len(), 3);
2725            assert_opt_eq_tuple(iter.next(), ("c", 3));
2726
2727            assert_eq!(iter.len(), 2);
2728            assert_opt_eq_tuple(iter.next_back(), ("a", 1));
2729
2730            assert_eq!(iter.len(), 1);
2731            assert_opt_eq_tuple(iter.next(), ("b", 2));
2732
2733            assert_eq!(iter.len(), 0);
2734            assert_eq!(iter.next_back(), None);
2735        }
2736        {
2737            // iter mut
2738            let mut iter = cache.iter_mut();
2739            assert_eq!(iter.len(), 3);
2740            assert_opt_eq_mut_tuple(iter.next(), ("c", 3));
2741
2742            assert_eq!(iter.len(), 2);
2743            assert_opt_eq_mut_tuple(iter.next_back(), ("a", 1));
2744
2745            assert_eq!(iter.len(), 1);
2746            assert_opt_eq_mut_tuple(iter.next(), ("b", 2));
2747
2748            assert_eq!(iter.len(), 0);
2749            assert_eq!(iter.next_back(), None);
2750        }
2751    }
2752
2753    #[test]
2754    fn test_iter_multiple_threads() {
2755        let mut pool = Pool::new(1);
2756        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2757        cache.put("a", 1);
2758        cache.put("b", 2);
2759        cache.put("c", 3);
2760
2761        let mut iter = cache.iter();
2762        assert_eq!(iter.len(), 3);
2763        assert_opt_eq_tuple(iter.next(), ("c", 3));
2764
2765        {
2766            let iter_ref = &mut iter;
2767            pool.scoped(|scoped| {
2768                scoped.execute(move || {
2769                    assert_eq!(iter_ref.len(), 2);
2770                    assert_opt_eq_tuple(iter_ref.next(), ("b", 2));
2771                });
2772            });
2773        }
2774
2775        assert_eq!(iter.len(), 1);
2776        assert_opt_eq_tuple(iter.next(), ("a", 1));
2777
2778        assert_eq!(iter.len(), 0);
2779        assert_eq!(iter.next(), None);
2780    }
2781
2782    #[test]
2783    fn test_iter_clone() {
2784        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2785        cache.put("a", 1);
2786        cache.put("b", 2);
2787
2788        let mut iter = cache.iter();
2789        let mut iter_clone = iter.clone();
2790
2791        assert_eq!(iter.len(), 2);
2792        assert_opt_eq_tuple(iter.next(), ("b", 2));
2793        assert_eq!(iter_clone.len(), 2);
2794        assert_opt_eq_tuple(iter_clone.next(), ("b", 2));
2795
2796        assert_eq!(iter.len(), 1);
2797        assert_opt_eq_tuple(iter.next(), ("a", 1));
2798        assert_eq!(iter_clone.len(), 1);
2799        assert_opt_eq_tuple(iter_clone.next(), ("a", 1));
2800
2801        assert_eq!(iter.len(), 0);
2802        assert_eq!(iter.next(), None);
2803        assert_eq!(iter_clone.len(), 0);
2804        assert_eq!(iter_clone.next(), None);
2805    }
2806
2807    #[test]
2808    fn test_into_iter() {
2809        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2810        cache.put("a", 1);
2811        cache.put("b", 2);
2812        cache.put("c", 3);
2813
2814        let mut iter = cache.into_iter();
2815        assert_eq!(iter.len(), 3);
2816        assert_eq!(iter.next(), Some(("a", 1)));
2817
2818        assert_eq!(iter.len(), 2);
2819        assert_eq!(iter.next(), Some(("b", 2)));
2820
2821        assert_eq!(iter.len(), 1);
2822        assert_eq!(iter.next(), Some(("c", 3)));
2823
2824        assert_eq!(iter.len(), 0);
2825        assert_eq!(iter.next(), None);
2826    }
2827
2828    #[test]
2829    fn test_that_pop_actually_detaches_node() {
2830        let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
2831
2832        cache.put("a", 1);
2833        cache.put("b", 2);
2834        cache.put("c", 3);
2835        cache.put("d", 4);
2836        cache.put("e", 5);
2837
2838        assert_eq!(cache.pop(&"c"), Some(3));
2839
2840        cache.put("f", 6);
2841
2842        let mut iter = cache.iter();
2843        assert_opt_eq_tuple(iter.next(), ("f", 6));
2844        assert_opt_eq_tuple(iter.next(), ("e", 5));
2845        assert_opt_eq_tuple(iter.next(), ("d", 4));
2846        assert_opt_eq_tuple(iter.next(), ("b", 2));
2847        assert_opt_eq_tuple(iter.next(), ("a", 1));
2848        assert!(iter.next().is_none());
2849    }
2850
2851    #[test]
2852    fn test_get_with_borrow() {
2853        use alloc::string::String;
2854
2855        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2856
2857        let key = String::from("apple");
2858        cache.put(key, "red");
2859
2860        assert_opt_eq(cache.get("apple"), "red");
2861    }
2862
2863    #[test]
2864    fn test_get_mut_with_borrow() {
2865        use alloc::string::String;
2866
2867        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2868
2869        let key = String::from("apple");
2870        cache.put(key, "red");
2871
2872        assert_opt_eq_mut(cache.get_mut("apple"), "red");
2873    }
2874
2875    #[test]
2876    fn test_no_memory_leaks() {
2877        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2878
2879        struct DropCounter;
2880
2881        impl Drop for DropCounter {
2882            fn drop(&mut self) {
2883                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2884            }
2885        }
2886
2887        let n = 100;
2888        for _ in 0..n {
2889            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2890            for i in 0..n {
2891                cache.put(i, DropCounter {});
2892            }
2893        }
2894        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
2895    }
2896
2897    #[test]
2898    fn test_no_memory_leaks_with_clear() {
2899        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2900
2901        struct DropCounter;
2902
2903        impl Drop for DropCounter {
2904            fn drop(&mut self) {
2905                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2906            }
2907        }
2908
2909        let n = 100;
2910        for _ in 0..n {
2911            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2912            for i in 0..n {
2913                cache.put(i, DropCounter {});
2914            }
2915            cache.clear();
2916        }
2917        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
2918    }
2919
2920    #[test]
2921    fn test_no_memory_leaks_with_resize() {
2922        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2923
2924        struct DropCounter;
2925
2926        impl Drop for DropCounter {
2927            fn drop(&mut self) {
2928                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2929            }
2930        }
2931
2932        let n = 100;
2933        for _ in 0..n {
2934            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2935            for i in 0..n {
2936                cache.put(i, DropCounter {});
2937            }
2938            cache.clear();
2939        }
2940        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
2941    }
2942
2943    #[test]
2944    fn test_no_memory_leaks_with_pop() {
2945        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2946
2947        #[derive(Hash, Eq)]
2948        struct KeyDropCounter(usize);
2949
2950        impl PartialEq for KeyDropCounter {
2951            fn eq(&self, other: &Self) -> bool {
2952                self.0.eq(&other.0)
2953            }
2954        }
2955
2956        impl Drop for KeyDropCounter {
2957            fn drop(&mut self) {
2958                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2959            }
2960        }
2961
2962        let n = 100;
2963        for _ in 0..n {
2964            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2965
2966            for i in 0..100 {
2967                cache.put(KeyDropCounter(i), i);
2968                cache.pop(&KeyDropCounter(i));
2969            }
2970        }
2971
2972        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n * 2);
2973    }
2974
2975    #[test]
2976    fn test_promote_and_demote() {
2977        let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
2978        for i in 0..5 {
2979            cache.push(i, i);
2980        }
2981        cache.promote(&1);
2982        cache.promote(&0);
2983        cache.demote(&3);
2984        cache.demote(&4);
2985        assert_eq!(cache.pop_lru(), Some((4, 4)));
2986        assert_eq!(cache.pop_lru(), Some((3, 3)));
2987        assert_eq!(cache.pop_lru(), Some((2, 2)));
2988        assert_eq!(cache.pop_lru(), Some((1, 1)));
2989        assert_eq!(cache.pop_lru(), Some((0, 0)));
2990        assert_eq!(cache.pop_lru(), None);
2991    }
2992
2993    #[test]
2994    fn test_get_key_value() {
2995        use alloc::string::String;
2996
2997        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2998
2999        let key = String::from("apple");
3000        cache.put(key, "red");
3001
3002        assert_eq!(
3003            cache.get_key_value("apple"),
3004            Some((&String::from("apple"), &"red"))
3005        );
3006        assert_eq!(cache.get_key_value("banana"), None);
3007    }
3008
3009    #[test]
3010    fn test_get_key_value_mut() {
3011        use alloc::string::String;
3012
3013        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
3014
3015        let key = String::from("apple");
3016        cache.put(key, "red");
3017
3018        let (k, v) = cache.get_key_value_mut("apple").unwrap();
3019        assert_eq!(k, &String::from("apple"));
3020        assert_eq!(v, &mut "red");
3021        *v = "green";
3022
3023        assert_eq!(
3024            cache.get_key_value("apple"),
3025            Some((&String::from("apple"), &"green"))
3026        );
3027        assert_eq!(cache.get_key_value("banana"), None);
3028    }
3029
3030    #[test]
3031    fn test_clone() {
3032        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3033        cache.put("a", 1);
3034        cache.put("b", 2);
3035        cache.put("c", 3);
3036
3037        let mut cloned = cache.clone();
3038
3039        assert_eq!(cache.pop_lru(), Some(("a", 1)));
3040        assert_eq!(cloned.pop_lru(), Some(("a", 1)));
3041
3042        assert_eq!(cache.pop_lru(), Some(("b", 2)));
3043        assert_eq!(cloned.pop_lru(), Some(("b", 2)));
3044
3045        assert_eq!(cache.pop_lru(), Some(("c", 3)));
3046        assert_eq!(cloned.pop_lru(), Some(("c", 3)));
3047
3048        assert_eq!(cache.pop_lru(), None);
3049        assert_eq!(cloned.pop_lru(), None);
3050    }
3051
3052    #[test]
3053    fn test_clone_unbounded() {
3054        let mut cache = LruCache::unbounded();
3055        cache.put("a", 1);
3056        cache.put("b", 2);
3057        cache.put("c", 3);
3058
3059        let mut cloned = cache.clone();
3060
3061        assert_eq!(cache.pop_lru(), Some(("a", 1)));
3062        assert_eq!(cloned.pop_lru(), Some(("a", 1)));
3063
3064        assert_eq!(cache.pop_lru(), Some(("b", 2)));
3065        assert_eq!(cloned.pop_lru(), Some(("b", 2)));
3066
3067        assert_eq!(cache.pop_lru(), Some(("c", 3)));
3068        assert_eq!(cloned.pop_lru(), Some(("c", 3)));
3069
3070        assert_eq!(cache.pop_lru(), None);
3071        assert_eq!(cloned.pop_lru(), None);
3072    }
3073
3074    #[test]
3075    fn iter_mut_stacked_borrows_violation() {
3076        let mut cache: LruCache<i32, i32> = LruCache::new(NonZeroUsize::new(3).unwrap());
3077        cache.put(1, 10);
3078        cache.put(2, 20);
3079        cache.put(3, 30);
3080
3081        for (_k, v) in cache.iter_mut() {
3082            *v *= 2;
3083        }
3084
3085        assert_eq!(cache.get(&1), Some(&20));
3086        assert_eq!(cache.get(&2), Some(&40));
3087        assert_eq!(cache.get(&3), Some(&60));
3088    }
3089}
3090
3091/// Doctests for what should *not* compile
3092///
3093/// ```compile_fail
3094/// let mut cache = lru::LruCache::<u32, u32>::unbounded();
3095/// let _: &'static u32 = cache.get_or_insert(0, || 92);
3096/// ```
3097///
3098/// ```compile_fail
3099/// let mut cache = lru::LruCache::<u32, u32>::unbounded();
3100/// let _: Option<(&'static u32, _)> = cache.peek_lru();
3101/// let _: Option<(_, &'static u32)> = cache.peek_lru();
3102/// ```
3103fn _test_lifetimes() {}