Coverage Report

Created: 2025-11-16 06:37

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