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/// An iterator can be sent to another thread only if its keys and values are
1894/// `Sync`, since it yields shared references to them.
1895///
1896/// ```compile_fail
1897/// use std::cell::Cell;
1898///
1899/// fn assert_send<T: Send>() {}
1900/// assert_send::<lru::Iter<'_, Cell<u8>, u8>>();
1901/// ```
1902///
1903/// ```compile_fail
1904/// use std::cell::Cell;
1905///
1906/// fn assert_send<T: Send>() {}
1907/// assert_send::<lru::Iter<'_, u8, Cell<u8>>>();
1908/// ```
1909///
1910/// [`iter`]: struct.LruCache.html#method.iter
1911/// [`LruCache`]: struct.LruCache.html
1912pub struct Iter<'a, K: 'a, V: 'a> {
1913    len: usize,
1914
1915    ptr: *const LruEntry<K, V>,
1916    end: *const LruEntry<K, V>,
1917
1918    phantom: PhantomData<&'a K>,
1919}
1920
1921impl<'a, K, V> Iterator for Iter<'a, K, V> {
1922    type Item = (&'a K, &'a V);
1923
1924    fn next(&mut self) -> Option<(&'a K, &'a V)> {
1925        if self.len == 0 {
1926            return None;
1927        }
1928
1929        let key = unsafe { &(*(*self.ptr).key.as_ptr()) as &K };
1930        let val = unsafe { &(*(*self.ptr).val.as_ptr()) as &V };
1931
1932        self.len -= 1;
1933        self.ptr = unsafe { (*self.ptr).next };
1934
1935        Some((key, val))
1936    }
1937
1938    fn size_hint(&self) -> (usize, Option<usize>) {
1939        (self.len, Some(self.len))
1940    }
1941
1942    fn count(self) -> usize {
1943        self.len
1944    }
1945}
1946
1947impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
1948    fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
1949        if self.len == 0 {
1950            return None;
1951        }
1952
1953        let key = unsafe { &(*(*self.end).key.as_ptr()) as &K };
1954        let val = unsafe { &(*(*self.end).val.as_ptr()) as &V };
1955
1956        self.len -= 1;
1957        self.end = unsafe { (*self.end).prev };
1958
1959        Some((key, val))
1960    }
1961}
1962
1963impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {}
1964impl<'a, K, V> FusedIterator for Iter<'a, K, V> {}
1965
1966impl<'a, K, V> Clone for Iter<'a, K, V> {
1967    fn clone(&self) -> Iter<'a, K, V> {
1968        Iter {
1969            len: self.len,
1970            ptr: self.ptr,
1971            end: self.end,
1972            phantom: PhantomData,
1973        }
1974    }
1975}
1976
1977// The compiler does not automatically derive Send and Sync for Iter because it contains
1978// raw pointers.
1979unsafe impl<'a, K: Sync, V: Sync> Send for Iter<'a, K, V> {}
1980unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
1981
1982/// An iterator over mutables entries of a `LruCache`.
1983///
1984/// This `struct` is created by the [`iter_mut`] method on [`LruCache`][`LruCache`]. See its
1985/// documentation for more.
1986///
1987/// [`iter_mut`]: struct.LruCache.html#method.iter_mut
1988/// [`LruCache`]: struct.LruCache.html
1989pub struct IterMut<'a, K: 'a, V: 'a> {
1990    len: usize,
1991
1992    ptr: *mut LruEntry<K, V>,
1993    end: *mut LruEntry<K, V>,
1994
1995    phantom: PhantomData<&'a K>,
1996}
1997
1998impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1999    type Item = (&'a K, &'a mut V);
2000
2001    fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
2002        if self.len == 0 {
2003            return None;
2004        }
2005
2006        let key = unsafe { &(*(*self.ptr).key.as_ptr()) as &K };
2007        let val = unsafe { &mut (*(*self.ptr).val.as_mut_ptr()) as &mut V };
2008
2009        self.len -= 1;
2010        self.ptr = unsafe { (*self.ptr).next };
2011
2012        Some((key, val))
2013    }
2014
2015    fn size_hint(&self) -> (usize, Option<usize>) {
2016        (self.len, Some(self.len))
2017    }
2018
2019    fn count(self) -> usize {
2020        self.len
2021    }
2022}
2023
2024impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> {
2025    fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
2026        if self.len == 0 {
2027            return None;
2028        }
2029
2030        let key = unsafe { &(*(*self.end).key.as_ptr()) as &K };
2031        let val = unsafe { &mut (*(*self.end).val.as_mut_ptr()) as &mut V };
2032
2033        self.len -= 1;
2034        self.end = unsafe { (*self.end).prev };
2035
2036        Some((key, val))
2037    }
2038}
2039
2040impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {}
2041impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}
2042
2043// The compiler does not automatically derive Send and Sync for Iter because it contains
2044// raw pointers.
2045unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {}
2046unsafe impl<'a, K: Sync, V: Sync> Sync for IterMut<'a, K, V> {}
2047
2048/// An iterator that moves out of a `LruCache`.
2049///
2050/// This `struct` is created by the [`into_iter`] method on [`LruCache`][`LruCache`]. See its
2051/// documentation for more.
2052///
2053/// [`into_iter`]: struct.LruCache.html#method.into_iter
2054/// [`LruCache`]: struct.LruCache.html
2055pub struct IntoIter<K, V>
2056where
2057    K: Hash + Eq,
2058{
2059    cache: LruCache<K, V>,
2060}
2061
2062impl<K, V> Iterator for IntoIter<K, V>
2063where
2064    K: Hash + Eq,
2065{
2066    type Item = (K, V);
2067
2068    fn next(&mut self) -> Option<(K, V)> {
2069        self.cache.pop_lru()
2070    }
2071
2072    fn size_hint(&self) -> (usize, Option<usize>) {
2073        let len = self.cache.len();
2074        (len, Some(len))
2075    }
2076
2077    fn count(self) -> usize {
2078        self.cache.len()
2079    }
2080}
2081
2082impl<K, V> ExactSizeIterator for IntoIter<K, V> where K: Hash + Eq {}
2083impl<K, V> FusedIterator for IntoIter<K, V> where K: Hash + Eq {}
2084
2085impl<K: Hash + Eq, V> IntoIterator for LruCache<K, V> {
2086    type Item = (K, V);
2087    type IntoIter = IntoIter<K, V>;
2088
2089    fn into_iter(self) -> IntoIter<K, V> {
2090        IntoIter { cache: self }
2091    }
2092}
2093
2094#[cfg(test)]
2095mod tests {
2096    use super::LruCache;
2097    use core::{fmt::Debug, num::NonZeroUsize};
2098    use scoped_threadpool::Pool;
2099    use std::rc::Rc;
2100    use std::sync::atomic::{AtomicUsize, Ordering};
2101
2102    fn assert_opt_eq<V: PartialEq + Debug>(opt: Option<&V>, v: V) {
2103        assert!(opt.is_some());
2104        assert_eq!(opt.unwrap(), &v);
2105    }
2106
2107    fn assert_opt_eq_mut<V: PartialEq + Debug>(opt: Option<&mut V>, v: V) {
2108        assert!(opt.is_some());
2109        assert_eq!(opt.unwrap(), &v);
2110    }
2111
2112    fn assert_opt_eq_tuple<K: PartialEq + Debug, V: PartialEq + Debug>(
2113        opt: Option<(&K, &V)>,
2114        kv: (K, V),
2115    ) {
2116        assert!(opt.is_some());
2117        let res = opt.unwrap();
2118        assert_eq!(res.0, &kv.0);
2119        assert_eq!(res.1, &kv.1);
2120    }
2121
2122    fn assert_opt_eq_mut_tuple<K: PartialEq + Debug, V: PartialEq + Debug>(
2123        opt: Option<(&K, &mut V)>,
2124        kv: (K, V),
2125    ) {
2126        assert!(opt.is_some());
2127        let res = opt.unwrap();
2128        assert_eq!(res.0, &kv.0);
2129        assert_eq!(res.1, &kv.1);
2130    }
2131
2132    #[test]
2133    fn test_unbounded() {
2134        let mut cache = LruCache::unbounded();
2135        for i in 0..13370 {
2136            cache.put(i, ());
2137        }
2138        assert_eq!(cache.len(), 13370);
2139    }
2140
2141    #[test]
2142    #[cfg(feature = "hashbrown")]
2143    fn test_with_hasher() {
2144        use core::num::NonZeroUsize;
2145
2146        use hashbrown::DefaultHashBuilder;
2147
2148        let s = DefaultHashBuilder::default();
2149        let mut cache = LruCache::with_hasher(NonZeroUsize::new(16).unwrap(), s);
2150
2151        for i in 0..13370 {
2152            cache.put(i, ());
2153        }
2154        assert_eq!(cache.len(), 16);
2155    }
2156
2157    #[test]
2158    fn test_put_and_get() {
2159        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2160        assert!(cache.is_empty());
2161
2162        assert_eq!(cache.put("apple", "red"), None);
2163        assert_eq!(cache.put("banana", "yellow"), None);
2164
2165        assert_eq!(cache.cap().get(), 2);
2166        assert_eq!(cache.len(), 2);
2167        assert!(!cache.is_empty());
2168        assert_opt_eq(cache.get(&"apple"), "red");
2169        assert_opt_eq(cache.get(&"banana"), "yellow");
2170    }
2171
2172    #[test]
2173    fn test_put_and_get_or_insert() {
2174        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2175        assert!(cache.is_empty());
2176
2177        assert_eq!(cache.put("apple", "red"), None);
2178        assert_eq!(cache.put("banana", "yellow"), 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("apple", || "orange"), &"red");
2184        assert_eq!(cache.get_or_insert("banana", || "orange"), &"yellow");
2185        assert_eq!(cache.get_or_insert("lemon", || "orange"), &"orange");
2186        assert_eq!(cache.get_or_insert("lemon", || "red"), &"orange");
2187    }
2188
2189    #[test]
2190    fn test_put_and_get_or_insert_with_key() {
2191        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2192        assert!(cache.is_empty());
2193
2194        assert_eq!(cache.put("apple", 2), None);
2195        assert_eq!(cache.put("banana", 8), None);
2196
2197        assert_eq!(cache.cap().get(), 2);
2198        assert_eq!(cache.len(), 2);
2199        assert!(!cache.is_empty());
2200        assert_eq!(cache.get_or_insert_with_key("apple", |k| k.len()), &2);
2201        assert_eq!(cache.get_or_insert_with_key("banana", |k| k.len()), &8);
2202        assert_eq!(cache.get_or_insert_with_key("lemon", |k| k.len()), &5);
2203        assert_eq!(cache.get_or_insert_with_key("lemon", |k| k.len() + 3), &5);
2204    }
2205
2206    #[test]
2207    fn test_get_or_insert_ref() {
2208        use alloc::borrow::ToOwned;
2209        use alloc::string::String;
2210
2211        let key1 = Rc::new("1".to_owned());
2212        let key2 = Rc::new("2".to_owned());
2213        let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
2214        assert!(cache.is_empty());
2215        assert_eq!(cache.get_or_insert_ref(&key1, || "One".to_owned()), "One");
2216        assert_eq!(cache.get_or_insert_ref(&key2, || "Two".to_owned()), "Two");
2217        assert_eq!(cache.len(), 2);
2218        assert!(!cache.is_empty());
2219        assert_eq!(
2220            cache.get_or_insert_ref(&key2, || "Not two".to_owned()),
2221            "Two"
2222        );
2223        assert_eq!(
2224            cache.get_or_insert_ref(&key2, || "Again not two".to_owned()),
2225            "Two"
2226        );
2227        assert_eq!(Rc::strong_count(&key1), 2);
2228        assert_eq!(Rc::strong_count(&key2), 2);
2229    }
2230
2231    #[test]
2232    fn test_try_get_or_insert() {
2233        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2234
2235        assert_eq!(
2236            cache.try_get_or_insert::<_, &str>("apple", || Ok("red")),
2237            Ok(&"red")
2238        );
2239        assert_eq!(
2240            cache.try_get_or_insert::<_, &str>("apple", || Err("failed")),
2241            Ok(&"red")
2242        );
2243        assert_eq!(
2244            cache.try_get_or_insert::<_, &str>("banana", || Ok("orange")),
2245            Ok(&"orange")
2246        );
2247        assert_eq!(
2248            cache.try_get_or_insert::<_, &str>("lemon", || Err("failed")),
2249            Err("failed")
2250        );
2251        assert_eq!(
2252            cache.try_get_or_insert::<_, &str>("banana", || Err("failed")),
2253            Ok(&"orange")
2254        );
2255    }
2256
2257    #[test]
2258    fn test_try_get_or_insert_with_key() {
2259        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2260
2261        assert_eq!(
2262            cache.try_get_or_insert_with_key::<_, &str>("apple", |k| Ok(k.len())),
2263            Ok(&5)
2264        );
2265        assert_eq!(
2266            cache.try_get_or_insert_with_key::<_, &str>("apple", |_| Err("failed")),
2267            Ok(&5)
2268        );
2269        assert_eq!(
2270            cache.try_get_or_insert_with_key::<_, &str>("banana", |k| Ok(k.len())),
2271            Ok(&6)
2272        );
2273        assert_eq!(
2274            cache.try_get_or_insert_with_key::<_, &str>("lemon", |_| Err("failed")),
2275            Err("failed")
2276        );
2277        assert_eq!(
2278            cache.try_get_or_insert_with_key::<_, &str>("banana", |_| Err("failed")),
2279            Ok(&6)
2280        );
2281    }
2282
2283    #[test]
2284    fn test_try_get_or_insert_ref() {
2285        use alloc::borrow::ToOwned;
2286        use alloc::string::String;
2287
2288        let key1 = Rc::new("1".to_owned());
2289        let key2 = Rc::new("2".to_owned());
2290        let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
2291        let f = || -> Result<String, ()> { Err(()) };
2292        let a = || -> Result<String, ()> { Ok("One".to_owned()) };
2293        let b = || -> Result<String, ()> { Ok("Two".to_owned()) };
2294        assert_eq!(cache.try_get_or_insert_ref(&key1, a), Ok(&"One".to_owned()));
2295        assert_eq!(cache.try_get_or_insert_ref(&key2, f), Err(()));
2296        assert_eq!(cache.try_get_or_insert_ref(&key2, b), Ok(&"Two".to_owned()));
2297        assert_eq!(cache.try_get_or_insert_ref(&key2, a), Ok(&"Two".to_owned()));
2298        assert_eq!(cache.len(), 2);
2299        assert_eq!(Rc::strong_count(&key1), 2);
2300        assert_eq!(Rc::strong_count(&key2), 2);
2301    }
2302
2303    #[test]
2304    fn test_put_and_get_or_insert_mut() {
2305        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2306        assert!(cache.is_empty());
2307
2308        assert_eq!(cache.put("apple", "red"), None);
2309        assert_eq!(cache.put("banana", "yellow"), None);
2310
2311        assert_eq!(cache.cap().get(), 2);
2312        assert_eq!(cache.len(), 2);
2313
2314        let v = cache.get_or_insert_mut("apple", || "orange");
2315        assert_eq!(v, &"red");
2316        *v = "blue";
2317
2318        assert_eq!(cache.get_or_insert_mut("apple", || "orange"), &"blue");
2319        assert_eq!(cache.get_or_insert_mut("banana", || "orange"), &"yellow");
2320        assert_eq!(cache.get_or_insert_mut("lemon", || "orange"), &"orange");
2321        assert_eq!(cache.get_or_insert_mut("lemon", || "red"), &"orange");
2322    }
2323
2324    #[test]
2325    fn test_put_and_get_or_insert_mut_with_key() {
2326        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2327        assert!(cache.is_empty());
2328
2329        assert_eq!(cache.put("apple", 2), None);
2330        assert_eq!(cache.put("banana", 8), None);
2331
2332        assert_eq!(cache.cap().get(), 2);
2333        assert_eq!(cache.len(), 2);
2334
2335        let v = cache.get_or_insert_mut_with_key("apple", |k| k.len());
2336        assert_eq!(v, &2);
2337        *v = 4;
2338
2339        assert_eq!(cache.get_or_insert_mut_with_key("apple", |k| k.len()), &4);
2340        assert_eq!(cache.get_or_insert_mut_with_key("banana", |k| k.len()), &8);
2341        assert_eq!(cache.get_or_insert_mut_with_key("lemon", |k| k.len()), &5);
2342        assert_eq!(cache.get_or_insert_mut_with_key("lemon", |_| 0), &5);
2343    }
2344
2345    #[test]
2346    fn test_get_or_insert_mut_ref() {
2347        use alloc::borrow::ToOwned;
2348        use alloc::string::String;
2349
2350        let key1 = Rc::new("1".to_owned());
2351        let key2 = Rc::new("2".to_owned());
2352        let mut cache = LruCache::<Rc<String>, &'static str>::new(NonZeroUsize::new(2).unwrap());
2353        assert_eq!(cache.get_or_insert_mut_ref(&key1, || "One"), &mut "One");
2354        let v = cache.get_or_insert_mut_ref(&key2, || "Two");
2355        *v = "New two";
2356        assert_eq!(cache.get_or_insert_mut_ref(&key2, || "Two"), &mut "New two");
2357        assert_eq!(Rc::strong_count(&key1), 2);
2358        assert_eq!(Rc::strong_count(&key2), 2);
2359    }
2360
2361    #[test]
2362    fn test_try_get_or_insert_mut() {
2363        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2364
2365        cache.put(1, "a");
2366        cache.put(2, "b");
2367        cache.put(2, "c");
2368
2369        let f = || -> Result<&str, &str> { Err("failed") };
2370        let a = || -> Result<&str, &str> { Ok("a") };
2371        let b = || -> Result<&str, &str> { Ok("b") };
2372        if let Ok(v) = cache.try_get_or_insert_mut(2, a) {
2373            *v = "d";
2374        }
2375        assert_eq!(cache.try_get_or_insert_mut(2, a), Ok(&mut "d"));
2376        assert_eq!(cache.try_get_or_insert_mut(3, f), Err("failed"));
2377        assert_eq!(cache.try_get_or_insert_mut(4, b), Ok(&mut "b"));
2378        assert_eq!(cache.try_get_or_insert_mut(4, a), Ok(&mut "b"));
2379    }
2380
2381    #[test]
2382    fn test_try_get_or_insert_mut_with_key() {
2383        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2384
2385        cache.put("One", 1);
2386        cache.put("Two", 2);
2387        cache.put("Two", 3);
2388
2389        let f = |_: &&str| -> Result<usize, &str> { Err("failed") };
2390        let len = |k: &&str| -> Result<usize, &str> { Ok(k.len()) };
2391        let zero = |_: &&str| -> Result<usize, &str> { Ok(0) };
2392        if let Ok(v) = cache.try_get_or_insert_mut_with_key("Two", f) {
2393            *v = 6;
2394        }
2395        assert_eq!(cache.try_get_or_insert_mut_with_key("Two", len), Ok(&mut 6));
2396        assert_eq!(
2397            cache.try_get_or_insert_mut_with_key("Three", f),
2398            Err("failed")
2399        );
2400        assert_eq!(
2401            cache.try_get_or_insert_mut_with_key("Four", len),
2402            Ok(&mut 4)
2403        );
2404        assert_eq!(
2405            cache.try_get_or_insert_mut_with_key("Four", zero),
2406            Ok(&mut 4)
2407        );
2408    }
2409
2410    #[test]
2411    fn test_try_get_or_insert_mut_ref() {
2412        use alloc::borrow::ToOwned;
2413        use alloc::string::String;
2414
2415        let key1 = Rc::new("1".to_owned());
2416        let key2 = Rc::new("2".to_owned());
2417        let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
2418        let f = || -> Result<String, ()> { Err(()) };
2419        let a = || -> Result<String, ()> { Ok("One".to_owned()) };
2420        let b = || -> Result<String, ()> { Ok("Two".to_owned()) };
2421        assert_eq!(
2422            cache.try_get_or_insert_mut_ref(&key1, a),
2423            Ok(&mut "One".to_owned())
2424        );
2425        assert_eq!(cache.try_get_or_insert_mut_ref(&key2, f), Err(()));
2426        if let Ok(v) = cache.try_get_or_insert_mut_ref(&key2, b) {
2427            assert_eq!(v, &mut "Two");
2428            *v = "New two".to_owned();
2429        }
2430        assert_eq!(
2431            cache.try_get_or_insert_mut_ref(&key2, a),
2432            Ok(&mut "New two".to_owned())
2433        );
2434        assert_eq!(Rc::strong_count(&key1), 2);
2435        assert_eq!(Rc::strong_count(&key2), 2);
2436    }
2437
2438    #[test]
2439    fn test_put_and_get_mut() {
2440        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2441
2442        cache.put("apple", "red");
2443        cache.put("banana", "yellow");
2444
2445        assert_eq!(cache.cap().get(), 2);
2446        assert_eq!(cache.len(), 2);
2447        assert_opt_eq_mut(cache.get_mut(&"apple"), "red");
2448        assert_opt_eq_mut(cache.get_mut(&"banana"), "yellow");
2449    }
2450
2451    #[test]
2452    fn test_get_mut_and_update() {
2453        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2454
2455        cache.put("apple", 1);
2456        cache.put("banana", 3);
2457
2458        {
2459            let v = cache.get_mut(&"apple").unwrap();
2460            *v = 4;
2461        }
2462
2463        assert_eq!(cache.cap().get(), 2);
2464        assert_eq!(cache.len(), 2);
2465        assert_opt_eq_mut(cache.get_mut(&"apple"), 4);
2466        assert_opt_eq_mut(cache.get_mut(&"banana"), 3);
2467    }
2468
2469    #[test]
2470    fn test_put_update() {
2471        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2472
2473        assert_eq!(cache.put("apple", "red"), None);
2474        assert_eq!(cache.put("apple", "green"), Some("red"));
2475
2476        assert_eq!(cache.len(), 1);
2477        assert_opt_eq(cache.get(&"apple"), "green");
2478    }
2479
2480    #[test]
2481    fn test_put_removes_oldest() {
2482        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2483
2484        assert_eq!(cache.put("apple", "red"), None);
2485        assert_eq!(cache.put("banana", "yellow"), None);
2486        assert_eq!(cache.put("pear", "green"), None);
2487
2488        assert!(cache.get(&"apple").is_none());
2489        assert_opt_eq(cache.get(&"banana"), "yellow");
2490        assert_opt_eq(cache.get(&"pear"), "green");
2491
2492        // Even though we inserted "apple" into the cache earlier it has since been removed from
2493        // the cache so there is no current value for `put` to return.
2494        assert_eq!(cache.put("apple", "green"), None);
2495        assert_eq!(cache.put("tomato", "red"), None);
2496
2497        assert!(cache.get(&"pear").is_none());
2498        assert_opt_eq(cache.get(&"apple"), "green");
2499        assert_opt_eq(cache.get(&"tomato"), "red");
2500    }
2501
2502    #[test]
2503    fn test_peek() {
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(cache.peek(&"banana"), "yellow");
2510        assert_opt_eq(cache.peek(&"apple"), "red");
2511
2512        cache.put("pear", "green");
2513
2514        assert!(cache.peek(&"apple").is_none());
2515        assert_opt_eq(cache.peek(&"banana"), "yellow");
2516        assert_opt_eq(cache.peek(&"pear"), "green");
2517    }
2518
2519    #[test]
2520    fn test_peek_mut() {
2521        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2522
2523        cache.put("apple", "red");
2524        cache.put("banana", "yellow");
2525
2526        assert_opt_eq_mut(cache.peek_mut(&"banana"), "yellow");
2527        assert_opt_eq_mut(cache.peek_mut(&"apple"), "red");
2528        assert!(cache.peek_mut(&"pear").is_none());
2529
2530        cache.put("pear", "green");
2531
2532        assert!(cache.peek_mut(&"apple").is_none());
2533        assert_opt_eq_mut(cache.peek_mut(&"banana"), "yellow");
2534        assert_opt_eq_mut(cache.peek_mut(&"pear"), "green");
2535
2536        {
2537            let v = cache.peek_mut(&"banana").unwrap();
2538            *v = "green";
2539        }
2540
2541        assert_opt_eq_mut(cache.peek_mut(&"banana"), "green");
2542    }
2543
2544    #[test]
2545    fn test_peek_lru() {
2546        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2547
2548        assert!(cache.peek_lru().is_none());
2549
2550        cache.put("apple", "red");
2551        cache.put("banana", "yellow");
2552        assert_opt_eq_tuple(cache.peek_lru(), ("apple", "red"));
2553
2554        cache.get(&"apple");
2555        assert_opt_eq_tuple(cache.peek_lru(), ("banana", "yellow"));
2556
2557        cache.clear();
2558        assert!(cache.peek_lru().is_none());
2559    }
2560
2561    #[test]
2562    fn test_peek_mru() {
2563        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2564
2565        assert!(cache.peek_mru().is_none());
2566
2567        cache.put("apple", "red");
2568        cache.put("banana", "yellow");
2569        assert_opt_eq_tuple(cache.peek_mru(), ("banana", "yellow"));
2570
2571        cache.get(&"apple");
2572        assert_opt_eq_tuple(cache.peek_mru(), ("apple", "red"));
2573
2574        cache.clear();
2575        assert!(cache.peek_mru().is_none());
2576    }
2577
2578    #[test]
2579    fn test_contains() {
2580        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2581
2582        cache.put("apple", "red");
2583        cache.put("banana", "yellow");
2584        cache.put("pear", "green");
2585
2586        assert!(!cache.contains(&"apple"));
2587        assert!(cache.contains(&"banana"));
2588        assert!(cache.contains(&"pear"));
2589    }
2590
2591    #[test]
2592    fn test_pop() {
2593        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2594
2595        cache.put("apple", "red");
2596        cache.put("banana", "yellow");
2597
2598        assert_eq!(cache.len(), 2);
2599        assert_opt_eq(cache.get(&"apple"), "red");
2600        assert_opt_eq(cache.get(&"banana"), "yellow");
2601
2602        let popped = cache.pop(&"apple");
2603        assert!(popped.is_some());
2604        assert_eq!(popped.unwrap(), "red");
2605        assert_eq!(cache.len(), 1);
2606        assert!(cache.get(&"apple").is_none());
2607        assert_opt_eq(cache.get(&"banana"), "yellow");
2608    }
2609
2610    #[test]
2611    fn test_pop_entry() {
2612        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2613        cache.put("apple", "red");
2614        cache.put("banana", "yellow");
2615
2616        assert_eq!(cache.len(), 2);
2617        assert_opt_eq(cache.get(&"apple"), "red");
2618        assert_opt_eq(cache.get(&"banana"), "yellow");
2619
2620        let popped = cache.pop_entry(&"apple");
2621        assert!(popped.is_some());
2622        assert_eq!(popped.unwrap(), ("apple", "red"));
2623        assert_eq!(cache.len(), 1);
2624        assert!(cache.get(&"apple").is_none());
2625        assert_opt_eq(cache.get(&"banana"), "yellow");
2626    }
2627
2628    #[test]
2629    fn test_pop_lru() {
2630        let mut cache = LruCache::new(NonZeroUsize::new(200).unwrap());
2631
2632        for i in 0..75 {
2633            cache.put(i, "A");
2634        }
2635        for i in 0..75 {
2636            cache.put(i + 100, "B");
2637        }
2638        for i in 0..75 {
2639            cache.put(i + 200, "C");
2640        }
2641        assert_eq!(cache.len(), 200);
2642
2643        for i in 0..75 {
2644            assert_opt_eq(cache.get(&(74 - i + 100)), "B");
2645        }
2646        assert_opt_eq(cache.get(&25), "A");
2647
2648        for i in 26..75 {
2649            assert_eq!(cache.pop_lru(), Some((i, "A")));
2650        }
2651        for i in 0..75 {
2652            assert_eq!(cache.pop_lru(), Some((i + 200, "C")));
2653        }
2654        for i in 0..75 {
2655            assert_eq!(cache.pop_lru(), Some((74 - i + 100, "B")));
2656        }
2657        assert_eq!(cache.pop_lru(), Some((25, "A")));
2658        for _ in 0..50 {
2659            assert_eq!(cache.pop_lru(), None);
2660        }
2661    }
2662
2663    #[test]
2664    fn test_pop_mru() {
2665        let mut cache = LruCache::new(NonZeroUsize::new(200).unwrap());
2666
2667        for i in 0..75 {
2668            cache.put(i, "A");
2669        }
2670        for i in 0..75 {
2671            cache.put(i + 100, "B");
2672        }
2673        for i in 0..75 {
2674            cache.put(i + 200, "C");
2675        }
2676        assert_eq!(cache.len(), 200);
2677
2678        for i in 0..75 {
2679            assert_opt_eq(cache.get(&(74 - i + 100)), "B");
2680        }
2681        assert_opt_eq(cache.get(&25), "A");
2682
2683        assert_eq!(cache.pop_mru(), Some((25, "A")));
2684        for i in 0..75 {
2685            assert_eq!(cache.pop_mru(), Some((i + 100, "B")));
2686        }
2687        for i in 0..75 {
2688            assert_eq!(cache.pop_mru(), Some((74 - i + 200, "C")));
2689        }
2690        for i in (26..75).into_iter().rev() {
2691            assert_eq!(cache.pop_mru(), Some((i, "A")));
2692        }
2693        for _ in 0..50 {
2694            assert_eq!(cache.pop_mru(), None);
2695        }
2696    }
2697
2698    #[test]
2699    fn test_clear() {
2700        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2701
2702        cache.put("apple", "red");
2703        cache.put("banana", "yellow");
2704
2705        assert_eq!(cache.len(), 2);
2706        assert_opt_eq(cache.get(&"apple"), "red");
2707        assert_opt_eq(cache.get(&"banana"), "yellow");
2708
2709        cache.clear();
2710        assert_eq!(cache.len(), 0);
2711    }
2712
2713    #[test]
2714    fn test_resize_larger() {
2715        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2716
2717        cache.put(1, "a");
2718        cache.put(2, "b");
2719        cache.resize(NonZeroUsize::new(4).unwrap());
2720        cache.put(3, "c");
2721        cache.put(4, "d");
2722
2723        assert_eq!(cache.len(), 4);
2724        assert_eq!(cache.get(&1), Some(&"a"));
2725        assert_eq!(cache.get(&2), Some(&"b"));
2726        assert_eq!(cache.get(&3), Some(&"c"));
2727        assert_eq!(cache.get(&4), Some(&"d"));
2728    }
2729
2730    #[test]
2731    fn test_resize_smaller() {
2732        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2733
2734        cache.put(1, "a");
2735        cache.put(2, "b");
2736        cache.put(3, "c");
2737        cache.put(4, "d");
2738
2739        cache.resize(NonZeroUsize::new(2).unwrap());
2740
2741        assert_eq!(cache.len(), 2);
2742        assert!(cache.get(&1).is_none());
2743        assert!(cache.get(&2).is_none());
2744        assert_eq!(cache.get(&3), Some(&"c"));
2745        assert_eq!(cache.get(&4), Some(&"d"));
2746    }
2747
2748    #[test]
2749    fn test_send() {
2750        use std::thread;
2751
2752        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2753        cache.put(1, "a");
2754
2755        let handle = thread::spawn(move || {
2756            assert_eq!(cache.get(&1), Some(&"a"));
2757        });
2758
2759        assert!(handle.join().is_ok());
2760    }
2761
2762    #[test]
2763    fn test_multiple_threads() {
2764        let mut pool = Pool::new(1);
2765        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2766        cache.put(1, "a");
2767
2768        let cache_ref = &cache;
2769        pool.scoped(|scoped| {
2770            scoped.execute(move || {
2771                assert_eq!(cache_ref.peek(&1), Some(&"a"));
2772            });
2773        });
2774
2775        assert_eq!((cache_ref).peek(&1), Some(&"a"));
2776    }
2777
2778    #[test]
2779    fn test_iter_forwards() {
2780        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2781        cache.put("a", 1);
2782        cache.put("b", 2);
2783        cache.put("c", 3);
2784
2785        {
2786            // iter const
2787            let mut iter = cache.iter();
2788            assert_eq!(iter.len(), 3);
2789            assert_opt_eq_tuple(iter.next(), ("c", 3));
2790
2791            assert_eq!(iter.len(), 2);
2792            assert_opt_eq_tuple(iter.next(), ("b", 2));
2793
2794            assert_eq!(iter.len(), 1);
2795            assert_opt_eq_tuple(iter.next(), ("a", 1));
2796
2797            assert_eq!(iter.len(), 0);
2798            assert_eq!(iter.next(), None);
2799        }
2800        {
2801            // iter mut
2802            let mut iter = cache.iter_mut();
2803            assert_eq!(iter.len(), 3);
2804            assert_opt_eq_mut_tuple(iter.next(), ("c", 3));
2805
2806            assert_eq!(iter.len(), 2);
2807            assert_opt_eq_mut_tuple(iter.next(), ("b", 2));
2808
2809            assert_eq!(iter.len(), 1);
2810            assert_opt_eq_mut_tuple(iter.next(), ("a", 1));
2811
2812            assert_eq!(iter.len(), 0);
2813            assert_eq!(iter.next(), None);
2814        }
2815    }
2816
2817    #[test]
2818    fn test_iter_backwards() {
2819        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2820        cache.put("a", 1);
2821        cache.put("b", 2);
2822        cache.put("c", 3);
2823
2824        {
2825            // iter const
2826            let mut iter = cache.iter();
2827            assert_eq!(iter.len(), 3);
2828            assert_opt_eq_tuple(iter.next_back(), ("a", 1));
2829
2830            assert_eq!(iter.len(), 2);
2831            assert_opt_eq_tuple(iter.next_back(), ("b", 2));
2832
2833            assert_eq!(iter.len(), 1);
2834            assert_opt_eq_tuple(iter.next_back(), ("c", 3));
2835
2836            assert_eq!(iter.len(), 0);
2837            assert_eq!(iter.next_back(), None);
2838        }
2839
2840        {
2841            // iter mut
2842            let mut iter = cache.iter_mut();
2843            assert_eq!(iter.len(), 3);
2844            assert_opt_eq_mut_tuple(iter.next_back(), ("a", 1));
2845
2846            assert_eq!(iter.len(), 2);
2847            assert_opt_eq_mut_tuple(iter.next_back(), ("b", 2));
2848
2849            assert_eq!(iter.len(), 1);
2850            assert_opt_eq_mut_tuple(iter.next_back(), ("c", 3));
2851
2852            assert_eq!(iter.len(), 0);
2853            assert_eq!(iter.next_back(), None);
2854        }
2855    }
2856
2857    #[test]
2858    fn test_iter_forwards_and_backwards() {
2859        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2860        cache.put("a", 1);
2861        cache.put("b", 2);
2862        cache.put("c", 3);
2863
2864        {
2865            // iter const
2866            let mut iter = cache.iter();
2867            assert_eq!(iter.len(), 3);
2868            assert_opt_eq_tuple(iter.next(), ("c", 3));
2869
2870            assert_eq!(iter.len(), 2);
2871            assert_opt_eq_tuple(iter.next_back(), ("a", 1));
2872
2873            assert_eq!(iter.len(), 1);
2874            assert_opt_eq_tuple(iter.next(), ("b", 2));
2875
2876            assert_eq!(iter.len(), 0);
2877            assert_eq!(iter.next_back(), None);
2878        }
2879        {
2880            // iter mut
2881            let mut iter = cache.iter_mut();
2882            assert_eq!(iter.len(), 3);
2883            assert_opt_eq_mut_tuple(iter.next(), ("c", 3));
2884
2885            assert_eq!(iter.len(), 2);
2886            assert_opt_eq_mut_tuple(iter.next_back(), ("a", 1));
2887
2888            assert_eq!(iter.len(), 1);
2889            assert_opt_eq_mut_tuple(iter.next(), ("b", 2));
2890
2891            assert_eq!(iter.len(), 0);
2892            assert_eq!(iter.next_back(), None);
2893        }
2894    }
2895
2896    #[test]
2897    fn test_iter_multiple_threads() {
2898        let mut pool = Pool::new(1);
2899        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2900        cache.put("a", 1);
2901        cache.put("b", 2);
2902        cache.put("c", 3);
2903
2904        let mut iter = cache.iter();
2905        assert_eq!(iter.len(), 3);
2906        assert_opt_eq_tuple(iter.next(), ("c", 3));
2907
2908        {
2909            let iter_ref = &mut iter;
2910            pool.scoped(|scoped| {
2911                scoped.execute(move || {
2912                    assert_eq!(iter_ref.len(), 2);
2913                    assert_opt_eq_tuple(iter_ref.next(), ("b", 2));
2914                });
2915            });
2916        }
2917
2918        assert_eq!(iter.len(), 1);
2919        assert_opt_eq_tuple(iter.next(), ("a", 1));
2920
2921        assert_eq!(iter.len(), 0);
2922        assert_eq!(iter.next(), None);
2923    }
2924
2925    #[test]
2926    fn test_iter_send_sync_not_send() {
2927        use std::sync::{Mutex, MutexGuard};
2928        use std::thread;
2929
2930        fn assert_send<T: Send>() {}
2931        assert_send::<super::Iter<'_, MutexGuard<'_, ()>, MutexGuard<'_, ()>>>();
2932
2933        let lock = Mutex::new(42);
2934        let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2935        cache.put(1, lock.lock().unwrap());
2936        let mut iter = cache.iter();
2937        thread::scope(|scope| {
2938            scope
2939                .spawn(move || assert_eq!(**iter.next().unwrap().1, 42))
2940                .join()
2941                .unwrap();
2942        });
2943    }
2944
2945    #[test]
2946    fn test_iter_clone() {
2947        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2948        cache.put("a", 1);
2949        cache.put("b", 2);
2950
2951        let mut iter = cache.iter();
2952        let mut iter_clone = iter.clone();
2953
2954        assert_eq!(iter.len(), 2);
2955        assert_opt_eq_tuple(iter.next(), ("b", 2));
2956        assert_eq!(iter_clone.len(), 2);
2957        assert_opt_eq_tuple(iter_clone.next(), ("b", 2));
2958
2959        assert_eq!(iter.len(), 1);
2960        assert_opt_eq_tuple(iter.next(), ("a", 1));
2961        assert_eq!(iter_clone.len(), 1);
2962        assert_opt_eq_tuple(iter_clone.next(), ("a", 1));
2963
2964        assert_eq!(iter.len(), 0);
2965        assert_eq!(iter.next(), None);
2966        assert_eq!(iter_clone.len(), 0);
2967        assert_eq!(iter_clone.next(), None);
2968    }
2969
2970    #[test]
2971    fn test_into_iter() {
2972        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2973        cache.put("a", 1);
2974        cache.put("b", 2);
2975        cache.put("c", 3);
2976
2977        let mut iter = cache.into_iter();
2978        assert_eq!(iter.len(), 3);
2979        assert_eq!(iter.next(), Some(("a", 1)));
2980
2981        assert_eq!(iter.len(), 2);
2982        assert_eq!(iter.next(), Some(("b", 2)));
2983
2984        assert_eq!(iter.len(), 1);
2985        assert_eq!(iter.next(), Some(("c", 3)));
2986
2987        assert_eq!(iter.len(), 0);
2988        assert_eq!(iter.next(), None);
2989    }
2990
2991    #[test]
2992    fn test_that_pop_actually_detaches_node() {
2993        let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
2994
2995        cache.put("a", 1);
2996        cache.put("b", 2);
2997        cache.put("c", 3);
2998        cache.put("d", 4);
2999        cache.put("e", 5);
3000
3001        assert_eq!(cache.pop(&"c"), Some(3));
3002
3003        cache.put("f", 6);
3004
3005        let mut iter = cache.iter();
3006        assert_opt_eq_tuple(iter.next(), ("f", 6));
3007        assert_opt_eq_tuple(iter.next(), ("e", 5));
3008        assert_opt_eq_tuple(iter.next(), ("d", 4));
3009        assert_opt_eq_tuple(iter.next(), ("b", 2));
3010        assert_opt_eq_tuple(iter.next(), ("a", 1));
3011        assert!(iter.next().is_none());
3012    }
3013
3014    #[test]
3015    fn test_retain() {
3016        let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
3017
3018        cache.put(1, 10);
3019        cache.put(2, 20);
3020        cache.put(3, 30);
3021        cache.put(4, 40);
3022        cache.put(5, 50);
3023
3024        // Keep even keys and double the values that are kept.
3025        cache.retain(|k, v| {
3026            if k % 2 == 0 {
3027                *v *= 2;
3028                true
3029            } else {
3030                false
3031            }
3032        });
3033
3034        assert_eq!(cache.len(), 2);
3035        assert_eq!(cache.peek(&2), Some(&40));
3036        assert_eq!(cache.peek(&4), Some(&80));
3037        assert_eq!(cache.peek(&1), None);
3038        assert_eq!(cache.peek(&3), None);
3039        assert_eq!(cache.peek(&5), None);
3040
3041        // The retained entries keep their most-recently-used to least-recently-used order.
3042        let mut iter = cache.iter();
3043        assert_opt_eq_tuple(iter.next(), (4, 80));
3044        assert_opt_eq_tuple(iter.next(), (2, 40));
3045        assert!(iter.next().is_none());
3046
3047        // The list is still consistent, so newly inserted entries land at the front.
3048        cache.put(6, 60);
3049        let mut iter = cache.iter();
3050        assert_opt_eq_tuple(iter.next(), (6, 60));
3051        assert_opt_eq_tuple(iter.next(), (4, 80));
3052        assert_opt_eq_tuple(iter.next(), (2, 40));
3053        assert!(iter.next().is_none());
3054    }
3055
3056    #[test]
3057    fn test_retain_all_and_none() {
3058        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3059        cache.put(1, "a");
3060        cache.put(2, "b");
3061
3062        cache.retain(|_, _| true);
3063        assert_eq!(cache.len(), 2);
3064
3065        cache.retain(|_, _| false);
3066        assert_eq!(cache.len(), 0);
3067        assert!(cache.is_empty());
3068    }
3069
3070    #[test]
3071    fn test_no_memory_leaks_with_retain() {
3072        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3073
3074        struct DropCounter;
3075
3076        impl Drop for DropCounter {
3077            fn drop(&mut self) {
3078                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3079            }
3080        }
3081
3082        let n = 100;
3083        for _ in 0..n {
3084            let mut cache = LruCache::unbounded();
3085            for i in 0..n {
3086                cache.put(i, DropCounter {});
3087            }
3088            // Drop half of the entries via `retain` and let the rest drop with the cache.
3089            cache.retain(|k, _| k % 2 == 0);
3090        }
3091        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
3092    }
3093
3094    #[test]
3095    fn test_get_with_borrow() {
3096        use alloc::string::String;
3097
3098        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
3099
3100        let key = String::from("apple");
3101        cache.put(key, "red");
3102
3103        assert_opt_eq(cache.get("apple"), "red");
3104    }
3105
3106    #[test]
3107    fn test_get_mut_with_borrow() {
3108        use alloc::string::String;
3109
3110        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
3111
3112        let key = String::from("apple");
3113        cache.put(key, "red");
3114
3115        assert_opt_eq_mut(cache.get_mut("apple"), "red");
3116    }
3117
3118    #[test]
3119    fn test_no_memory_leaks() {
3120        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3121
3122        struct DropCounter;
3123
3124        impl Drop for DropCounter {
3125            fn drop(&mut self) {
3126                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3127            }
3128        }
3129
3130        let n = 100;
3131        for _ in 0..n {
3132            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
3133            for i in 0..n {
3134                cache.put(i, DropCounter {});
3135            }
3136        }
3137        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
3138    }
3139
3140    #[test]
3141    fn test_no_memory_leaks_with_clear() {
3142        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3143
3144        struct DropCounter;
3145
3146        impl Drop for DropCounter {
3147            fn drop(&mut self) {
3148                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3149            }
3150        }
3151
3152        let n = 100;
3153        for _ in 0..n {
3154            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
3155            for i in 0..n {
3156                cache.put(i, DropCounter {});
3157            }
3158            cache.clear();
3159        }
3160        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
3161    }
3162
3163    #[test]
3164    fn test_no_memory_leaks_with_resize() {
3165        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3166
3167        struct DropCounter;
3168
3169        impl Drop for DropCounter {
3170            fn drop(&mut self) {
3171                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3172            }
3173        }
3174
3175        let n = 100;
3176        for _ in 0..n {
3177            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
3178            for i in 0..n {
3179                cache.put(i, DropCounter {});
3180            }
3181            cache.clear();
3182        }
3183        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
3184    }
3185
3186    #[test]
3187    fn test_no_memory_leaks_with_pop() {
3188        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3189
3190        #[derive(Hash, Eq)]
3191        struct KeyDropCounter(usize);
3192
3193        impl PartialEq for KeyDropCounter {
3194            fn eq(&self, other: &Self) -> bool {
3195                self.0.eq(&other.0)
3196            }
3197        }
3198
3199        impl Drop for KeyDropCounter {
3200            fn drop(&mut self) {
3201                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3202            }
3203        }
3204
3205        let n = 100;
3206        for _ in 0..n {
3207            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
3208
3209            for i in 0..100 {
3210                cache.put(KeyDropCounter(i), i);
3211                cache.pop(&KeyDropCounter(i));
3212            }
3213        }
3214
3215        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n * 2);
3216    }
3217
3218    #[test]
3219    fn test_find_and_promote() {
3220        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3221        cache.put(1, "a");
3222        cache.put(2, "b");
3223        cache.put(3, "c");
3224
3225        let found = cache.find_and_promote(|(_, value)| *value == "b");
3226        assert_eq!(found, Some((&2, &"b")));
3227        assert_eq!(cache.pop_lru(), Some((1, "a")));
3228        assert_eq!(cache.pop_lru(), Some((3, "c")));
3229        assert_eq!(cache.pop_lru(), Some((2, "b")));
3230        assert_eq!(cache.pop_lru(), None);
3231    }
3232
3233    #[test]
3234    fn test_find_and_promote_no_match() {
3235        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3236        cache.put(1, "a");
3237        cache.put(2, "b");
3238        cache.put(3, "c");
3239
3240        let found = cache.find_and_promote(|(_, value)| *value == "d");
3241        assert_eq!(found, None);
3242        assert_eq!(cache.pop_lru(), Some((1, "a")));
3243        assert_eq!(cache.pop_lru(), Some((2, "b")));
3244        assert_eq!(cache.pop_lru(), Some((3, "c")));
3245        assert_eq!(cache.pop_lru(), None);
3246    }
3247
3248    #[test]
3249    fn test_find_and_promote_multiple_matches_picks_first_in_mru_order() {
3250        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3251        cache.put(1, "b");
3252        cache.put(2, "b");
3253        cache.put(3, "x");
3254
3255        let found = cache.find_and_promote(|(_, value)| *value == "b");
3256        assert_eq!(found, Some((&2, &"b")));
3257        assert_eq!(cache.pop_lru(), Some((1, "b")));
3258        assert_eq!(cache.pop_lru(), Some((3, "x")));
3259        assert_eq!(cache.pop_lru(), Some((2, "b")));
3260        assert_eq!(cache.pop_lru(), None);
3261    }
3262
3263    #[test]
3264    fn test_promote_and_demote() {
3265        let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
3266        for i in 0..5 {
3267            cache.push(i, i);
3268        }
3269        cache.promote(&1);
3270        cache.promote(&0);
3271        cache.demote(&3);
3272        cache.demote(&4);
3273        assert_eq!(cache.pop_lru(), Some((4, 4)));
3274        assert_eq!(cache.pop_lru(), Some((3, 3)));
3275        assert_eq!(cache.pop_lru(), Some((2, 2)));
3276        assert_eq!(cache.pop_lru(), Some((1, 1)));
3277        assert_eq!(cache.pop_lru(), Some((0, 0)));
3278        assert_eq!(cache.pop_lru(), None);
3279    }
3280
3281    #[test]
3282    fn test_get_key_value() {
3283        use alloc::string::String;
3284
3285        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
3286
3287        let key = String::from("apple");
3288        cache.put(key, "red");
3289
3290        assert_eq!(
3291            cache.get_key_value("apple"),
3292            Some((&String::from("apple"), &"red"))
3293        );
3294        assert_eq!(cache.get_key_value("banana"), None);
3295    }
3296
3297    #[test]
3298    fn test_get_key_value_mut() {
3299        use alloc::string::String;
3300
3301        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
3302
3303        let key = String::from("apple");
3304        cache.put(key, "red");
3305
3306        let (k, v) = cache.get_key_value_mut("apple").unwrap();
3307        assert_eq!(k, &String::from("apple"));
3308        assert_eq!(v, &mut "red");
3309        *v = "green";
3310
3311        assert_eq!(
3312            cache.get_key_value("apple"),
3313            Some((&String::from("apple"), &"green"))
3314        );
3315        assert_eq!(cache.get_key_value("banana"), None);
3316    }
3317
3318    #[test]
3319    fn test_clone() {
3320        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3321        cache.put("a", 1);
3322        cache.put("b", 2);
3323        cache.put("c", 3);
3324
3325        let mut cloned = cache.clone();
3326
3327        assert_eq!(cache.pop_lru(), Some(("a", 1)));
3328        assert_eq!(cloned.pop_lru(), Some(("a", 1)));
3329
3330        assert_eq!(cache.pop_lru(), Some(("b", 2)));
3331        assert_eq!(cloned.pop_lru(), Some(("b", 2)));
3332
3333        assert_eq!(cache.pop_lru(), Some(("c", 3)));
3334        assert_eq!(cloned.pop_lru(), Some(("c", 3)));
3335
3336        assert_eq!(cache.pop_lru(), None);
3337        assert_eq!(cloned.pop_lru(), None);
3338    }
3339
3340    #[test]
3341    fn test_clone_unbounded() {
3342        let mut cache = LruCache::unbounded();
3343        cache.put("a", 1);
3344        cache.put("b", 2);
3345        cache.put("c", 3);
3346
3347        let mut cloned = cache.clone();
3348
3349        assert_eq!(cache.pop_lru(), Some(("a", 1)));
3350        assert_eq!(cloned.pop_lru(), Some(("a", 1)));
3351
3352        assert_eq!(cache.pop_lru(), Some(("b", 2)));
3353        assert_eq!(cloned.pop_lru(), Some(("b", 2)));
3354
3355        assert_eq!(cache.pop_lru(), Some(("c", 3)));
3356        assert_eq!(cloned.pop_lru(), Some(("c", 3)));
3357
3358        assert_eq!(cache.pop_lru(), None);
3359        assert_eq!(cloned.pop_lru(), None);
3360    }
3361
3362    #[test]
3363    fn iter_mut_stacked_borrows_violation() {
3364        let mut cache: LruCache<i32, i32> = LruCache::new(NonZeroUsize::new(3).unwrap());
3365        cache.put(1, 10);
3366        cache.put(2, 20);
3367        cache.put(3, 30);
3368
3369        for (_k, v) in cache.iter_mut() {
3370            *v *= 2;
3371        }
3372
3373        assert_eq!(cache.get(&1), Some(&20));
3374        assert_eq!(cache.get(&2), Some(&40));
3375        assert_eq!(cache.get(&3), Some(&60));
3376    }
3377
3378    #[test]
3379    fn test_pop_panicking_key_drop_keeps_list_consistent() {
3380        use std::panic::{catch_unwind, AssertUnwindSafe};
3381        use std::sync::atomic::{AtomicBool, Ordering};
3382
3383        static ARMED: AtomicBool = AtomicBool::new(false);
3384
3385        #[derive(PartialEq, Eq, Hash)]
3386        struct PanicKey(u32);
3387        impl Drop for PanicKey {
3388            fn drop(&mut self) {
3389                if ARMED.swap(false, Ordering::SeqCst) {
3390                    panic!("PanicKey::drop");
3391                }
3392            }
3393        }
3394
3395        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
3396        cache.put(PanicKey(1), "a");
3397        cache.put(PanicKey(2), "b");
3398        cache.put(PanicKey(3), "c");
3399
3400        ARMED.store(true, Ordering::SeqCst);
3401        let _ = catch_unwind(AssertUnwindSafe(|| {
3402            cache.pop(&PanicKey(2));
3403        }));
3404
3405        cache.put(PanicKey(4), "d");
3406        cache.put(PanicKey(5), "e");
3407        let _ = cache.get(&PanicKey(3));
3408        for (_k, _v) in cache.iter() {}
3409    }
3410}
3411
3412/// Doctests for what should *not* compile
3413///
3414/// ```compile_fail
3415/// let mut cache = lru::LruCache::<u32, u32>::unbounded();
3416/// let _: &'static u32 = cache.get_or_insert(0, || 92);
3417/// ```
3418///
3419/// ```compile_fail
3420/// let mut cache = lru::LruCache::<u32, u32>::unbounded();
3421/// let _: Option<(&'static u32, _)> = cache.peek_lru();
3422/// let _: Option<(_, &'static u32)> = cache.peek_lru();
3423/// ```
3424fn _test_lifetimes() {}