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 holds at most `cap` items without allocating storage space
236    /// for them.
237    ///
238    /// # Example
239    ///
240    /// ```
241    /// use lru::LruCache;
242    /// use std::num::NonZeroUsize;
243    /// let mut cache: LruCache<isize, &str> = LruCache::sparse(NonZeroUsize::new(1_000_000).unwrap());
244    /// ```
245    pub fn sparse(cap: NonZeroUsize) -> LruCache<K, V> {
246        LruCache::construct(cap, HashMap::default())
247    }
248
249    /// Creates a new LRU Cache that never automatically evicts items.
250    ///
251    /// # Example
252    ///
253    /// ```
254    /// use lru::LruCache;
255    /// use std::num::NonZeroUsize;
256    /// let mut cache: LruCache<isize, &str> = LruCache::unbounded();
257    /// ```
258    pub fn unbounded() -> LruCache<K, V> {
259        LruCache::construct(NonZeroUsize::MAX, HashMap::default())
260    }
261}
262
263impl<K: Hash + Eq, V, S: BuildHasher> LruCache<K, V, S> {
264    /// Creates a new LRU Cache that holds at most `cap` items and
265    /// uses the provided hash builder to hash keys.
266    ///
267    /// # Example
268    ///
269    /// ```
270    /// use lru::{LruCache, DefaultHasher};
271    /// use std::num::NonZeroUsize;
272    ///
273    /// let s = DefaultHasher::default();
274    /// let mut cache: LruCache<isize, &str> = LruCache::with_hasher(NonZeroUsize::new(10).unwrap(), s);
275    /// ```
276    pub fn with_hasher(cap: NonZeroUsize, hash_builder: S) -> LruCache<K, V, S> {
277        LruCache::construct(
278            cap,
279            HashMap::with_capacity_and_hasher(cap.into(), hash_builder),
280        )
281    }
282
283    /// Creates a new LRU Cache that never automatically evicts items and
284    /// uses the provided hash builder to hash keys.
285    ///
286    /// # Example
287    ///
288    /// ```
289    /// use lru::{LruCache, DefaultHasher};
290    ///
291    /// let s = DefaultHasher::default();
292    /// let mut cache: LruCache<isize, &str> = LruCache::unbounded_with_hasher(s);
293    /// ```
294    pub fn unbounded_with_hasher(hash_builder: S) -> LruCache<K, V, S> {
295        LruCache::construct(NonZeroUsize::MAX, HashMap::with_hasher(hash_builder))
296    }
297
298    /// Creates a new LRU Cache with the given capacity.
299    fn construct(
300        cap: NonZeroUsize,
301        map: HashMap<KeyRef<K>, NonNull<LruEntry<K, V>>, S>,
302    ) -> LruCache<K, V, S> {
303        // NB: The compiler warns that cache does not need to be marked as mutable if we
304        // declare it as such since we only mutate it inside the unsafe block.
305        let cache = LruCache {
306            map,
307            cap,
308            head: Box::into_raw(Box::new(LruEntry::new_sigil())),
309            tail: Box::into_raw(Box::new(LruEntry::new_sigil())),
310        };
311
312        unsafe {
313            (*cache.head).next = cache.tail;
314            (*cache.tail).prev = cache.head;
315        }
316
317        cache
318    }
319
320    /// Whether this LRU cache is unbounded.
321    fn is_unbounded(&self) -> bool {
322        self.cap() == NonZeroUsize::MAX
323    }
324
325    /// Puts a key-value pair into cache. If the key already exists in the cache, then it updates
326    /// the key's value and returns the old value. Otherwise, `None` is returned.
327    ///
328    /// # Example
329    ///
330    /// ```
331    /// use lru::LruCache;
332    /// use std::num::NonZeroUsize;
333    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
334    ///
335    /// assert_eq!(None, cache.put(1, "a"));
336    /// assert_eq!(None, cache.put(2, "b"));
337    /// assert_eq!(Some("b"), cache.put(2, "beta"));
338    ///
339    /// assert_eq!(cache.get(&1), Some(&"a"));
340    /// assert_eq!(cache.get(&2), Some(&"beta"));
341    /// ```
342    pub fn put(&mut self, k: K, v: V) -> Option<V> {
343        self.capturing_put(k, v, false).map(|(_, v)| v)
344    }
345
346    /// Pushes a key-value pair into the cache. If an entry with key `k` already exists in
347    /// the cache or another cache entry is removed (due to the lru's capacity),
348    /// then it returns the old entry's key-value pair. Otherwise, returns `None`.
349    ///
350    /// # Example
351    ///
352    /// ```
353    /// use lru::LruCache;
354    /// use std::num::NonZeroUsize;
355    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
356    ///
357    /// assert_eq!(None, cache.push(1, "a"));
358    /// assert_eq!(None, cache.push(2, "b"));
359    ///
360    /// // This push call returns (2, "b") because that was previously 2's entry in the cache.
361    /// assert_eq!(Some((2, "b")), cache.push(2, "beta"));
362    ///
363    /// // This push call returns (1, "a") because the cache is at capacity and 1's entry was the lru entry.
364    /// assert_eq!(Some((1, "a")), cache.push(3, "alpha"));
365    ///
366    /// assert_eq!(cache.get(&1), None);
367    /// assert_eq!(cache.get(&2), Some(&"beta"));
368    /// assert_eq!(cache.get(&3), Some(&"alpha"));
369    /// ```
370    pub fn push(&mut self, k: K, v: V) -> Option<(K, V)> {
371        self.capturing_put(k, v, true)
372    }
373
374    // Used internally by `put` and `push` to add a new entry to the lru.
375    // Takes ownership of and returns entries replaced due to the cache's capacity
376    // when `capture` is true.
377    fn capturing_put(&mut self, k: K, mut v: V, capture: bool) -> Option<(K, V)> {
378        let node_ref = self.map.get_mut(&KeyRef { k: &k });
379
380        match node_ref {
381            Some(node_ref) => {
382                // if the key is already in the cache just update its value and move it to the
383                // front of the list
384                let node_ptr: *mut LruEntry<K, V> = node_ref.as_ptr();
385
386                // gets a reference to the node to perform a swap and drops it right after
387                let node_ref = unsafe { &mut (*(*node_ptr).val.as_mut_ptr()) };
388                mem::swap(&mut v, node_ref);
389                let _ = node_ref;
390
391                self.detach(node_ptr);
392                self.attach(node_ptr);
393                Some((k, v))
394            }
395            None => {
396                let (replaced, node) = self.replace_or_create_node(k, v);
397                let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
398
399                self.attach(node_ptr);
400
401                let keyref = unsafe { (*node_ptr).key.as_ptr() };
402                self.map.insert(KeyRef { k: keyref }, node);
403
404                replaced.filter(|_| capture)
405            }
406        }
407    }
408
409    // Used internally to swap out a node if the cache is full or to create a new node if space
410    // is available. Shared between `put`, `push`, `get_or_insert`, and `get_or_insert_mut`.
411    #[allow(clippy::type_complexity)]
412    fn replace_or_create_node(&mut self, k: K, v: V) -> (Option<(K, V)>, NonNull<LruEntry<K, V>>) {
413        if self.len() == self.cap().get() {
414            // if the cache is full, remove the last entry so we can use it for the new key
415            let old_key = KeyRef {
416                k: unsafe { &(*(*(*self.tail).prev).key.as_ptr()) },
417            };
418            let old_node = self.map.remove(&old_key).unwrap();
419            let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
420
421            // read out the node's old key and value and then replace it
422            let replaced = unsafe {
423                (
424                    mem::replace(&mut (*node_ptr).key, mem::MaybeUninit::new(k)).assume_init(),
425                    mem::replace(&mut (*node_ptr).val, mem::MaybeUninit::new(v)).assume_init(),
426                )
427            };
428
429            self.detach(node_ptr);
430
431            (Some(replaced), old_node)
432        } else {
433            // if the cache is not full allocate a new LruEntry
434            (
435                None,
436                NonNull::new(Box::into_raw(Box::new(LruEntry::new(k, v)))).unwrap(),
437            )
438        }
439    }
440
441    /// Returns a reference to the value of the key in the cache or `None` if it is not
442    /// present in the cache. Moves the key to the head of the LRU list if it exists.
443    ///
444    /// # Example
445    ///
446    /// ```
447    /// use lru::LruCache;
448    /// use std::num::NonZeroUsize;
449    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
450    ///
451    /// cache.put(1, "a");
452    /// cache.put(2, "b");
453    /// cache.put(2, "c");
454    /// cache.put(3, "d");
455    ///
456    /// assert_eq!(cache.get(&1), None);
457    /// assert_eq!(cache.get(&2), Some(&"c"));
458    /// assert_eq!(cache.get(&3), Some(&"d"));
459    /// ```
460    pub fn get<'a, Q>(&'a mut self, k: &Q) -> Option<&'a V>
461    where
462        K: Borrow<Q>,
463        Q: Hash + Eq + ?Sized,
464    {
465        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
466            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
467
468            self.detach(node_ptr);
469            self.attach(node_ptr);
470
471            Some(unsafe { &*(*node_ptr).val.as_ptr() })
472        } else {
473            None
474        }
475    }
476
477    /// Returns a mutable reference to the value of the key in the cache or `None` if it
478    /// is not present in the cache. Moves the key to the head of the LRU list if it exists.
479    ///
480    /// # Example
481    ///
482    /// ```
483    /// use lru::LruCache;
484    /// use std::num::NonZeroUsize;
485    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
486    ///
487    /// cache.put("apple", 8);
488    /// cache.put("banana", 4);
489    /// cache.put("banana", 6);
490    /// cache.put("pear", 2);
491    ///
492    /// assert_eq!(cache.get_mut(&"apple"), None);
493    /// assert_eq!(cache.get_mut(&"banana"), Some(&mut 6));
494    /// assert_eq!(cache.get_mut(&"pear"), Some(&mut 2));
495    /// ```
496    pub fn get_mut<'a, Q>(&'a mut self, k: &Q) -> Option<&'a mut V>
497    where
498        K: Borrow<Q>,
499        Q: Hash + Eq + ?Sized,
500    {
501        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
502            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
503
504            self.detach(node_ptr);
505            self.attach(node_ptr);
506
507            Some(unsafe { &mut *(*node_ptr).val.as_mut_ptr() })
508        } else {
509            None
510        }
511    }
512
513    /// Returns a key-value references pair of the key in the cache or `None` if it is not
514    /// present in the cache. Moves the key to the head of the LRU list if it exists.
515    ///
516    /// # Example
517    ///
518    /// ```
519    /// use lru::LruCache;
520    /// use std::num::NonZeroUsize;
521    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
522    ///
523    /// cache.put(String::from("1"), "a");
524    /// cache.put(String::from("2"), "b");
525    /// cache.put(String::from("2"), "c");
526    /// cache.put(String::from("3"), "d");
527    ///
528    /// assert_eq!(cache.get_key_value("1"), None);
529    /// assert_eq!(cache.get_key_value("2"), Some((&String::from("2"), &"c")));
530    /// assert_eq!(cache.get_key_value("3"), Some((&String::from("3"), &"d")));
531    /// ```
532    pub fn get_key_value<'a, Q>(&'a mut self, k: &Q) -> Option<(&'a K, &'a V)>
533    where
534        K: Borrow<Q>,
535        Q: Hash + Eq + ?Sized,
536    {
537        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
538            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
539
540            self.detach(node_ptr);
541            self.attach(node_ptr);
542
543            Some(unsafe { (&*(*node_ptr).key.as_ptr(), &*(*node_ptr).val.as_ptr()) })
544        } else {
545            None
546        }
547    }
548
549    /// Returns a key-value references pair of the key in the cache or `None` if it is not
550    /// present in the cache. The reference to the value of the key is mutable. Moves the key to
551    /// the head of the LRU list if it exists.
552    ///
553    /// # Example
554    ///
555    /// ```
556    /// use lru::LruCache;
557    /// use std::num::NonZeroUsize;
558    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
559    ///
560    /// cache.put(1, "a");
561    /// cache.put(2, "b");
562    /// let (k, v) = cache.get_key_value_mut(&1).unwrap();
563    /// assert_eq!(k, &1);
564    /// assert_eq!(v, &mut "a");
565    /// *v = "aa";
566    /// cache.put(3, "c");
567    /// assert_eq!(cache.get_key_value(&2), None);
568    /// assert_eq!(cache.get_key_value(&1), Some((&1, &"aa")));
569    /// assert_eq!(cache.get_key_value(&3), Some((&3, &"c")));
570    /// ```
571    pub fn get_key_value_mut<'a, Q>(&'a mut self, k: &Q) -> Option<(&'a K, &'a mut V)>
572    where
573        K: Borrow<Q>,
574        Q: Hash + Eq + ?Sized,
575    {
576        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
577            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
578
579            self.detach(node_ptr);
580            self.attach(node_ptr);
581
582            Some(unsafe {
583                (
584                    &*(*node_ptr).key.as_ptr(),
585                    &mut *(*node_ptr).val.as_mut_ptr(),
586                )
587            })
588        } else {
589            None
590        }
591    }
592
593    /// Returns a reference to the value of the key in the cache if it is
594    /// present in the cache and moves the key to the head of the LRU list.
595    /// If the key does not exist the provided `FnOnce` is used to populate
596    /// the list and a reference is returned.
597    ///
598    /// # Example
599    ///
600    /// ```
601    /// use lru::LruCache;
602    /// use std::num::NonZeroUsize;
603    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
604    ///
605    /// cache.put(1, "a");
606    /// cache.put(2, "b");
607    /// cache.put(2, "c");
608    /// cache.put(3, "d");
609    ///
610    /// assert_eq!(cache.get_or_insert(2, ||"a"), &"c");
611    /// assert_eq!(cache.get_or_insert(3, ||"a"), &"d");
612    /// assert_eq!(cache.get_or_insert(1, ||"a"), &"a");
613    /// assert_eq!(cache.get_or_insert(1, ||"b"), &"a");
614    /// ```
615    pub fn get_or_insert<F>(&mut self, k: K, f: F) -> &V
616    where
617        F: FnOnce() -> V,
618    {
619        self.get_or_insert_with_key(k, |_| f())
620    }
621
622    /// Returns a reference to the value of the key in the cache if it is
623    /// present in the cache and moves the key to the head of the LRU list.
624    /// If the key does not exist the provided `FnOnce` is used by passing
625    /// a reference to the key to populate the list and a reference is returned.
626    ///
627    /// # Example
628    ///
629    /// ```
630    /// use lru::LruCache;
631    /// use std::num::NonZeroUsize;
632    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
633    ///
634    /// cache.put("One", 1);
635    /// cache.put("Two", 2);
636    /// cache.put("Two", 3);
637    /// cache.put("Three", 4);
638    ///
639    /// assert_eq!(cache.get_or_insert_with_key("Two", |_|1), &3);
640    /// assert_eq!(cache.get_or_insert_with_key("Three", |k|k.len()), &4);
641    /// assert_eq!(cache.get_or_insert_with_key("One", |_|1), &1);
642    /// assert_eq!(cache.get_or_insert_with_key("One", |k|k.len()), &1);
643    /// ```
644    pub fn get_or_insert_with_key<F>(&mut self, k: K, f: F) -> &V
645    where
646        F: FnOnce(&K) -> V,
647    {
648        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
649            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
650
651            self.detach(node_ptr);
652            self.attach(node_ptr);
653
654            unsafe { &*(*node_ptr).val.as_ptr() }
655        } else {
656            let v = f(&k);
657            let (_, node) = self.replace_or_create_node(k, v);
658            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
659
660            self.attach(node_ptr);
661
662            let keyref = unsafe { (*node_ptr).key.as_ptr() };
663            self.map.insert(KeyRef { k: keyref }, node);
664            unsafe { &*(*node_ptr).val.as_ptr() }
665        }
666    }
667
668    /// Returns a reference to the value of the key in the cache if it is
669    /// present in the cache and moves the key to the head of the LRU list.
670    /// If the key does not exist the provided `FnOnce` is used to populate
671    /// the list and a reference is returned. The value referenced by the
672    /// key is only cloned (using `to_owned()`) if it doesn't exist in the
673    /// cache.
674    ///
675    /// # Example
676    ///
677    /// ```
678    /// use lru::LruCache;
679    /// use std::num::NonZeroUsize;
680    /// use std::rc::Rc;
681    ///
682    /// let key1 = Rc::new("1".to_owned());
683    /// let key2 = Rc::new("2".to_owned());
684    /// let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
685    /// assert_eq!(cache.get_or_insert_ref(&key1, ||"One".to_owned()), "One");
686    /// assert_eq!(cache.get_or_insert_ref(&key2, ||"Two".to_owned()), "Two");
687    /// assert_eq!(cache.get_or_insert_ref(&key2, ||"Not two".to_owned()), "Two");
688    /// assert_eq!(cache.get_or_insert_ref(&key2, ||"Again not two".to_owned()), "Two");
689    /// assert_eq!(Rc::strong_count(&key1), 2);
690    /// assert_eq!(Rc::strong_count(&key2), 2); // key2 was only cloned once even though we
691    ///                                         // queried it 3 times
692    /// ```
693    pub fn get_or_insert_ref<'a, Q, F>(&'a mut self, k: &'_ Q, f: F) -> &'a V
694    where
695        K: Borrow<Q>,
696        Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
697        F: FnOnce() -> V,
698    {
699        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
700            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
701
702            self.detach(node_ptr);
703            self.attach(node_ptr);
704
705            unsafe { &*(*node_ptr).val.as_ptr() }
706        } else {
707            let v = f();
708            let (_, node) = self.replace_or_create_node(k.to_owned(), v);
709            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
710
711            self.attach(node_ptr);
712
713            let keyref = unsafe { (*node_ptr).key.as_ptr() };
714            self.map.insert(KeyRef { k: keyref }, node);
715            unsafe { &*(*node_ptr).val.as_ptr() }
716        }
717    }
718
719    /// Returns a reference to the value of the key in the cache if it is
720    /// present in the cache and moves the key to the head of the LRU list.
721    /// If the key does not exist the provided `FnOnce` is used to populate
722    /// the list and a reference is returned. If `FnOnce` returns `Err`,
723    /// returns the `Err`.
724    ///
725    /// # Example
726    ///
727    /// ```
728    /// use lru::LruCache;
729    /// use std::num::NonZeroUsize;
730    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
731    ///
732    /// cache.put(1, "a");
733    /// cache.put(2, "b");
734    /// cache.put(2, "c");
735    /// cache.put(3, "d");
736    ///
737    /// let f = ||->Result<&str, String> {Err("failed".to_owned())};
738    /// let a = ||->Result<&str, String> {Ok("a")};
739    /// let b = ||->Result<&str, String> {Ok("b")};
740    /// assert_eq!(cache.try_get_or_insert(2, a), Ok(&"c"));
741    /// assert_eq!(cache.try_get_or_insert(3, a), Ok(&"d"));
742    /// assert_eq!(cache.try_get_or_insert(4, f), Err("failed".to_owned()));
743    /// assert_eq!(cache.try_get_or_insert(5, b), Ok(&"b"));
744    /// assert_eq!(cache.try_get_or_insert(5, a), Ok(&"b"));
745    /// ```
746    pub fn try_get_or_insert<F, E>(&mut self, k: K, f: F) -> Result<&V, E>
747    where
748        F: FnOnce() -> Result<V, E>,
749    {
750        self.try_get_or_insert_with_key(k, |_| f())
751    }
752
753    /// Returns a reference to the value of the key in the cache if it is
754    /// present in the cache and moves the key to the head of the LRU list.
755    /// If the key does not exist the provided `FnOnce` is used by passing
756    /// a reference to the key to populate the list and a reference is returned.
757    /// If `FnOnce` returns `Err`, returns the `Err`.
758    ///
759    /// # Example
760    ///
761    /// ```
762    /// use lru::LruCache;
763    /// use std::num::NonZeroUsize;
764    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
765    ///
766    /// cache.put("One", 1);
767    /// cache.put("Two", 2);
768    /// cache.put("Two", 3);
769    /// cache.put("Three", 4);
770    ///
771    /// let f = |_: &&str|->Result<usize, String> {Err("failed".to_owned())};
772    /// let len = |k: &&str|->Result<usize, String> {Ok(k.len())};
773    /// let zero = |_: &&str|->Result<usize, String> {Ok(0)};
774    /// assert_eq!(cache.try_get_or_insert_with_key("Two", len), Ok(&3));
775    /// assert_eq!(cache.try_get_or_insert_with_key("Three", len), Ok(&4));
776    /// assert_eq!(cache.try_get_or_insert_with_key("Four", f), Err("failed".to_owned()));
777    /// assert_eq!(cache.try_get_or_insert_with_key("Five", len), Ok(&4));
778    /// assert_eq!(cache.try_get_or_insert_with_key("Five", zero), Ok(&4));
779    /// ```
780    pub fn try_get_or_insert_with_key<F, E>(&mut self, k: K, f: F) -> Result<&V, E>
781    where
782        F: FnOnce(&K) -> Result<V, E>,
783    {
784        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
785            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
786
787            self.detach(node_ptr);
788            self.attach(node_ptr);
789
790            unsafe { Ok(&*(*node_ptr).val.as_ptr()) }
791        } else {
792            let v = f(&k)?;
793            let (_, node) = self.replace_or_create_node(k, v);
794            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
795
796            self.attach(node_ptr);
797
798            let keyref = unsafe { (*node_ptr).key.as_ptr() };
799            self.map.insert(KeyRef { k: keyref }, node);
800            Ok(unsafe { &*(*node_ptr).val.as_ptr() })
801        }
802    }
803
804    /// Returns a reference to the value of the key in the cache if it is
805    /// present in the cache and moves the key to the head of the LRU list.
806    /// If the key does not exist the provided `FnOnce` is used to populate
807    /// the list and a reference is returned. If `FnOnce` returns `Err`,
808    /// returns the `Err`. The value referenced by the key is only cloned
809    /// (using `to_owned()`) if it doesn't exist in the cache and `FnOnce`
810    /// succeeds.
811    ///
812    /// # Example
813    ///
814    /// ```
815    /// use lru::LruCache;
816    /// use std::num::NonZeroUsize;
817    /// use std::rc::Rc;
818    ///
819    /// let key1 = Rc::new("1".to_owned());
820    /// let key2 = Rc::new("2".to_owned());
821    /// let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
822    /// let f = ||->Result<String, ()> {Err(())};
823    /// let a = ||->Result<String, ()> {Ok("One".to_owned())};
824    /// let b = ||->Result<String, ()> {Ok("Two".to_owned())};
825    /// assert_eq!(cache.try_get_or_insert_ref(&key1, a), Ok(&"One".to_owned()));
826    /// assert_eq!(cache.try_get_or_insert_ref(&key2, f), Err(()));
827    /// assert_eq!(cache.try_get_or_insert_ref(&key2, b), Ok(&"Two".to_owned()));
828    /// assert_eq!(cache.try_get_or_insert_ref(&key2, a), Ok(&"Two".to_owned()));
829    /// assert_eq!(Rc::strong_count(&key1), 2);
830    /// assert_eq!(Rc::strong_count(&key2), 2); // key2 was only cloned once even though we
831    ///                                         // queried it 3 times
832    /// ```
833    pub fn try_get_or_insert_ref<'a, Q, F, E>(&'a mut self, k: &'_ Q, f: F) -> Result<&'a V, E>
834    where
835        K: Borrow<Q>,
836        Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
837        F: FnOnce() -> Result<V, E>,
838    {
839        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
840            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
841
842            self.detach(node_ptr);
843            self.attach(node_ptr);
844
845            unsafe { Ok(&*(*node_ptr).val.as_ptr()) }
846        } else {
847            let v = f()?;
848            let (_, node) = self.replace_or_create_node(k.to_owned(), v);
849            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
850
851            self.attach(node_ptr);
852
853            let keyref = unsafe { (*node_ptr).key.as_ptr() };
854            self.map.insert(KeyRef { k: keyref }, node);
855            Ok(unsafe { &*(*node_ptr).val.as_ptr() })
856        }
857    }
858
859    /// Returns a mutable reference to the value of the key in the cache if it is
860    /// present in the cache and moves the key to the head of the LRU list.
861    /// If the key does not exist the provided `FnOnce` is used to populate
862    /// the list and a mutable reference is returned.
863    ///
864    /// # Example
865    ///
866    /// ```
867    /// use lru::LruCache;
868    /// use std::num::NonZeroUsize;
869    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
870    ///
871    /// cache.put(1, "a");
872    /// cache.put(2, "b");
873    ///
874    /// let v = cache.get_or_insert_mut(2, ||"c");
875    /// assert_eq!(v, &"b");
876    /// *v = "d";
877    /// assert_eq!(cache.get_or_insert_mut(2, ||"e"), &mut "d");
878    /// assert_eq!(cache.get_or_insert_mut(3, ||"f"), &mut "f");
879    /// assert_eq!(cache.get_or_insert_mut(3, ||"e"), &mut "f");
880    /// ```
881    pub fn get_or_insert_mut<F>(&mut self, k: K, f: F) -> &mut V
882    where
883        F: FnOnce() -> V,
884    {
885        self.get_or_insert_mut_with_key(k, |_| f())
886    }
887
888    /// Returns a mutable reference to the value of the key in the cache if it is
889    /// present in the cache and moves the key to the head of the LRU list.
890    /// If the key does not exist the provided `FnOnce` is used by passing
891    /// a reference to the key to populate the list and a mutable reference
892    /// is returned.
893    ///
894    /// # Example
895    ///
896    /// ```
897    /// use lru::LruCache;
898    /// use std::num::NonZeroUsize;
899    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
900    ///
901    /// cache.put("One", 1);
902    /// cache.put("Two", 2);
903    /// cache.put("Two", 3);
904    /// cache.put("Three", 4);
905    ///
906    /// assert_eq!(cache.get_or_insert_mut_with_key("Two", |_|1), &mut 3);
907    /// assert_eq!(cache.get_or_insert_mut_with_key("Three", |k|k.len()), &mut 4);
908    /// assert_eq!(cache.get_or_insert_mut_with_key("One", |_|1), &mut 1);
909    /// assert_eq!(cache.get_or_insert_mut_with_key("One", |k|k.len()), &mut 1);
910    /// ```
911    pub fn get_or_insert_mut_with_key<F>(&mut self, k: K, f: F) -> &mut V
912    where
913        F: FnOnce(&K) -> V,
914    {
915        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
916            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
917
918            self.detach(node_ptr);
919            self.attach(node_ptr);
920
921            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
922        } else {
923            let v = f(&k);
924            let (_, node) = self.replace_or_create_node(k, v);
925            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
926
927            self.attach(node_ptr);
928
929            let keyref = unsafe { (*node_ptr).key.as_ptr() };
930            self.map.insert(KeyRef { k: keyref }, node);
931            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
932        }
933    }
934
935    /// Returns a mutable reference to the value of the key in the cache if it is
936    /// present in the cache and moves the key to the head of the LRU list.
937    /// If the key does not exist the provided `FnOnce` is used to populate
938    /// the list and a mutable reference is returned. The value referenced by the
939    /// key is only cloned (using `to_owned()`) if it doesn't exist in the cache.
940    ///
941    /// # Example
942    ///
943    /// ```
944    /// use lru::LruCache;
945    /// use std::num::NonZeroUsize;
946    /// use std::rc::Rc;
947    ///
948    /// let key1 = Rc::new("1".to_owned());
949    /// let key2 = Rc::new("2".to_owned());
950    /// let mut cache = LruCache::<Rc<String>, &'static str>::new(NonZeroUsize::new(2).unwrap());
951    /// cache.get_or_insert_mut_ref(&key1, ||"One");
952    /// let v = cache.get_or_insert_mut_ref(&key2, ||"Two");
953    /// *v = "New two";
954    /// assert_eq!(cache.get_or_insert_mut_ref(&key2, ||"Two"), &mut "New two");
955    /// assert_eq!(Rc::strong_count(&key1), 2);
956    /// assert_eq!(Rc::strong_count(&key2), 2); // key2 was only cloned once even though we
957    ///                                         // queried it 2 times
958    /// ```
959    pub fn get_or_insert_mut_ref<'a, Q, F>(&'a mut self, k: &'_ Q, f: F) -> &'a mut V
960    where
961        K: Borrow<Q>,
962        Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
963        F: FnOnce() -> V,
964    {
965        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
966            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
967
968            self.detach(node_ptr);
969            self.attach(node_ptr);
970
971            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
972        } else {
973            let v = f();
974            let (_, node) = self.replace_or_create_node(k.to_owned(), v);
975            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
976
977            self.attach(node_ptr);
978
979            let keyref = unsafe { (*node_ptr).key.as_ptr() };
980            self.map.insert(KeyRef { k: keyref }, node);
981            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
982        }
983    }
984
985    /// Returns a mutable reference to the value of the key in the cache if it is
986    /// present in the cache and moves the key to the head of the LRU list.
987    /// If the key does not exist the provided `FnOnce` is used to populate
988    /// the list and a mutable reference is returned. If `FnOnce` returns `Err`,
989    /// returns the `Err`.
990    ///
991    /// # Example
992    ///
993    /// ```
994    /// use lru::LruCache;
995    /// use std::num::NonZeroUsize;
996    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
997    ///
998    /// cache.put(1, "a");
999    /// cache.put(2, "b");
1000    /// cache.put(2, "c");
1001    ///
1002    /// let f = ||->Result<&str, String> {Err("failed".to_owned())};
1003    /// let a = ||->Result<&str, String> {Ok("a")};
1004    /// let b = ||->Result<&str, String> {Ok("b")};
1005    /// if let Ok(v) = cache.try_get_or_insert_mut(2, a) {
1006    ///     *v = "d";
1007    /// }
1008    /// assert_eq!(cache.try_get_or_insert_mut(2, a), Ok(&mut "d"));
1009    /// assert_eq!(cache.try_get_or_insert_mut(3, f), Err("failed".to_owned()));
1010    /// assert_eq!(cache.try_get_or_insert_mut(4, b), Ok(&mut "b"));
1011    /// assert_eq!(cache.try_get_or_insert_mut(4, a), Ok(&mut "b"));
1012    /// ```
1013    pub fn try_get_or_insert_mut<F, E>(&mut self, k: K, f: F) -> Result<&mut V, E>
1014    where
1015        F: FnOnce() -> Result<V, E>,
1016    {
1017        self.try_get_or_insert_mut_with_key(k, |_| f())
1018    }
1019
1020    /// Returns a mutable reference to the value of the key in the cache if it is
1021    /// present in the cache and moves the key to the head of the LRU list.
1022    /// If the key does not exist the provided `FnOnce` is used by passing
1023    /// a reference to the key to populate the list and a mutable reference
1024    /// is returned. If `FnOnce` returns `Err`, returns the `Err`.
1025    ///
1026    /// # Example
1027    ///
1028    /// ```
1029    /// use lru::LruCache;
1030    /// use std::num::NonZeroUsize;
1031    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1032    ///
1033    /// cache.put("One", 1);
1034    /// cache.put("Two", 2);
1035    /// cache.put("Two", 3);
1036    /// cache.put("Three", 4);
1037    ///
1038    /// let f = |_: &&str|->Result<usize, String> {Err("failed".to_owned())};
1039    /// let len = |k: &&str|->Result<usize, String> {Ok(k.len())};
1040    /// let zero = |_: &&str|->Result<usize, String> {Ok(0)};
1041    /// assert_eq!(cache.try_get_or_insert_mut_with_key("Two", len), Ok(&mut 3));
1042    /// assert_eq!(cache.try_get_or_insert_mut_with_key("Three", len), Ok(&mut 4));
1043    /// assert_eq!(cache.try_get_or_insert_mut_with_key("Four", f), Err("failed".to_owned()));
1044    /// assert_eq!(cache.try_get_or_insert_mut_with_key("Five", len), Ok(&mut 4));
1045    /// assert_eq!(cache.try_get_or_insert_mut_with_key("Five", zero), Ok(&mut 4));
1046    /// ```
1047    pub fn try_get_or_insert_mut_with_key<F, E>(&mut self, k: K, f: F) -> Result<&mut V, E>
1048    where
1049        F: FnOnce(&K) -> Result<V, E>,
1050    {
1051        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
1052            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1053
1054            self.detach(node_ptr);
1055            self.attach(node_ptr);
1056
1057            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
1058        } else {
1059            let v = f(&k)?;
1060            let (_, node) = self.replace_or_create_node(k, v);
1061            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1062
1063            self.attach(node_ptr);
1064
1065            let keyref = unsafe { (*node_ptr).key.as_ptr() };
1066            self.map.insert(KeyRef { k: keyref }, node);
1067            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
1068        }
1069    }
1070
1071    /// Returns a mutable reference to the value of the key in the cache if it is
1072    /// present in the cache and moves the key to the head of the LRU list.
1073    /// If the key does not exist the provided `FnOnce` is used to populate
1074    /// the list and a mutable reference is returned. If `FnOnce` returns `Err`,
1075    /// returns the `Err`. The value referenced by the key is only cloned
1076    /// (using `to_owned()`) if it doesn't exist in the cache and `FnOnce`
1077    /// succeeds.
1078    ///
1079    /// # Example
1080    ///
1081    /// ```
1082    /// use lru::LruCache;
1083    /// use std::num::NonZeroUsize;
1084    /// use std::rc::Rc;
1085    ///
1086    /// let key1 = Rc::new("1".to_owned());
1087    /// let key2 = Rc::new("2".to_owned());
1088    /// let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
1089    /// let f = ||->Result<String, ()> {Err(())};
1090    /// let a = ||->Result<String, ()> {Ok("One".to_owned())};
1091    /// let b = ||->Result<String, ()> {Ok("Two".to_owned())};
1092    /// assert_eq!(cache.try_get_or_insert_mut_ref(&key1, a), Ok(&mut "One".to_owned()));
1093    /// assert_eq!(cache.try_get_or_insert_mut_ref(&key2, f), Err(()));
1094    /// if let Ok(v) = cache.try_get_or_insert_mut_ref(&key2, b) {
1095    ///     *v = "New two".to_owned();
1096    /// }
1097    /// assert_eq!(cache.try_get_or_insert_mut_ref(&key2, a), Ok(&mut "New two".to_owned()));
1098    /// assert_eq!(Rc::strong_count(&key1), 2);
1099    /// assert_eq!(Rc::strong_count(&key2), 2); // key2 was only cloned once even though we
1100    ///                                         // queried it 3 times
1101    /// ```
1102    pub fn try_get_or_insert_mut_ref<'a, Q, F, E>(
1103        &'a mut self,
1104        k: &'_ Q,
1105        f: F,
1106    ) -> Result<&'a mut V, E>
1107    where
1108        K: Borrow<Q>,
1109        Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
1110        F: FnOnce() -> Result<V, E>,
1111    {
1112        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
1113            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1114
1115            self.detach(node_ptr);
1116            self.attach(node_ptr);
1117
1118            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
1119        } else {
1120            let v = f()?;
1121            let (_, node) = self.replace_or_create_node(k.to_owned(), v);
1122            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1123
1124            self.attach(node_ptr);
1125
1126            let keyref = unsafe { (*node_ptr).key.as_ptr() };
1127            self.map.insert(KeyRef { k: keyref }, node);
1128            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
1129        }
1130    }
1131
1132    /// Returns a reference to the value corresponding to the key in the cache or `None` if it is
1133    /// not present in the cache. Unlike `get`, `peek` does not update the LRU list so the key's
1134    /// position will be unchanged.
1135    ///
1136    /// # Example
1137    ///
1138    /// ```
1139    /// use lru::LruCache;
1140    /// use std::num::NonZeroUsize;
1141    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1142    ///
1143    /// cache.put(1, "a");
1144    /// cache.put(2, "b");
1145    ///
1146    /// assert_eq!(cache.peek(&1), Some(&"a"));
1147    /// assert_eq!(cache.peek(&2), Some(&"b"));
1148    /// ```
1149    pub fn peek<'a, Q>(&'a self, k: &Q) -> Option<&'a V>
1150    where
1151        K: Borrow<Q>,
1152        Q: Hash + Eq + ?Sized,
1153    {
1154        self.map
1155            .get(KeyWrapper::from_ref(k))
1156            .map(|node| unsafe { &*node.as_ref().val.as_ptr() })
1157    }
1158
1159    /// Returns a mutable reference to the value corresponding to the key in the cache or `None`
1160    /// if it is not present in the cache. Unlike `get_mut`, `peek_mut` does not update the LRU
1161    /// list so the key's position will be unchanged.
1162    ///
1163    /// # Example
1164    ///
1165    /// ```
1166    /// use lru::LruCache;
1167    /// use std::num::NonZeroUsize;
1168    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1169    ///
1170    /// cache.put(1, "a");
1171    /// cache.put(2, "b");
1172    ///
1173    /// assert_eq!(cache.peek_mut(&1), Some(&mut "a"));
1174    /// assert_eq!(cache.peek_mut(&2), Some(&mut "b"));
1175    /// ```
1176    pub fn peek_mut<'a, Q>(&'a mut self, k: &Q) -> Option<&'a mut V>
1177    where
1178        K: Borrow<Q>,
1179        Q: Hash + Eq + ?Sized,
1180    {
1181        match self.map.get_mut(KeyWrapper::from_ref(k)) {
1182            None => None,
1183            Some(node) => Some(unsafe { &mut *(*node.as_ptr()).val.as_mut_ptr() }),
1184        }
1185    }
1186
1187    /// Returns the value corresponding to the least recently used item or `None` if the
1188    /// cache is empty. Like `peek`, `peek_lru` does not update the LRU list so the item's
1189    /// position will be unchanged.
1190    ///
1191    /// # Example
1192    ///
1193    /// ```
1194    /// use lru::LruCache;
1195    /// use std::num::NonZeroUsize;
1196    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1197    ///
1198    /// cache.put(1, "a");
1199    /// cache.put(2, "b");
1200    ///
1201    /// assert_eq!(cache.peek_lru(), Some((&1, &"a")));
1202    /// ```
1203    pub fn peek_lru(&self) -> Option<(&K, &V)> {
1204        if self.is_empty() {
1205            return None;
1206        }
1207
1208        let (key, val);
1209        unsafe {
1210            let node = (*self.tail).prev;
1211            key = &(*(*node).key.as_ptr()) as &K;
1212            val = &(*(*node).val.as_ptr()) as &V;
1213        }
1214
1215        Some((key, val))
1216    }
1217
1218    /// Returns the value corresponding to the most recently used item or `None` if the
1219    /// cache is empty. Like `peek`, `peek_mru` does not update the LRU list so the item's
1220    /// position will be unchanged.
1221    ///
1222    /// # Example
1223    ///
1224    /// ```
1225    /// use lru::LruCache;
1226    /// use std::num::NonZeroUsize;
1227    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1228    ///
1229    /// cache.put(1, "a");
1230    /// cache.put(2, "b");
1231    ///
1232    /// assert_eq!(cache.peek_mru(), Some((&2, &"b")));
1233    /// ```
1234    pub fn peek_mru(&self) -> Option<(&K, &V)> {
1235        if self.is_empty() {
1236            return None;
1237        }
1238
1239        let (key, val);
1240        unsafe {
1241            let node: *mut LruEntry<K, V> = (*self.head).next;
1242            key = &(*(*node).key.as_ptr()) as &K;
1243            val = &(*(*node).val.as_ptr()) as &V;
1244        }
1245
1246        Some((key, val))
1247    }
1248
1249    /// Returns a bool indicating whether the given key is in the cache. Does not update the
1250    /// LRU list.
1251    ///
1252    /// # Example
1253    ///
1254    /// ```
1255    /// use lru::LruCache;
1256    /// use std::num::NonZeroUsize;
1257    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1258    ///
1259    /// cache.put(1, "a");
1260    /// cache.put(2, "b");
1261    /// cache.put(3, "c");
1262    ///
1263    /// assert!(!cache.contains(&1));
1264    /// assert!(cache.contains(&2));
1265    /// assert!(cache.contains(&3));
1266    /// ```
1267    pub fn contains<Q>(&self, k: &Q) -> bool
1268    where
1269        K: Borrow<Q>,
1270        Q: Hash + Eq + ?Sized,
1271    {
1272        self.map.contains_key(KeyWrapper::from_ref(k))
1273    }
1274
1275    /// Removes and returns the value corresponding to the key from the cache or
1276    /// `None` if it does not exist.
1277    ///
1278    /// # Example
1279    ///
1280    /// ```
1281    /// use lru::LruCache;
1282    /// use std::num::NonZeroUsize;
1283    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1284    ///
1285    /// cache.put(2, "a");
1286    ///
1287    /// assert_eq!(cache.pop(&1), None);
1288    /// assert_eq!(cache.pop(&2), Some("a"));
1289    /// assert_eq!(cache.pop(&2), None);
1290    /// assert_eq!(cache.len(), 0);
1291    /// ```
1292    pub fn pop<Q>(&mut self, k: &Q) -> Option<V>
1293    where
1294        K: Borrow<Q>,
1295        Q: Hash + Eq + ?Sized,
1296    {
1297        match self.map.remove(KeyWrapper::from_ref(k)) {
1298            None => None,
1299            Some(old_node) => {
1300                let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
1301
1302                // Detach the node from the linked list *before* freeing it and
1303                // dropping the key. `ptr::drop_in_place` below runs the key's
1304                // `Drop`, which may panic; if it does, unwinding must not leave
1305                // dangling `prev`/`next` pointers in the list. Detaching first
1306                // keeps the list consistent regardless of whether `Drop` panics.
1307                self.detach(node_ptr);
1308
1309                let mut old_node = unsafe { *Box::from_raw(node_ptr) };
1310                unsafe {
1311                    ptr::drop_in_place(old_node.key.as_mut_ptr());
1312                }
1313
1314                let LruEntry { key: _, val, .. } = old_node;
1315                unsafe { Some(val.assume_init()) }
1316            }
1317        }
1318    }
1319
1320    /// Removes and returns the key and the value corresponding to the key from the cache or
1321    /// `None` if it does not exist.
1322    ///
1323    /// # Example
1324    ///
1325    /// ```
1326    /// use lru::LruCache;
1327    /// use std::num::NonZeroUsize;
1328    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1329    ///
1330    /// cache.put(1, "a");
1331    /// cache.put(2, "a");
1332    ///
1333    /// assert_eq!(cache.pop(&1), Some("a"));
1334    /// assert_eq!(cache.pop_entry(&2), Some((2, "a")));
1335    /// assert_eq!(cache.pop(&1), None);
1336    /// assert_eq!(cache.pop_entry(&2), None);
1337    /// assert_eq!(cache.len(), 0);
1338    /// ```
1339    pub fn pop_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
1340    where
1341        K: Borrow<Q>,
1342        Q: Hash + Eq + ?Sized,
1343    {
1344        match self.map.remove(KeyWrapper::from_ref(k)) {
1345            None => None,
1346            Some(old_node) => {
1347                let mut old_node = unsafe { *Box::from_raw(old_node.as_ptr()) };
1348
1349                self.detach(&mut old_node);
1350
1351                let LruEntry { key, val, .. } = old_node;
1352                unsafe { Some((key.assume_init(), val.assume_init())) }
1353            }
1354        }
1355    }
1356
1357    /// Removes and returns the key and value corresponding to the least recently
1358    /// used item or `None` if the cache is empty.
1359    ///
1360    /// # Example
1361    ///
1362    /// ```
1363    /// use lru::LruCache;
1364    /// use std::num::NonZeroUsize;
1365    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1366    ///
1367    /// cache.put(2, "a");
1368    /// cache.put(3, "b");
1369    /// cache.put(4, "c");
1370    /// cache.get(&3);
1371    ///
1372    /// assert_eq!(cache.pop_lru(), Some((4, "c")));
1373    /// assert_eq!(cache.pop_lru(), Some((3, "b")));
1374    /// assert_eq!(cache.pop_lru(), None);
1375    /// assert_eq!(cache.len(), 0);
1376    /// ```
1377    pub fn pop_lru(&mut self) -> Option<(K, V)> {
1378        let node = self.remove_last()?;
1379        // N.B.: Can't destructure directly because of https://github.com/rust-lang/rust/issues/28536
1380        let node = *node;
1381        let LruEntry { key, val, .. } = node;
1382        unsafe { Some((key.assume_init(), val.assume_init())) }
1383    }
1384
1385    /// Removes and returns the key and value corresponding to the most recently
1386    /// used item or `None` if the cache is empty.
1387    ///
1388    /// # Example
1389    ///
1390    /// ```
1391    /// use lru::LruCache;
1392    /// use std::num::NonZeroUsize;
1393    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1394    ///
1395    /// cache.put(2, "a");
1396    /// cache.put(3, "b");
1397    /// cache.put(4, "c");
1398    /// cache.get(&3);
1399    ///
1400    /// assert_eq!(cache.pop_mru(), Some((3, "b")));
1401    /// assert_eq!(cache.pop_mru(), Some((4, "c")));
1402    /// assert_eq!(cache.pop_mru(), None);
1403    /// assert_eq!(cache.len(), 0);
1404    /// ```
1405    pub fn pop_mru(&mut self) -> Option<(K, V)> {
1406        let node = self.remove_first()?;
1407        // N.B.: Can't destructure directly because of https://github.com/rust-lang/rust/issues/28536
1408        let node = *node;
1409        let LruEntry { key, val, .. } = node;
1410        unsafe { Some((key.assume_init(), val.assume_init())) }
1411    }
1412
1413    /// Marks the key as the most recently used one. Returns true if the key
1414    /// was promoted because it exists in the cache, false otherwise.
1415    ///
1416    /// # Example
1417    ///
1418    /// ```
1419    /// use lru::LruCache;
1420    /// use std::num::NonZeroUsize;
1421    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1422    ///
1423    /// cache.put(1, "a");
1424    /// cache.put(2, "b");
1425    /// cache.put(3, "c");
1426    /// cache.get(&1);
1427    /// cache.get(&2);
1428    ///
1429    /// // If we do `pop_lru` now, we would pop 3.
1430    /// // assert_eq!(cache.pop_lru(), Some((3, "c")));
1431    ///
1432    /// // By promoting 3, we make sure it isn't popped.
1433    /// assert!(cache.promote(&3));
1434    /// assert_eq!(cache.pop_lru(), Some((1, "a")));
1435    ///
1436    /// // Promoting an entry that doesn't exist doesn't do anything.
1437    /// assert!(!cache.promote(&4));
1438    /// ```
1439    pub fn promote<Q>(&mut self, k: &Q) -> bool
1440    where
1441        K: Borrow<Q>,
1442        Q: Hash + Eq + ?Sized,
1443    {
1444        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
1445            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1446            self.detach(node_ptr);
1447            self.attach(node_ptr);
1448            true
1449        } else {
1450            false
1451        }
1452    }
1453
1454    /// Marks the key as the least recently used one. Returns true if the key was demoted
1455    /// because it exists in the cache, false otherwise.
1456    ///
1457    /// # Example
1458    ///
1459    /// ```
1460    /// use lru::LruCache;
1461    /// use std::num::NonZeroUsize;
1462    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1463    ///
1464    /// cache.put(1, "a");
1465    /// cache.put(2, "b");
1466    /// cache.put(3, "c");
1467    /// cache.get(&1);
1468    /// cache.get(&2);
1469    ///
1470    /// // If we do `pop_lru` now, we would pop 3.
1471    /// // assert_eq!(cache.pop_lru(), Some((3, "c")));
1472    ///
1473    /// // By demoting 1 and 2, we make sure those are popped first.
1474    /// assert!(cache.demote(&2));
1475    /// assert!(cache.demote(&1));
1476    /// assert_eq!(cache.pop_lru(), Some((1, "a")));
1477    /// assert_eq!(cache.pop_lru(), Some((2, "b")));
1478    ///
1479    /// // Demoting a key that doesn't exist does nothing.
1480    /// assert!(!cache.demote(&4));
1481    /// ```
1482    pub fn demote<Q>(&mut self, k: &Q) -> bool
1483    where
1484        K: Borrow<Q>,
1485        Q: Hash + Eq + ?Sized,
1486    {
1487        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
1488            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1489            self.detach(node_ptr);
1490            self.attach_last(node_ptr);
1491            true
1492        } else {
1493            false
1494        }
1495    }
1496
1497    /// Finds the first entry (in most-recently-used to least-recently-used iteration order)
1498    /// that matches the provided predicate and promotes it to the most recently used position.
1499    ///
1500    /// # Example
1501    ///
1502    /// ```
1503    /// use lru::LruCache;
1504    /// use std::num::NonZeroUsize;
1505    ///
1506    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1507    /// cache.put(1, "a");
1508    /// cache.put(2, "b");
1509    /// cache.put(3, "c");
1510    ///
1511    /// let found = cache.find_and_promote(|(_, value)| *value == "b");
1512    /// assert_eq!(found, Some((&2, &"b")));
1513    /// assert_eq!(cache.pop_lru(), Some((1, "a")));
1514    /// assert_eq!(cache.pop_lru(), Some((3, "c")));
1515    /// assert_eq!(cache.pop_lru(), Some((2, "b")));
1516    /// ```
1517    pub fn find_and_promote<F>(&mut self, mut predicate: F) -> Option<(&K, &V)>
1518    where
1519        F: FnMut((&K, &V)) -> bool,
1520    {
1521        let mut node = unsafe { (*self.head).next };
1522
1523        while !core::ptr::eq(node, self.tail) {
1524            let matches = {
1525                let key = unsafe { &*(*node).key.as_ptr() };
1526                let val = unsafe { &*(*node).val.as_ptr() };
1527                predicate((key, val))
1528            };
1529
1530            if matches {
1531                self.detach(node);
1532                self.attach(node);
1533                return Some(unsafe { (&*(*node).key.as_ptr(), &*(*node).val.as_ptr()) });
1534            }
1535
1536            unsafe { node = (*node).next };
1537        }
1538
1539        None
1540    }
1541
1542    /// Retains only the entries for which the predicate `f` returns `true`, removing the rest.
1543    ///
1544    /// The entries are visited in most-recently-used to least-recently-used order and the
1545    /// relative order of the entries that are kept is preserved.
1546    ///
1547    /// # Example
1548    ///
1549    /// ```
1550    /// use lru::LruCache;
1551    /// use std::num::NonZeroUsize;
1552    ///
1553    /// let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
1554    /// cache.put(1, "a");
1555    /// cache.put(2, "b");
1556    /// cache.put(3, "c");
1557    /// cache.put(4, "d");
1558    ///
1559    /// cache.retain(|k, _| k % 2 == 0);
1560    ///
1561    /// assert_eq!(cache.len(), 2);
1562    /// assert_eq!(cache.get(&2), Some(&"b"));
1563    /// assert_eq!(cache.get(&4), Some(&"d"));
1564    /// assert_eq!(cache.get(&1), None);
1565    /// assert_eq!(cache.get(&3), None);
1566    /// ```
1567    pub fn retain<F>(&mut self, mut f: F)
1568    where
1569        F: FnMut(&K, &mut V) -> bool,
1570    {
1571        let mut node = unsafe { (*self.head).next };
1572
1573        while !core::ptr::eq(node, self.tail) {
1574            // Grab the next node before we potentially free the current one.
1575            let next = unsafe { (*node).next };
1576
1577            let keep = {
1578                let key = unsafe { &*(*node).key.as_ptr() };
1579                let val = unsafe { &mut *(*node).val.as_mut_ptr() };
1580                f(key, val)
1581            };
1582
1583            if !keep {
1584                let key_ref = KeyRef {
1585                    k: unsafe { &*(*node).key.as_ptr() },
1586                };
1587                self.map.remove(&key_ref);
1588
1589                // Detach before dropping the key and value so that a panic in either
1590                // `Drop` cannot leave dangling pointers in the list.
1591                self.detach(node);
1592
1593                let mut old_node = unsafe { *Box::from_raw(node) };
1594                unsafe {
1595                    ptr::drop_in_place(old_node.key.as_mut_ptr());
1596                    ptr::drop_in_place(old_node.val.as_mut_ptr());
1597                }
1598            }
1599
1600            node = next;
1601        }
1602    }
1603
1604    /// Returns the number of key-value pairs that are currently in the the cache.
1605    ///
1606    /// # Example
1607    ///
1608    /// ```
1609    /// use lru::LruCache;
1610    /// use std::num::NonZeroUsize;
1611    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1612    /// assert_eq!(cache.len(), 0);
1613    ///
1614    /// cache.put(1, "a");
1615    /// assert_eq!(cache.len(), 1);
1616    ///
1617    /// cache.put(2, "b");
1618    /// assert_eq!(cache.len(), 2);
1619    ///
1620    /// cache.put(3, "c");
1621    /// assert_eq!(cache.len(), 2);
1622    /// ```
1623    pub fn len(&self) -> usize {
1624        self.map.len()
1625    }
1626
1627    /// Returns a bool indicating whether the cache is empty or not.
1628    ///
1629    /// # Example
1630    ///
1631    /// ```
1632    /// use lru::LruCache;
1633    /// use std::num::NonZeroUsize;
1634    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1635    /// assert!(cache.is_empty());
1636    ///
1637    /// cache.put(1, "a");
1638    /// assert!(!cache.is_empty());
1639    /// ```
1640    pub fn is_empty(&self) -> bool {
1641        self.map.len() == 0
1642    }
1643
1644    /// Returns the maximum number of key-value pairs the cache can hold.
1645    ///
1646    /// # Example
1647    ///
1648    /// ```
1649    /// use lru::LruCache;
1650    /// use std::num::NonZeroUsize;
1651    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
1652    /// assert_eq!(cache.cap().get(), 2);
1653    /// ```
1654    pub fn cap(&self) -> NonZeroUsize {
1655        self.cap
1656    }
1657
1658    /// Resizes the cache. If the new capacity is smaller than the size of the current
1659    /// cache any entries past the new capacity are discarded.
1660    ///
1661    /// # Example
1662    ///
1663    /// ```
1664    /// use lru::LruCache;
1665    /// use std::num::NonZeroUsize;
1666    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
1667    ///
1668    /// cache.put(1, "a");
1669    /// cache.put(2, "b");
1670    /// cache.resize(NonZeroUsize::new(4).unwrap());
1671    /// cache.put(3, "c");
1672    /// cache.put(4, "d");
1673    ///
1674    /// assert_eq!(cache.len(), 4);
1675    /// assert_eq!(cache.get(&1), Some(&"a"));
1676    /// assert_eq!(cache.get(&2), Some(&"b"));
1677    /// assert_eq!(cache.get(&3), Some(&"c"));
1678    /// assert_eq!(cache.get(&4), Some(&"d"));
1679    /// ```
1680    pub fn resize(&mut self, cap: NonZeroUsize) {
1681        // return early if capacity doesn't change
1682        if cap == self.cap {
1683            return;
1684        }
1685
1686        while self.map.len() > cap.get() {
1687            self.pop_lru();
1688        }
1689        self.map.shrink_to_fit();
1690
1691        self.cap = cap;
1692    }
1693
1694    /// Clears the contents of the cache.
1695    ///
1696    /// # Example
1697    ///
1698    /// ```
1699    /// use lru::LruCache;
1700    /// use std::num::NonZeroUsize;
1701    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
1702    /// assert_eq!(cache.len(), 0);
1703    ///
1704    /// cache.put(1, "a");
1705    /// assert_eq!(cache.len(), 1);
1706    ///
1707    /// cache.put(2, "b");
1708    /// assert_eq!(cache.len(), 2);
1709    ///
1710    /// cache.clear();
1711    /// assert_eq!(cache.len(), 0);
1712    /// ```
1713    pub fn clear(&mut self) {
1714        while self.pop_lru().is_some() {}
1715    }
1716
1717    /// An iterator visiting all entries in most-recently used order. The iterator element type is
1718    /// `(&K, &V)`.
1719    ///
1720    /// # Examples
1721    ///
1722    /// ```
1723    /// use lru::LruCache;
1724    /// use std::num::NonZeroUsize;
1725    ///
1726    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1727    /// cache.put("a", 1);
1728    /// cache.put("b", 2);
1729    /// cache.put("c", 3);
1730    ///
1731    /// for (key, val) in cache.iter() {
1732    ///     println!("key: {} val: {}", key, val);
1733    /// }
1734    /// ```
1735    pub fn iter(&self) -> Iter<'_, K, V> {
1736        Iter {
1737            len: self.len(),
1738            ptr: unsafe { (*self.head).next },
1739            end: unsafe { (*self.tail).prev },
1740            phantom: PhantomData,
1741        }
1742    }
1743
1744    /// An iterator visiting all entries in most-recently-used order, giving a mutable reference on
1745    /// V.  The iterator element type is `(&K, &mut V)`.
1746    ///
1747    /// # Examples
1748    ///
1749    /// ```
1750    /// use lru::LruCache;
1751    /// use std::num::NonZeroUsize;
1752    ///
1753    /// struct HddBlock {
1754    ///     dirty: bool,
1755    ///     data: [u8; 512]
1756    /// }
1757    ///
1758    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1759    /// cache.put(0, HddBlock { dirty: false, data: [0x00; 512]});
1760    /// cache.put(1, HddBlock { dirty: true,  data: [0x55; 512]});
1761    /// cache.put(2, HddBlock { dirty: true,  data: [0x77; 512]});
1762    ///
1763    /// // write dirty blocks to disk.
1764    /// for (block_id, block) in cache.iter_mut() {
1765    ///     if block.dirty {
1766    ///         // write block to disk
1767    ///         block.dirty = false
1768    ///     }
1769    /// }
1770    /// ```
1771    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
1772        IterMut {
1773            len: self.len(),
1774            ptr: unsafe { (*self.head).next },
1775            end: unsafe { (*self.tail).prev },
1776            phantom: PhantomData,
1777        }
1778    }
1779
1780    fn remove_first(&mut self) -> Option<Box<LruEntry<K, V>>> {
1781        let next;
1782        unsafe { next = (*self.head).next }
1783        if !core::ptr::eq(next, self.tail) {
1784            let old_key = KeyRef {
1785                k: unsafe { &(*(*(*self.head).next).key.as_ptr()) },
1786            };
1787            let old_node = self.map.remove(&old_key).unwrap();
1788            let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
1789            self.detach(node_ptr);
1790            unsafe { Some(Box::from_raw(node_ptr)) }
1791        } else {
1792            None
1793        }
1794    }
1795
1796    fn remove_last(&mut self) -> Option<Box<LruEntry<K, V>>> {
1797        let prev;
1798        unsafe { prev = (*self.tail).prev }
1799        if !core::ptr::eq(prev, self.head) {
1800            let old_key = KeyRef {
1801                k: unsafe { &(*(*(*self.tail).prev).key.as_ptr()) },
1802            };
1803            let old_node = self.map.remove(&old_key).unwrap();
1804            let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
1805            self.detach(node_ptr);
1806            unsafe { Some(Box::from_raw(node_ptr)) }
1807        } else {
1808            None
1809        }
1810    }
1811
1812    fn detach(&mut self, node: *mut LruEntry<K, V>) {
1813        unsafe {
1814            (*(*node).prev).next = (*node).next;
1815            (*(*node).next).prev = (*node).prev;
1816        }
1817    }
1818
1819    // Attaches `node` after the sigil `self.head` node.
1820    fn attach(&mut self, node: *mut LruEntry<K, V>) {
1821        unsafe {
1822            (*node).next = (*self.head).next;
1823            (*node).prev = self.head;
1824            (*self.head).next = node;
1825            (*(*node).next).prev = node;
1826        }
1827    }
1828
1829    // Attaches `node` before the sigil `self.tail` node.
1830    fn attach_last(&mut self, node: *mut LruEntry<K, V>) {
1831        unsafe {
1832            (*node).next = self.tail;
1833            (*node).prev = (*self.tail).prev;
1834            (*self.tail).prev = node;
1835            (*(*node).prev).next = node;
1836        }
1837    }
1838}
1839
1840impl<K, V, S> Drop for LruCache<K, V, S> {
1841    fn drop(&mut self) {
1842        self.map.drain().for_each(|(_, node)| unsafe {
1843            let mut node = *Box::from_raw(node.as_ptr());
1844            ptr::drop_in_place((node).key.as_mut_ptr());
1845            ptr::drop_in_place((node).val.as_mut_ptr());
1846        });
1847        // We rebox the head/tail, and because these are maybe-uninit
1848        // they do not have the absent k/v dropped.
1849
1850        let _head = unsafe { *Box::from_raw(self.head) };
1851        let _tail = unsafe { *Box::from_raw(self.tail) };
1852    }
1853}
1854
1855impl<'a, K: Hash + Eq, V, S: BuildHasher> IntoIterator for &'a LruCache<K, V, S> {
1856    type Item = (&'a K, &'a V);
1857    type IntoIter = Iter<'a, K, V>;
1858
1859    fn into_iter(self) -> Iter<'a, K, V> {
1860        self.iter()
1861    }
1862}
1863
1864impl<'a, K: Hash + Eq, V, S: BuildHasher> IntoIterator for &'a mut LruCache<K, V, S> {
1865    type Item = (&'a K, &'a mut V);
1866    type IntoIter = IterMut<'a, K, V>;
1867
1868    fn into_iter(self) -> IterMut<'a, K, V> {
1869        self.iter_mut()
1870    }
1871}
1872
1873// The compiler does not automatically derive Send and Sync for LruCache because it contains
1874// raw pointers. The raw pointers are safely encapsulated by LruCache though so we can
1875// implement Send and Sync for it below.
1876unsafe impl<K: Send, V: Send, S: Send> Send for LruCache<K, V, S> {}
1877unsafe impl<K: Sync, V: Sync, S: Sync> Sync for LruCache<K, V, S> {}
1878
1879impl<K: Hash + Eq, V, S: BuildHasher> fmt::Debug for LruCache<K, V, S> {
1880    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1881        f.debug_struct("LruCache")
1882            .field("len", &self.len())
1883            .field("cap", &self.cap())
1884            .finish()
1885    }
1886}
1887
1888/// An iterator over the entries of a `LruCache`.
1889///
1890/// This `struct` is created by the [`iter`] method on [`LruCache`][`LruCache`]. See its
1891/// documentation for more.
1892///
1893/// [`iter`]: struct.LruCache.html#method.iter
1894/// [`LruCache`]: struct.LruCache.html
1895pub struct Iter<'a, K: 'a, V: 'a> {
1896    len: usize,
1897
1898    ptr: *const LruEntry<K, V>,
1899    end: *const LruEntry<K, V>,
1900
1901    phantom: PhantomData<&'a K>,
1902}
1903
1904impl<'a, K, V> Iterator for Iter<'a, K, V> {
1905    type Item = (&'a K, &'a V);
1906
1907    fn next(&mut self) -> Option<(&'a K, &'a V)> {
1908        if self.len == 0 {
1909            return None;
1910        }
1911
1912        let key = unsafe { &(*(*self.ptr).key.as_ptr()) as &K };
1913        let val = unsafe { &(*(*self.ptr).val.as_ptr()) as &V };
1914
1915        self.len -= 1;
1916        self.ptr = unsafe { (*self.ptr).next };
1917
1918        Some((key, val))
1919    }
1920
1921    fn size_hint(&self) -> (usize, Option<usize>) {
1922        (self.len, Some(self.len))
1923    }
1924
1925    fn count(self) -> usize {
1926        self.len
1927    }
1928}
1929
1930impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
1931    fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
1932        if self.len == 0 {
1933            return None;
1934        }
1935
1936        let key = unsafe { &(*(*self.end).key.as_ptr()) as &K };
1937        let val = unsafe { &(*(*self.end).val.as_ptr()) as &V };
1938
1939        self.len -= 1;
1940        self.end = unsafe { (*self.end).prev };
1941
1942        Some((key, val))
1943    }
1944}
1945
1946impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {}
1947impl<'a, K, V> FusedIterator for Iter<'a, K, V> {}
1948
1949impl<'a, K, V> Clone for Iter<'a, K, V> {
1950    fn clone(&self) -> Iter<'a, K, V> {
1951        Iter {
1952            len: self.len,
1953            ptr: self.ptr,
1954            end: self.end,
1955            phantom: PhantomData,
1956        }
1957    }
1958}
1959
1960// The compiler does not automatically derive Send and Sync for Iter because it contains
1961// raw pointers.
1962unsafe impl<'a, K: Send, V: Send> Send for Iter<'a, K, V> {}
1963unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
1964
1965/// An iterator over mutables entries of a `LruCache`.
1966///
1967/// This `struct` is created by the [`iter_mut`] method on [`LruCache`][`LruCache`]. See its
1968/// documentation for more.
1969///
1970/// [`iter_mut`]: struct.LruCache.html#method.iter_mut
1971/// [`LruCache`]: struct.LruCache.html
1972pub struct IterMut<'a, K: 'a, V: 'a> {
1973    len: usize,
1974
1975    ptr: *mut LruEntry<K, V>,
1976    end: *mut LruEntry<K, V>,
1977
1978    phantom: PhantomData<&'a K>,
1979}
1980
1981impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1982    type Item = (&'a K, &'a mut V);
1983
1984    fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
1985        if self.len == 0 {
1986            return None;
1987        }
1988
1989        let key = unsafe { &(*(*self.ptr).key.as_ptr()) as &K };
1990        let val = unsafe { &mut (*(*self.ptr).val.as_mut_ptr()) as &mut V };
1991
1992        self.len -= 1;
1993        self.ptr = unsafe { (*self.ptr).next };
1994
1995        Some((key, val))
1996    }
1997
1998    fn size_hint(&self) -> (usize, Option<usize>) {
1999        (self.len, Some(self.len))
2000    }
2001
2002    fn count(self) -> usize {
2003        self.len
2004    }
2005}
2006
2007impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> {
2008    fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
2009        if self.len == 0 {
2010            return None;
2011        }
2012
2013        let key = unsafe { &(*(*self.end).key.as_ptr()) as &K };
2014        let val = unsafe { &mut (*(*self.end).val.as_mut_ptr()) as &mut V };
2015
2016        self.len -= 1;
2017        self.end = unsafe { (*self.end).prev };
2018
2019        Some((key, val))
2020    }
2021}
2022
2023impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {}
2024impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}
2025
2026// The compiler does not automatically derive Send and Sync for Iter because it contains
2027// raw pointers.
2028unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {}
2029unsafe impl<'a, K: Sync, V: Sync> Sync for IterMut<'a, K, V> {}
2030
2031/// An iterator that moves out of a `LruCache`.
2032///
2033/// This `struct` is created by the [`into_iter`] method on [`LruCache`][`LruCache`]. See its
2034/// documentation for more.
2035///
2036/// [`into_iter`]: struct.LruCache.html#method.into_iter
2037/// [`LruCache`]: struct.LruCache.html
2038pub struct IntoIter<K, V>
2039where
2040    K: Hash + Eq,
2041{
2042    cache: LruCache<K, V>,
2043}
2044
2045impl<K, V> Iterator for IntoIter<K, V>
2046where
2047    K: Hash + Eq,
2048{
2049    type Item = (K, V);
2050
2051    fn next(&mut self) -> Option<(K, V)> {
2052        self.cache.pop_lru()
2053    }
2054
2055    fn size_hint(&self) -> (usize, Option<usize>) {
2056        let len = self.cache.len();
2057        (len, Some(len))
2058    }
2059
2060    fn count(self) -> usize {
2061        self.cache.len()
2062    }
2063}
2064
2065impl<K, V> ExactSizeIterator for IntoIter<K, V> where K: Hash + Eq {}
2066impl<K, V> FusedIterator for IntoIter<K, V> where K: Hash + Eq {}
2067
2068impl<K: Hash + Eq, V> IntoIterator for LruCache<K, V> {
2069    type Item = (K, V);
2070    type IntoIter = IntoIter<K, V>;
2071
2072    fn into_iter(self) -> IntoIter<K, V> {
2073        IntoIter { cache: self }
2074    }
2075}
2076
2077#[cfg(test)]
2078mod tests {
2079    use super::LruCache;
2080    use core::{fmt::Debug, num::NonZeroUsize};
2081    use scoped_threadpool::Pool;
2082    use std::rc::Rc;
2083    use std::sync::atomic::{AtomicUsize, Ordering};
2084
2085    fn assert_opt_eq<V: PartialEq + Debug>(opt: Option<&V>, v: V) {
2086        assert!(opt.is_some());
2087        assert_eq!(opt.unwrap(), &v);
2088    }
2089
2090    fn assert_opt_eq_mut<V: PartialEq + Debug>(opt: Option<&mut V>, v: V) {
2091        assert!(opt.is_some());
2092        assert_eq!(opt.unwrap(), &v);
2093    }
2094
2095    fn assert_opt_eq_tuple<K: PartialEq + Debug, V: PartialEq + Debug>(
2096        opt: Option<(&K, &V)>,
2097        kv: (K, V),
2098    ) {
2099        assert!(opt.is_some());
2100        let res = opt.unwrap();
2101        assert_eq!(res.0, &kv.0);
2102        assert_eq!(res.1, &kv.1);
2103    }
2104
2105    fn assert_opt_eq_mut_tuple<K: PartialEq + Debug, V: PartialEq + Debug>(
2106        opt: Option<(&K, &mut V)>,
2107        kv: (K, V),
2108    ) {
2109        assert!(opt.is_some());
2110        let res = opt.unwrap();
2111        assert_eq!(res.0, &kv.0);
2112        assert_eq!(res.1, &kv.1);
2113    }
2114
2115    #[test]
2116    fn test_unbounded() {
2117        let mut cache = LruCache::unbounded();
2118        for i in 0..13370 {
2119            cache.put(i, ());
2120        }
2121        assert_eq!(cache.len(), 13370);
2122    }
2123
2124    #[test]
2125    #[cfg(feature = "hashbrown")]
2126    fn test_with_hasher() {
2127        use core::num::NonZeroUsize;
2128
2129        use hashbrown::DefaultHashBuilder;
2130
2131        let s = DefaultHashBuilder::default();
2132        let mut cache = LruCache::with_hasher(NonZeroUsize::new(16).unwrap(), s);
2133
2134        for i in 0..13370 {
2135            cache.put(i, ());
2136        }
2137        assert_eq!(cache.len(), 16);
2138    }
2139
2140    #[test]
2141    fn test_put_and_get() {
2142        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2143        assert!(cache.is_empty());
2144
2145        assert_eq!(cache.put("apple", "red"), None);
2146        assert_eq!(cache.put("banana", "yellow"), None);
2147
2148        assert_eq!(cache.cap().get(), 2);
2149        assert_eq!(cache.len(), 2);
2150        assert!(!cache.is_empty());
2151        assert_opt_eq(cache.get(&"apple"), "red");
2152        assert_opt_eq(cache.get(&"banana"), "yellow");
2153    }
2154
2155    #[test]
2156    fn test_put_and_get_or_insert() {
2157        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2158        assert!(cache.is_empty());
2159
2160        assert_eq!(cache.put("apple", "red"), None);
2161        assert_eq!(cache.put("banana", "yellow"), None);
2162
2163        assert_eq!(cache.cap().get(), 2);
2164        assert_eq!(cache.len(), 2);
2165        assert!(!cache.is_empty());
2166        assert_eq!(cache.get_or_insert("apple", || "orange"), &"red");
2167        assert_eq!(cache.get_or_insert("banana", || "orange"), &"yellow");
2168        assert_eq!(cache.get_or_insert("lemon", || "orange"), &"orange");
2169        assert_eq!(cache.get_or_insert("lemon", || "red"), &"orange");
2170    }
2171
2172    #[test]
2173    fn test_put_and_get_or_insert_with_key() {
2174        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2175        assert!(cache.is_empty());
2176
2177        assert_eq!(cache.put("apple", 2), None);
2178        assert_eq!(cache.put("banana", 8), None);
2179
2180        assert_eq!(cache.cap().get(), 2);
2181        assert_eq!(cache.len(), 2);
2182        assert!(!cache.is_empty());
2183        assert_eq!(cache.get_or_insert_with_key("apple", |k| k.len()), &2);
2184        assert_eq!(cache.get_or_insert_with_key("banana", |k| k.len()), &8);
2185        assert_eq!(cache.get_or_insert_with_key("lemon", |k| k.len()), &5);
2186        assert_eq!(cache.get_or_insert_with_key("lemon", |k| k.len() + 3), &5);
2187    }
2188
2189    #[test]
2190    fn test_get_or_insert_ref() {
2191        use alloc::borrow::ToOwned;
2192        use alloc::string::String;
2193
2194        let key1 = Rc::new("1".to_owned());
2195        let key2 = Rc::new("2".to_owned());
2196        let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
2197        assert!(cache.is_empty());
2198        assert_eq!(cache.get_or_insert_ref(&key1, || "One".to_owned()), "One");
2199        assert_eq!(cache.get_or_insert_ref(&key2, || "Two".to_owned()), "Two");
2200        assert_eq!(cache.len(), 2);
2201        assert!(!cache.is_empty());
2202        assert_eq!(
2203            cache.get_or_insert_ref(&key2, || "Not two".to_owned()),
2204            "Two"
2205        );
2206        assert_eq!(
2207            cache.get_or_insert_ref(&key2, || "Again not two".to_owned()),
2208            "Two"
2209        );
2210        assert_eq!(Rc::strong_count(&key1), 2);
2211        assert_eq!(Rc::strong_count(&key2), 2);
2212    }
2213
2214    #[test]
2215    fn test_try_get_or_insert() {
2216        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2217
2218        assert_eq!(
2219            cache.try_get_or_insert::<_, &str>("apple", || Ok("red")),
2220            Ok(&"red")
2221        );
2222        assert_eq!(
2223            cache.try_get_or_insert::<_, &str>("apple", || Err("failed")),
2224            Ok(&"red")
2225        );
2226        assert_eq!(
2227            cache.try_get_or_insert::<_, &str>("banana", || Ok("orange")),
2228            Ok(&"orange")
2229        );
2230        assert_eq!(
2231            cache.try_get_or_insert::<_, &str>("lemon", || Err("failed")),
2232            Err("failed")
2233        );
2234        assert_eq!(
2235            cache.try_get_or_insert::<_, &str>("banana", || Err("failed")),
2236            Ok(&"orange")
2237        );
2238    }
2239
2240    #[test]
2241    fn test_try_get_or_insert_with_key() {
2242        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2243
2244        assert_eq!(
2245            cache.try_get_or_insert_with_key::<_, &str>("apple", |k| Ok(k.len())),
2246            Ok(&5)
2247        );
2248        assert_eq!(
2249            cache.try_get_or_insert_with_key::<_, &str>("apple", |_| Err("failed")),
2250            Ok(&5)
2251        );
2252        assert_eq!(
2253            cache.try_get_or_insert_with_key::<_, &str>("banana", |k| Ok(k.len())),
2254            Ok(&6)
2255        );
2256        assert_eq!(
2257            cache.try_get_or_insert_with_key::<_, &str>("lemon", |_| Err("failed")),
2258            Err("failed")
2259        );
2260        assert_eq!(
2261            cache.try_get_or_insert_with_key::<_, &str>("banana", |_| Err("failed")),
2262            Ok(&6)
2263        );
2264    }
2265
2266    #[test]
2267    fn test_try_get_or_insert_ref() {
2268        use alloc::borrow::ToOwned;
2269        use alloc::string::String;
2270
2271        let key1 = Rc::new("1".to_owned());
2272        let key2 = Rc::new("2".to_owned());
2273        let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
2274        let f = || -> Result<String, ()> { Err(()) };
2275        let a = || -> Result<String, ()> { Ok("One".to_owned()) };
2276        let b = || -> Result<String, ()> { Ok("Two".to_owned()) };
2277        assert_eq!(cache.try_get_or_insert_ref(&key1, a), Ok(&"One".to_owned()));
2278        assert_eq!(cache.try_get_or_insert_ref(&key2, f), Err(()));
2279        assert_eq!(cache.try_get_or_insert_ref(&key2, b), Ok(&"Two".to_owned()));
2280        assert_eq!(cache.try_get_or_insert_ref(&key2, a), Ok(&"Two".to_owned()));
2281        assert_eq!(cache.len(), 2);
2282        assert_eq!(Rc::strong_count(&key1), 2);
2283        assert_eq!(Rc::strong_count(&key2), 2);
2284    }
2285
2286    #[test]
2287    fn test_put_and_get_or_insert_mut() {
2288        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2289        assert!(cache.is_empty());
2290
2291        assert_eq!(cache.put("apple", "red"), None);
2292        assert_eq!(cache.put("banana", "yellow"), None);
2293
2294        assert_eq!(cache.cap().get(), 2);
2295        assert_eq!(cache.len(), 2);
2296
2297        let v = cache.get_or_insert_mut("apple", || "orange");
2298        assert_eq!(v, &"red");
2299        *v = "blue";
2300
2301        assert_eq!(cache.get_or_insert_mut("apple", || "orange"), &"blue");
2302        assert_eq!(cache.get_or_insert_mut("banana", || "orange"), &"yellow");
2303        assert_eq!(cache.get_or_insert_mut("lemon", || "orange"), &"orange");
2304        assert_eq!(cache.get_or_insert_mut("lemon", || "red"), &"orange");
2305    }
2306
2307    #[test]
2308    fn test_put_and_get_or_insert_mut_with_key() {
2309        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2310        assert!(cache.is_empty());
2311
2312        assert_eq!(cache.put("apple", 2), None);
2313        assert_eq!(cache.put("banana", 8), None);
2314
2315        assert_eq!(cache.cap().get(), 2);
2316        assert_eq!(cache.len(), 2);
2317
2318        let v = cache.get_or_insert_mut_with_key("apple", |k| k.len());
2319        assert_eq!(v, &2);
2320        *v = 4;
2321
2322        assert_eq!(cache.get_or_insert_mut_with_key("apple", |k| k.len()), &4);
2323        assert_eq!(cache.get_or_insert_mut_with_key("banana", |k| k.len()), &8);
2324        assert_eq!(cache.get_or_insert_mut_with_key("lemon", |k| k.len()), &5);
2325        assert_eq!(cache.get_or_insert_mut_with_key("lemon", |_| 0), &5);
2326    }
2327
2328    #[test]
2329    fn test_get_or_insert_mut_ref() {
2330        use alloc::borrow::ToOwned;
2331        use alloc::string::String;
2332
2333        let key1 = Rc::new("1".to_owned());
2334        let key2 = Rc::new("2".to_owned());
2335        let mut cache = LruCache::<Rc<String>, &'static str>::new(NonZeroUsize::new(2).unwrap());
2336        assert_eq!(cache.get_or_insert_mut_ref(&key1, || "One"), &mut "One");
2337        let v = cache.get_or_insert_mut_ref(&key2, || "Two");
2338        *v = "New two";
2339        assert_eq!(cache.get_or_insert_mut_ref(&key2, || "Two"), &mut "New two");
2340        assert_eq!(Rc::strong_count(&key1), 2);
2341        assert_eq!(Rc::strong_count(&key2), 2);
2342    }
2343
2344    #[test]
2345    fn test_try_get_or_insert_mut() {
2346        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2347
2348        cache.put(1, "a");
2349        cache.put(2, "b");
2350        cache.put(2, "c");
2351
2352        let f = || -> Result<&str, &str> { Err("failed") };
2353        let a = || -> Result<&str, &str> { Ok("a") };
2354        let b = || -> Result<&str, &str> { Ok("b") };
2355        if let Ok(v) = cache.try_get_or_insert_mut(2, a) {
2356            *v = "d";
2357        }
2358        assert_eq!(cache.try_get_or_insert_mut(2, a), Ok(&mut "d"));
2359        assert_eq!(cache.try_get_or_insert_mut(3, f), Err("failed"));
2360        assert_eq!(cache.try_get_or_insert_mut(4, b), Ok(&mut "b"));
2361        assert_eq!(cache.try_get_or_insert_mut(4, a), Ok(&mut "b"));
2362    }
2363
2364    #[test]
2365    fn test_try_get_or_insert_mut_with_key() {
2366        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2367
2368        cache.put("One", 1);
2369        cache.put("Two", 2);
2370        cache.put("Two", 3);
2371
2372        let f = |_: &&str| -> Result<usize, &str> { Err("failed") };
2373        let len = |k: &&str| -> Result<usize, &str> { Ok(k.len()) };
2374        let zero = |_: &&str| -> Result<usize, &str> { Ok(0) };
2375        if let Ok(v) = cache.try_get_or_insert_mut_with_key("Two", f) {
2376            *v = 6;
2377        }
2378        assert_eq!(cache.try_get_or_insert_mut_with_key("Two", len), Ok(&mut 6));
2379        assert_eq!(
2380            cache.try_get_or_insert_mut_with_key("Three", f),
2381            Err("failed")
2382        );
2383        assert_eq!(
2384            cache.try_get_or_insert_mut_with_key("Four", len),
2385            Ok(&mut 4)
2386        );
2387        assert_eq!(
2388            cache.try_get_or_insert_mut_with_key("Four", zero),
2389            Ok(&mut 4)
2390        );
2391    }
2392
2393    #[test]
2394    fn test_try_get_or_insert_mut_ref() {
2395        use alloc::borrow::ToOwned;
2396        use alloc::string::String;
2397
2398        let key1 = Rc::new("1".to_owned());
2399        let key2 = Rc::new("2".to_owned());
2400        let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
2401        let f = || -> Result<String, ()> { Err(()) };
2402        let a = || -> Result<String, ()> { Ok("One".to_owned()) };
2403        let b = || -> Result<String, ()> { Ok("Two".to_owned()) };
2404        assert_eq!(
2405            cache.try_get_or_insert_mut_ref(&key1, a),
2406            Ok(&mut "One".to_owned())
2407        );
2408        assert_eq!(cache.try_get_or_insert_mut_ref(&key2, f), Err(()));
2409        if let Ok(v) = cache.try_get_or_insert_mut_ref(&key2, b) {
2410            assert_eq!(v, &mut "Two");
2411            *v = "New two".to_owned();
2412        }
2413        assert_eq!(
2414            cache.try_get_or_insert_mut_ref(&key2, a),
2415            Ok(&mut "New two".to_owned())
2416        );
2417        assert_eq!(Rc::strong_count(&key1), 2);
2418        assert_eq!(Rc::strong_count(&key2), 2);
2419    }
2420
2421    #[test]
2422    fn test_put_and_get_mut() {
2423        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2424
2425        cache.put("apple", "red");
2426        cache.put("banana", "yellow");
2427
2428        assert_eq!(cache.cap().get(), 2);
2429        assert_eq!(cache.len(), 2);
2430        assert_opt_eq_mut(cache.get_mut(&"apple"), "red");
2431        assert_opt_eq_mut(cache.get_mut(&"banana"), "yellow");
2432    }
2433
2434    #[test]
2435    fn test_get_mut_and_update() {
2436        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2437
2438        cache.put("apple", 1);
2439        cache.put("banana", 3);
2440
2441        {
2442            let v = cache.get_mut(&"apple").unwrap();
2443            *v = 4;
2444        }
2445
2446        assert_eq!(cache.cap().get(), 2);
2447        assert_eq!(cache.len(), 2);
2448        assert_opt_eq_mut(cache.get_mut(&"apple"), 4);
2449        assert_opt_eq_mut(cache.get_mut(&"banana"), 3);
2450    }
2451
2452    #[test]
2453    fn test_put_update() {
2454        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2455
2456        assert_eq!(cache.put("apple", "red"), None);
2457        assert_eq!(cache.put("apple", "green"), Some("red"));
2458
2459        assert_eq!(cache.len(), 1);
2460        assert_opt_eq(cache.get(&"apple"), "green");
2461    }
2462
2463    #[test]
2464    fn test_put_removes_oldest() {
2465        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2466
2467        assert_eq!(cache.put("apple", "red"), None);
2468        assert_eq!(cache.put("banana", "yellow"), None);
2469        assert_eq!(cache.put("pear", "green"), None);
2470
2471        assert!(cache.get(&"apple").is_none());
2472        assert_opt_eq(cache.get(&"banana"), "yellow");
2473        assert_opt_eq(cache.get(&"pear"), "green");
2474
2475        // Even though we inserted "apple" into the cache earlier it has since been removed from
2476        // the cache so there is no current value for `put` to return.
2477        assert_eq!(cache.put("apple", "green"), None);
2478        assert_eq!(cache.put("tomato", "red"), None);
2479
2480        assert!(cache.get(&"pear").is_none());
2481        assert_opt_eq(cache.get(&"apple"), "green");
2482        assert_opt_eq(cache.get(&"tomato"), "red");
2483    }
2484
2485    #[test]
2486    fn test_peek() {
2487        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2488
2489        cache.put("apple", "red");
2490        cache.put("banana", "yellow");
2491
2492        assert_opt_eq(cache.peek(&"banana"), "yellow");
2493        assert_opt_eq(cache.peek(&"apple"), "red");
2494
2495        cache.put("pear", "green");
2496
2497        assert!(cache.peek(&"apple").is_none());
2498        assert_opt_eq(cache.peek(&"banana"), "yellow");
2499        assert_opt_eq(cache.peek(&"pear"), "green");
2500    }
2501
2502    #[test]
2503    fn test_peek_mut() {
2504        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2505
2506        cache.put("apple", "red");
2507        cache.put("banana", "yellow");
2508
2509        assert_opt_eq_mut(cache.peek_mut(&"banana"), "yellow");
2510        assert_opt_eq_mut(cache.peek_mut(&"apple"), "red");
2511        assert!(cache.peek_mut(&"pear").is_none());
2512
2513        cache.put("pear", "green");
2514
2515        assert!(cache.peek_mut(&"apple").is_none());
2516        assert_opt_eq_mut(cache.peek_mut(&"banana"), "yellow");
2517        assert_opt_eq_mut(cache.peek_mut(&"pear"), "green");
2518
2519        {
2520            let v = cache.peek_mut(&"banana").unwrap();
2521            *v = "green";
2522        }
2523
2524        assert_opt_eq_mut(cache.peek_mut(&"banana"), "green");
2525    }
2526
2527    #[test]
2528    fn test_peek_lru() {
2529        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2530
2531        assert!(cache.peek_lru().is_none());
2532
2533        cache.put("apple", "red");
2534        cache.put("banana", "yellow");
2535        assert_opt_eq_tuple(cache.peek_lru(), ("apple", "red"));
2536
2537        cache.get(&"apple");
2538        assert_opt_eq_tuple(cache.peek_lru(), ("banana", "yellow"));
2539
2540        cache.clear();
2541        assert!(cache.peek_lru().is_none());
2542    }
2543
2544    #[test]
2545    fn test_peek_mru() {
2546        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2547
2548        assert!(cache.peek_mru().is_none());
2549
2550        cache.put("apple", "red");
2551        cache.put("banana", "yellow");
2552        assert_opt_eq_tuple(cache.peek_mru(), ("banana", "yellow"));
2553
2554        cache.get(&"apple");
2555        assert_opt_eq_tuple(cache.peek_mru(), ("apple", "red"));
2556
2557        cache.clear();
2558        assert!(cache.peek_mru().is_none());
2559    }
2560
2561    #[test]
2562    fn test_contains() {
2563        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2564
2565        cache.put("apple", "red");
2566        cache.put("banana", "yellow");
2567        cache.put("pear", "green");
2568
2569        assert!(!cache.contains(&"apple"));
2570        assert!(cache.contains(&"banana"));
2571        assert!(cache.contains(&"pear"));
2572    }
2573
2574    #[test]
2575    fn test_pop() {
2576        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2577
2578        cache.put("apple", "red");
2579        cache.put("banana", "yellow");
2580
2581        assert_eq!(cache.len(), 2);
2582        assert_opt_eq(cache.get(&"apple"), "red");
2583        assert_opt_eq(cache.get(&"banana"), "yellow");
2584
2585        let popped = cache.pop(&"apple");
2586        assert!(popped.is_some());
2587        assert_eq!(popped.unwrap(), "red");
2588        assert_eq!(cache.len(), 1);
2589        assert!(cache.get(&"apple").is_none());
2590        assert_opt_eq(cache.get(&"banana"), "yellow");
2591    }
2592
2593    #[test]
2594    fn test_pop_entry() {
2595        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2596        cache.put("apple", "red");
2597        cache.put("banana", "yellow");
2598
2599        assert_eq!(cache.len(), 2);
2600        assert_opt_eq(cache.get(&"apple"), "red");
2601        assert_opt_eq(cache.get(&"banana"), "yellow");
2602
2603        let popped = cache.pop_entry(&"apple");
2604        assert!(popped.is_some());
2605        assert_eq!(popped.unwrap(), ("apple", "red"));
2606        assert_eq!(cache.len(), 1);
2607        assert!(cache.get(&"apple").is_none());
2608        assert_opt_eq(cache.get(&"banana"), "yellow");
2609    }
2610
2611    #[test]
2612    fn test_pop_lru() {
2613        let mut cache = LruCache::new(NonZeroUsize::new(200).unwrap());
2614
2615        for i in 0..75 {
2616            cache.put(i, "A");
2617        }
2618        for i in 0..75 {
2619            cache.put(i + 100, "B");
2620        }
2621        for i in 0..75 {
2622            cache.put(i + 200, "C");
2623        }
2624        assert_eq!(cache.len(), 200);
2625
2626        for i in 0..75 {
2627            assert_opt_eq(cache.get(&(74 - i + 100)), "B");
2628        }
2629        assert_opt_eq(cache.get(&25), "A");
2630
2631        for i in 26..75 {
2632            assert_eq!(cache.pop_lru(), Some((i, "A")));
2633        }
2634        for i in 0..75 {
2635            assert_eq!(cache.pop_lru(), Some((i + 200, "C")));
2636        }
2637        for i in 0..75 {
2638            assert_eq!(cache.pop_lru(), Some((74 - i + 100, "B")));
2639        }
2640        assert_eq!(cache.pop_lru(), Some((25, "A")));
2641        for _ in 0..50 {
2642            assert_eq!(cache.pop_lru(), None);
2643        }
2644    }
2645
2646    #[test]
2647    fn test_pop_mru() {
2648        let mut cache = LruCache::new(NonZeroUsize::new(200).unwrap());
2649
2650        for i in 0..75 {
2651            cache.put(i, "A");
2652        }
2653        for i in 0..75 {
2654            cache.put(i + 100, "B");
2655        }
2656        for i in 0..75 {
2657            cache.put(i + 200, "C");
2658        }
2659        assert_eq!(cache.len(), 200);
2660
2661        for i in 0..75 {
2662            assert_opt_eq(cache.get(&(74 - i + 100)), "B");
2663        }
2664        assert_opt_eq(cache.get(&25), "A");
2665
2666        assert_eq!(cache.pop_mru(), Some((25, "A")));
2667        for i in 0..75 {
2668            assert_eq!(cache.pop_mru(), Some((i + 100, "B")));
2669        }
2670        for i in 0..75 {
2671            assert_eq!(cache.pop_mru(), Some((74 - i + 200, "C")));
2672        }
2673        for i in (26..75).into_iter().rev() {
2674            assert_eq!(cache.pop_mru(), Some((i, "A")));
2675        }
2676        for _ in 0..50 {
2677            assert_eq!(cache.pop_mru(), None);
2678        }
2679    }
2680
2681    #[test]
2682    fn test_clear() {
2683        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2684
2685        cache.put("apple", "red");
2686        cache.put("banana", "yellow");
2687
2688        assert_eq!(cache.len(), 2);
2689        assert_opt_eq(cache.get(&"apple"), "red");
2690        assert_opt_eq(cache.get(&"banana"), "yellow");
2691
2692        cache.clear();
2693        assert_eq!(cache.len(), 0);
2694    }
2695
2696    #[test]
2697    fn test_resize_larger() {
2698        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2699
2700        cache.put(1, "a");
2701        cache.put(2, "b");
2702        cache.resize(NonZeroUsize::new(4).unwrap());
2703        cache.put(3, "c");
2704        cache.put(4, "d");
2705
2706        assert_eq!(cache.len(), 4);
2707        assert_eq!(cache.get(&1), Some(&"a"));
2708        assert_eq!(cache.get(&2), Some(&"b"));
2709        assert_eq!(cache.get(&3), Some(&"c"));
2710        assert_eq!(cache.get(&4), Some(&"d"));
2711    }
2712
2713    #[test]
2714    fn test_resize_smaller() {
2715        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2716
2717        cache.put(1, "a");
2718        cache.put(2, "b");
2719        cache.put(3, "c");
2720        cache.put(4, "d");
2721
2722        cache.resize(NonZeroUsize::new(2).unwrap());
2723
2724        assert_eq!(cache.len(), 2);
2725        assert!(cache.get(&1).is_none());
2726        assert!(cache.get(&2).is_none());
2727        assert_eq!(cache.get(&3), Some(&"c"));
2728        assert_eq!(cache.get(&4), Some(&"d"));
2729    }
2730
2731    #[test]
2732    fn test_send() {
2733        use std::thread;
2734
2735        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2736        cache.put(1, "a");
2737
2738        let handle = thread::spawn(move || {
2739            assert_eq!(cache.get(&1), Some(&"a"));
2740        });
2741
2742        assert!(handle.join().is_ok());
2743    }
2744
2745    #[test]
2746    fn test_multiple_threads() {
2747        let mut pool = Pool::new(1);
2748        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2749        cache.put(1, "a");
2750
2751        let cache_ref = &cache;
2752        pool.scoped(|scoped| {
2753            scoped.execute(move || {
2754                assert_eq!(cache_ref.peek(&1), Some(&"a"));
2755            });
2756        });
2757
2758        assert_eq!((cache_ref).peek(&1), Some(&"a"));
2759    }
2760
2761    #[test]
2762    fn test_iter_forwards() {
2763        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2764        cache.put("a", 1);
2765        cache.put("b", 2);
2766        cache.put("c", 3);
2767
2768        {
2769            // iter const
2770            let mut iter = cache.iter();
2771            assert_eq!(iter.len(), 3);
2772            assert_opt_eq_tuple(iter.next(), ("c", 3));
2773
2774            assert_eq!(iter.len(), 2);
2775            assert_opt_eq_tuple(iter.next(), ("b", 2));
2776
2777            assert_eq!(iter.len(), 1);
2778            assert_opt_eq_tuple(iter.next(), ("a", 1));
2779
2780            assert_eq!(iter.len(), 0);
2781            assert_eq!(iter.next(), None);
2782        }
2783        {
2784            // iter mut
2785            let mut iter = cache.iter_mut();
2786            assert_eq!(iter.len(), 3);
2787            assert_opt_eq_mut_tuple(iter.next(), ("c", 3));
2788
2789            assert_eq!(iter.len(), 2);
2790            assert_opt_eq_mut_tuple(iter.next(), ("b", 2));
2791
2792            assert_eq!(iter.len(), 1);
2793            assert_opt_eq_mut_tuple(iter.next(), ("a", 1));
2794
2795            assert_eq!(iter.len(), 0);
2796            assert_eq!(iter.next(), None);
2797        }
2798    }
2799
2800    #[test]
2801    fn test_iter_backwards() {
2802        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2803        cache.put("a", 1);
2804        cache.put("b", 2);
2805        cache.put("c", 3);
2806
2807        {
2808            // iter const
2809            let mut iter = cache.iter();
2810            assert_eq!(iter.len(), 3);
2811            assert_opt_eq_tuple(iter.next_back(), ("a", 1));
2812
2813            assert_eq!(iter.len(), 2);
2814            assert_opt_eq_tuple(iter.next_back(), ("b", 2));
2815
2816            assert_eq!(iter.len(), 1);
2817            assert_opt_eq_tuple(iter.next_back(), ("c", 3));
2818
2819            assert_eq!(iter.len(), 0);
2820            assert_eq!(iter.next_back(), None);
2821        }
2822
2823        {
2824            // iter mut
2825            let mut iter = cache.iter_mut();
2826            assert_eq!(iter.len(), 3);
2827            assert_opt_eq_mut_tuple(iter.next_back(), ("a", 1));
2828
2829            assert_eq!(iter.len(), 2);
2830            assert_opt_eq_mut_tuple(iter.next_back(), ("b", 2));
2831
2832            assert_eq!(iter.len(), 1);
2833            assert_opt_eq_mut_tuple(iter.next_back(), ("c", 3));
2834
2835            assert_eq!(iter.len(), 0);
2836            assert_eq!(iter.next_back(), None);
2837        }
2838    }
2839
2840    #[test]
2841    fn test_iter_forwards_and_backwards() {
2842        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2843        cache.put("a", 1);
2844        cache.put("b", 2);
2845        cache.put("c", 3);
2846
2847        {
2848            // iter const
2849            let mut iter = cache.iter();
2850            assert_eq!(iter.len(), 3);
2851            assert_opt_eq_tuple(iter.next(), ("c", 3));
2852
2853            assert_eq!(iter.len(), 2);
2854            assert_opt_eq_tuple(iter.next_back(), ("a", 1));
2855
2856            assert_eq!(iter.len(), 1);
2857            assert_opt_eq_tuple(iter.next(), ("b", 2));
2858
2859            assert_eq!(iter.len(), 0);
2860            assert_eq!(iter.next_back(), None);
2861        }
2862        {
2863            // iter mut
2864            let mut iter = cache.iter_mut();
2865            assert_eq!(iter.len(), 3);
2866            assert_opt_eq_mut_tuple(iter.next(), ("c", 3));
2867
2868            assert_eq!(iter.len(), 2);
2869            assert_opt_eq_mut_tuple(iter.next_back(), ("a", 1));
2870
2871            assert_eq!(iter.len(), 1);
2872            assert_opt_eq_mut_tuple(iter.next(), ("b", 2));
2873
2874            assert_eq!(iter.len(), 0);
2875            assert_eq!(iter.next_back(), None);
2876        }
2877    }
2878
2879    #[test]
2880    fn test_iter_multiple_threads() {
2881        let mut pool = Pool::new(1);
2882        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2883        cache.put("a", 1);
2884        cache.put("b", 2);
2885        cache.put("c", 3);
2886
2887        let mut iter = cache.iter();
2888        assert_eq!(iter.len(), 3);
2889        assert_opt_eq_tuple(iter.next(), ("c", 3));
2890
2891        {
2892            let iter_ref = &mut iter;
2893            pool.scoped(|scoped| {
2894                scoped.execute(move || {
2895                    assert_eq!(iter_ref.len(), 2);
2896                    assert_opt_eq_tuple(iter_ref.next(), ("b", 2));
2897                });
2898            });
2899        }
2900
2901        assert_eq!(iter.len(), 1);
2902        assert_opt_eq_tuple(iter.next(), ("a", 1));
2903
2904        assert_eq!(iter.len(), 0);
2905        assert_eq!(iter.next(), None);
2906    }
2907
2908    #[test]
2909    fn test_iter_clone() {
2910        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2911        cache.put("a", 1);
2912        cache.put("b", 2);
2913
2914        let mut iter = cache.iter();
2915        let mut iter_clone = iter.clone();
2916
2917        assert_eq!(iter.len(), 2);
2918        assert_opt_eq_tuple(iter.next(), ("b", 2));
2919        assert_eq!(iter_clone.len(), 2);
2920        assert_opt_eq_tuple(iter_clone.next(), ("b", 2));
2921
2922        assert_eq!(iter.len(), 1);
2923        assert_opt_eq_tuple(iter.next(), ("a", 1));
2924        assert_eq!(iter_clone.len(), 1);
2925        assert_opt_eq_tuple(iter_clone.next(), ("a", 1));
2926
2927        assert_eq!(iter.len(), 0);
2928        assert_eq!(iter.next(), None);
2929        assert_eq!(iter_clone.len(), 0);
2930        assert_eq!(iter_clone.next(), None);
2931    }
2932
2933    #[test]
2934    fn test_into_iter() {
2935        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2936        cache.put("a", 1);
2937        cache.put("b", 2);
2938        cache.put("c", 3);
2939
2940        let mut iter = cache.into_iter();
2941        assert_eq!(iter.len(), 3);
2942        assert_eq!(iter.next(), Some(("a", 1)));
2943
2944        assert_eq!(iter.len(), 2);
2945        assert_eq!(iter.next(), Some(("b", 2)));
2946
2947        assert_eq!(iter.len(), 1);
2948        assert_eq!(iter.next(), Some(("c", 3)));
2949
2950        assert_eq!(iter.len(), 0);
2951        assert_eq!(iter.next(), None);
2952    }
2953
2954    #[test]
2955    fn test_that_pop_actually_detaches_node() {
2956        let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
2957
2958        cache.put("a", 1);
2959        cache.put("b", 2);
2960        cache.put("c", 3);
2961        cache.put("d", 4);
2962        cache.put("e", 5);
2963
2964        assert_eq!(cache.pop(&"c"), Some(3));
2965
2966        cache.put("f", 6);
2967
2968        let mut iter = cache.iter();
2969        assert_opt_eq_tuple(iter.next(), ("f", 6));
2970        assert_opt_eq_tuple(iter.next(), ("e", 5));
2971        assert_opt_eq_tuple(iter.next(), ("d", 4));
2972        assert_opt_eq_tuple(iter.next(), ("b", 2));
2973        assert_opt_eq_tuple(iter.next(), ("a", 1));
2974        assert!(iter.next().is_none());
2975    }
2976
2977    #[test]
2978    fn test_retain() {
2979        let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
2980
2981        cache.put(1, 10);
2982        cache.put(2, 20);
2983        cache.put(3, 30);
2984        cache.put(4, 40);
2985        cache.put(5, 50);
2986
2987        // Keep even keys and double the values that are kept.
2988        cache.retain(|k, v| {
2989            if k % 2 == 0 {
2990                *v *= 2;
2991                true
2992            } else {
2993                false
2994            }
2995        });
2996
2997        assert_eq!(cache.len(), 2);
2998        assert_eq!(cache.peek(&2), Some(&40));
2999        assert_eq!(cache.peek(&4), Some(&80));
3000        assert_eq!(cache.peek(&1), None);
3001        assert_eq!(cache.peek(&3), None);
3002        assert_eq!(cache.peek(&5), None);
3003
3004        // The retained entries keep their most-recently-used to least-recently-used order.
3005        let mut iter = cache.iter();
3006        assert_opt_eq_tuple(iter.next(), (4, 80));
3007        assert_opt_eq_tuple(iter.next(), (2, 40));
3008        assert!(iter.next().is_none());
3009
3010        // The list is still consistent, so newly inserted entries land at the front.
3011        cache.put(6, 60);
3012        let mut iter = cache.iter();
3013        assert_opt_eq_tuple(iter.next(), (6, 60));
3014        assert_opt_eq_tuple(iter.next(), (4, 80));
3015        assert_opt_eq_tuple(iter.next(), (2, 40));
3016        assert!(iter.next().is_none());
3017    }
3018
3019    #[test]
3020    fn test_retain_all_and_none() {
3021        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3022        cache.put(1, "a");
3023        cache.put(2, "b");
3024
3025        cache.retain(|_, _| true);
3026        assert_eq!(cache.len(), 2);
3027
3028        cache.retain(|_, _| false);
3029        assert_eq!(cache.len(), 0);
3030        assert!(cache.is_empty());
3031    }
3032
3033    #[test]
3034    fn test_no_memory_leaks_with_retain() {
3035        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3036
3037        struct DropCounter;
3038
3039        impl Drop for DropCounter {
3040            fn drop(&mut self) {
3041                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3042            }
3043        }
3044
3045        let n = 100;
3046        for _ in 0..n {
3047            let mut cache = LruCache::unbounded();
3048            for i in 0..n {
3049                cache.put(i, DropCounter {});
3050            }
3051            // Drop half of the entries via `retain` and let the rest drop with the cache.
3052            cache.retain(|k, _| k % 2 == 0);
3053        }
3054        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
3055    }
3056
3057    #[test]
3058    fn test_get_with_borrow() {
3059        use alloc::string::String;
3060
3061        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
3062
3063        let key = String::from("apple");
3064        cache.put(key, "red");
3065
3066        assert_opt_eq(cache.get("apple"), "red");
3067    }
3068
3069    #[test]
3070    fn test_get_mut_with_borrow() {
3071        use alloc::string::String;
3072
3073        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
3074
3075        let key = String::from("apple");
3076        cache.put(key, "red");
3077
3078        assert_opt_eq_mut(cache.get_mut("apple"), "red");
3079    }
3080
3081    #[test]
3082    fn test_no_memory_leaks() {
3083        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3084
3085        struct DropCounter;
3086
3087        impl Drop for DropCounter {
3088            fn drop(&mut self) {
3089                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3090            }
3091        }
3092
3093        let n = 100;
3094        for _ in 0..n {
3095            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
3096            for i in 0..n {
3097                cache.put(i, DropCounter {});
3098            }
3099        }
3100        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
3101    }
3102
3103    #[test]
3104    fn test_no_memory_leaks_with_clear() {
3105        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3106
3107        struct DropCounter;
3108
3109        impl Drop for DropCounter {
3110            fn drop(&mut self) {
3111                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3112            }
3113        }
3114
3115        let n = 100;
3116        for _ in 0..n {
3117            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
3118            for i in 0..n {
3119                cache.put(i, DropCounter {});
3120            }
3121            cache.clear();
3122        }
3123        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
3124    }
3125
3126    #[test]
3127    fn test_no_memory_leaks_with_resize() {
3128        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3129
3130        struct DropCounter;
3131
3132        impl Drop for DropCounter {
3133            fn drop(&mut self) {
3134                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3135            }
3136        }
3137
3138        let n = 100;
3139        for _ in 0..n {
3140            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
3141            for i in 0..n {
3142                cache.put(i, DropCounter {});
3143            }
3144            cache.clear();
3145        }
3146        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
3147    }
3148
3149    #[test]
3150    fn test_no_memory_leaks_with_pop() {
3151        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3152
3153        #[derive(Hash, Eq)]
3154        struct KeyDropCounter(usize);
3155
3156        impl PartialEq for KeyDropCounter {
3157            fn eq(&self, other: &Self) -> bool {
3158                self.0.eq(&other.0)
3159            }
3160        }
3161
3162        impl Drop for KeyDropCounter {
3163            fn drop(&mut self) {
3164                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3165            }
3166        }
3167
3168        let n = 100;
3169        for _ in 0..n {
3170            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
3171
3172            for i in 0..100 {
3173                cache.put(KeyDropCounter(i), i);
3174                cache.pop(&KeyDropCounter(i));
3175            }
3176        }
3177
3178        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n * 2);
3179    }
3180
3181    #[test]
3182    fn test_find_and_promote() {
3183        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3184        cache.put(1, "a");
3185        cache.put(2, "b");
3186        cache.put(3, "c");
3187
3188        let found = cache.find_and_promote(|(_, value)| *value == "b");
3189        assert_eq!(found, Some((&2, &"b")));
3190        assert_eq!(cache.pop_lru(), Some((1, "a")));
3191        assert_eq!(cache.pop_lru(), Some((3, "c")));
3192        assert_eq!(cache.pop_lru(), Some((2, "b")));
3193        assert_eq!(cache.pop_lru(), None);
3194    }
3195
3196    #[test]
3197    fn test_find_and_promote_no_match() {
3198        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3199        cache.put(1, "a");
3200        cache.put(2, "b");
3201        cache.put(3, "c");
3202
3203        let found = cache.find_and_promote(|(_, value)| *value == "d");
3204        assert_eq!(found, None);
3205        assert_eq!(cache.pop_lru(), Some((1, "a")));
3206        assert_eq!(cache.pop_lru(), Some((2, "b")));
3207        assert_eq!(cache.pop_lru(), Some((3, "c")));
3208        assert_eq!(cache.pop_lru(), None);
3209    }
3210
3211    #[test]
3212    fn test_find_and_promote_multiple_matches_picks_first_in_mru_order() {
3213        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3214        cache.put(1, "b");
3215        cache.put(2, "b");
3216        cache.put(3, "x");
3217
3218        let found = cache.find_and_promote(|(_, value)| *value == "b");
3219        assert_eq!(found, Some((&2, &"b")));
3220        assert_eq!(cache.pop_lru(), Some((1, "b")));
3221        assert_eq!(cache.pop_lru(), Some((3, "x")));
3222        assert_eq!(cache.pop_lru(), Some((2, "b")));
3223        assert_eq!(cache.pop_lru(), None);
3224    }
3225
3226    #[test]
3227    fn test_promote_and_demote() {
3228        let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
3229        for i in 0..5 {
3230            cache.push(i, i);
3231        }
3232        cache.promote(&1);
3233        cache.promote(&0);
3234        cache.demote(&3);
3235        cache.demote(&4);
3236        assert_eq!(cache.pop_lru(), Some((4, 4)));
3237        assert_eq!(cache.pop_lru(), Some((3, 3)));
3238        assert_eq!(cache.pop_lru(), Some((2, 2)));
3239        assert_eq!(cache.pop_lru(), Some((1, 1)));
3240        assert_eq!(cache.pop_lru(), Some((0, 0)));
3241        assert_eq!(cache.pop_lru(), None);
3242    }
3243
3244    #[test]
3245    fn test_get_key_value() {
3246        use alloc::string::String;
3247
3248        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
3249
3250        let key = String::from("apple");
3251        cache.put(key, "red");
3252
3253        assert_eq!(
3254            cache.get_key_value("apple"),
3255            Some((&String::from("apple"), &"red"))
3256        );
3257        assert_eq!(cache.get_key_value("banana"), None);
3258    }
3259
3260    #[test]
3261    fn test_get_key_value_mut() {
3262        use alloc::string::String;
3263
3264        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
3265
3266        let key = String::from("apple");
3267        cache.put(key, "red");
3268
3269        let (k, v) = cache.get_key_value_mut("apple").unwrap();
3270        assert_eq!(k, &String::from("apple"));
3271        assert_eq!(v, &mut "red");
3272        *v = "green";
3273
3274        assert_eq!(
3275            cache.get_key_value("apple"),
3276            Some((&String::from("apple"), &"green"))
3277        );
3278        assert_eq!(cache.get_key_value("banana"), None);
3279    }
3280
3281    #[test]
3282    fn test_clone() {
3283        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3284        cache.put("a", 1);
3285        cache.put("b", 2);
3286        cache.put("c", 3);
3287
3288        let mut cloned = cache.clone();
3289
3290        assert_eq!(cache.pop_lru(), Some(("a", 1)));
3291        assert_eq!(cloned.pop_lru(), Some(("a", 1)));
3292
3293        assert_eq!(cache.pop_lru(), Some(("b", 2)));
3294        assert_eq!(cloned.pop_lru(), Some(("b", 2)));
3295
3296        assert_eq!(cache.pop_lru(), Some(("c", 3)));
3297        assert_eq!(cloned.pop_lru(), Some(("c", 3)));
3298
3299        assert_eq!(cache.pop_lru(), None);
3300        assert_eq!(cloned.pop_lru(), None);
3301    }
3302
3303    #[test]
3304    fn test_clone_unbounded() {
3305        let mut cache = LruCache::unbounded();
3306        cache.put("a", 1);
3307        cache.put("b", 2);
3308        cache.put("c", 3);
3309
3310        let mut cloned = cache.clone();
3311
3312        assert_eq!(cache.pop_lru(), Some(("a", 1)));
3313        assert_eq!(cloned.pop_lru(), Some(("a", 1)));
3314
3315        assert_eq!(cache.pop_lru(), Some(("b", 2)));
3316        assert_eq!(cloned.pop_lru(), Some(("b", 2)));
3317
3318        assert_eq!(cache.pop_lru(), Some(("c", 3)));
3319        assert_eq!(cloned.pop_lru(), Some(("c", 3)));
3320
3321        assert_eq!(cache.pop_lru(), None);
3322        assert_eq!(cloned.pop_lru(), None);
3323    }
3324
3325    #[test]
3326    fn iter_mut_stacked_borrows_violation() {
3327        let mut cache: LruCache<i32, i32> = LruCache::new(NonZeroUsize::new(3).unwrap());
3328        cache.put(1, 10);
3329        cache.put(2, 20);
3330        cache.put(3, 30);
3331
3332        for (_k, v) in cache.iter_mut() {
3333            *v *= 2;
3334        }
3335
3336        assert_eq!(cache.get(&1), Some(&20));
3337        assert_eq!(cache.get(&2), Some(&40));
3338        assert_eq!(cache.get(&3), Some(&60));
3339    }
3340
3341    #[test]
3342    fn test_pop_panicking_key_drop_keeps_list_consistent() {
3343        use std::panic::{catch_unwind, AssertUnwindSafe};
3344        use std::sync::atomic::{AtomicBool, Ordering};
3345
3346        static ARMED: AtomicBool = AtomicBool::new(false);
3347
3348        #[derive(PartialEq, Eq, Hash)]
3349        struct PanicKey(u32);
3350        impl Drop for PanicKey {
3351            fn drop(&mut self) {
3352                if ARMED.swap(false, Ordering::SeqCst) {
3353                    panic!("PanicKey::drop");
3354                }
3355            }
3356        }
3357
3358        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
3359        cache.put(PanicKey(1), "a");
3360        cache.put(PanicKey(2), "b");
3361        cache.put(PanicKey(3), "c");
3362
3363        ARMED.store(true, Ordering::SeqCst);
3364        let _ = catch_unwind(AssertUnwindSafe(|| {
3365            cache.pop(&PanicKey(2));
3366        }));
3367
3368        cache.put(PanicKey(4), "d");
3369        cache.put(PanicKey(5), "e");
3370        let _ = cache.get(&PanicKey(3));
3371        for (_k, _v) in cache.iter() {}
3372    }
3373}
3374
3375/// Doctests for what should *not* compile
3376///
3377/// ```compile_fail
3378/// let mut cache = lru::LruCache::<u32, u32>::unbounded();
3379/// let _: &'static u32 = cache.get_or_insert(0, || 92);
3380/// ```
3381///
3382/// ```compile_fail
3383/// let mut cache = lru::LruCache::<u32, u32>::unbounded();
3384/// let _: Option<(&'static u32, _)> = cache.peek_lru();
3385/// let _: Option<(_, &'static u32)> = cache.peek_lru();
3386/// ```
3387fn _test_lifetimes() {}