Skip to main content

lru/
lib.rs

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