1#![no_std]
61
62#[cfg(feature = "hashbrown")]
63extern crate hashbrown;
64
65#[cfg(test)]
66extern crate scoped_threadpool;
67
68use alloc::borrow::Borrow;
69use alloc::boxed::Box;
70use core::fmt;
71use core::hash::{BuildHasher, Hash, Hasher};
72use core::iter::FusedIterator;
73use core::marker::PhantomData;
74use core::mem;
75use core::num::NonZeroUsize;
76use core::ptr::{self, NonNull};
77
78#[cfg(any(test, not(feature = "hashbrown")))]
79extern crate std;
80
81#[cfg(feature = "hashbrown")]
82use hashbrown::HashMap;
83#[cfg(not(feature = "hashbrown"))]
84use std::collections::HashMap;
85
86extern crate alloc;
87
88struct KeyRef<K> {
90 k: *const K,
91}
92
93impl<K: Hash> Hash for KeyRef<K> {
94 fn hash<H: Hasher>(&self, state: &mut H) {
95 unsafe { (*self.k).hash(state) }
96 }
97}
98
99impl<K: PartialEq> PartialEq for KeyRef<K> {
100 #![allow(unknown_lints)]
103 #[allow(clippy::unconditional_recursion)]
104 fn eq(&self, other: &KeyRef<K>) -> bool {
105 unsafe { (*self.k).eq(&*other.k) }
106 }
107}
108
109impl<K: Eq> Eq for KeyRef<K> {}
110
111#[repr(transparent)]
114struct KeyWrapper<K: ?Sized>(K);
115
116impl<K: ?Sized> KeyWrapper<K> {
117 fn from_ref(key: &K) -> &Self {
118 unsafe { &*(key as *const K as *const KeyWrapper<K>) }
120 }
121}
122
123impl<K: ?Sized + Hash> Hash for KeyWrapper<K> {
124 fn hash<H: Hasher>(&self, state: &mut H) {
125 self.0.hash(state)
126 }
127}
128
129impl<K: ?Sized + PartialEq> PartialEq for KeyWrapper<K> {
130 #![allow(unknown_lints)]
133 #[allow(clippy::unconditional_recursion)]
134 fn eq(&self, other: &Self) -> bool {
135 self.0.eq(&other.0)
136 }
137}
138
139impl<K: ?Sized + Eq> Eq for KeyWrapper<K> {}
140
141impl<K, Q> Borrow<KeyWrapper<Q>> for KeyRef<K>
142where
143 K: Borrow<Q>,
144 Q: ?Sized,
145{
146 fn borrow(&self) -> &KeyWrapper<Q> {
147 let key = unsafe { &*self.k }.borrow();
148 KeyWrapper::from_ref(key)
149 }
150}
151
152struct LruEntry<K, V> {
155 key: mem::MaybeUninit<K>,
156 val: mem::MaybeUninit<V>,
157 prev: *mut LruEntry<K, V>,
158 next: *mut LruEntry<K, V>,
159}
160
161impl<K, V> LruEntry<K, V> {
162 fn new(key: K, val: V) -> Self {
163 LruEntry {
164 key: mem::MaybeUninit::new(key),
165 val: mem::MaybeUninit::new(val),
166 prev: ptr::null_mut(),
167 next: ptr::null_mut(),
168 }
169 }
170
171 fn new_sigil() -> Self {
172 LruEntry {
173 key: mem::MaybeUninit::uninit(),
174 val: mem::MaybeUninit::uninit(),
175 prev: ptr::null_mut(),
176 next: ptr::null_mut(),
177 }
178 }
179}
180
181#[cfg(feature = "hashbrown")]
182pub type DefaultHasher = hashbrown::DefaultHashBuilder;
183#[cfg(not(feature = "hashbrown"))]
184pub type DefaultHasher = std::collections::hash_map::RandomState;
185
186pub struct LruCache<K, V, S = DefaultHasher> {
188 map: HashMap<KeyRef<K>, NonNull<LruEntry<K, V>>, S>,
189 cap: NonZeroUsize,
190
191 head: *mut LruEntry<K, V>,
193 tail: *mut LruEntry<K, V>,
194}
195
196impl<K, V, S> Clone for LruCache<K, V, S>
197where
198 K: Hash + PartialEq + Eq + Clone,
199 V: Clone,
200 S: BuildHasher + Clone,
201{
202 fn clone(&self) -> Self {
203 let map_cap = if self.is_unbounded() {
204 self.len()
205 } else {
206 self.cap().get()
207 };
208 let mut new_lru = LruCache::construct(
209 self.cap(),
210 HashMap::with_capacity_and_hasher(map_cap, self.map.hasher().clone()),
211 );
212
213 for (key, value) in self.iter().rev() {
214 new_lru.push(key.clone(), value.clone());
215 }
216
217 new_lru
218 }
219}
220
221impl<K: Hash + Eq, V> LruCache<K, V> {
222 pub fn new(cap: NonZeroUsize) -> LruCache<K, V> {
232 LruCache::construct(cap, HashMap::with_capacity(cap.get()))
233 }
234
235 pub fn unbounded() -> LruCache<K, V> {
245 LruCache::construct(NonZeroUsize::MAX, HashMap::default())
246 }
247}
248
249impl<K: Hash + Eq, V, S: BuildHasher> LruCache<K, V, S> {
250 pub fn with_hasher(cap: NonZeroUsize, hash_builder: S) -> LruCache<K, V, S> {
263 LruCache::construct(
264 cap,
265 HashMap::with_capacity_and_hasher(cap.into(), hash_builder),
266 )
267 }
268
269 pub fn unbounded_with_hasher(hash_builder: S) -> LruCache<K, V, S> {
281 LruCache::construct(NonZeroUsize::MAX, HashMap::with_hasher(hash_builder))
282 }
283
284 fn construct(
286 cap: NonZeroUsize,
287 map: HashMap<KeyRef<K>, NonNull<LruEntry<K, V>>, S>,
288 ) -> LruCache<K, V, S> {
289 let cache = LruCache {
292 map,
293 cap,
294 head: Box::into_raw(Box::new(LruEntry::new_sigil())),
295 tail: Box::into_raw(Box::new(LruEntry::new_sigil())),
296 };
297
298 unsafe {
299 (*cache.head).next = cache.tail;
300 (*cache.tail).prev = cache.head;
301 }
302
303 cache
304 }
305
306 fn is_unbounded(&self) -> bool {
308 self.cap() == NonZeroUsize::MAX
309 }
310
311 pub fn put(&mut self, k: K, v: V) -> Option<V> {
329 self.capturing_put(k, v, false).map(|(_, v)| v)
330 }
331
332 pub fn push(&mut self, k: K, v: V) -> Option<(K, V)> {
357 self.capturing_put(k, v, true)
358 }
359
360 fn capturing_put(&mut self, k: K, mut v: V, capture: bool) -> Option<(K, V)> {
364 let node_ref = self.map.get_mut(&KeyRef { k: &k });
365
366 match node_ref {
367 Some(node_ref) => {
368 let node_ptr: *mut LruEntry<K, V> = node_ref.as_ptr();
371
372 let node_ref = unsafe { &mut (*(*node_ptr).val.as_mut_ptr()) };
374 mem::swap(&mut v, node_ref);
375 let _ = node_ref;
376
377 self.detach(node_ptr);
378 self.attach(node_ptr);
379 Some((k, v))
380 }
381 None => {
382 let (replaced, node) = self.replace_or_create_node(k, v);
383 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
384
385 self.attach(node_ptr);
386
387 let keyref = unsafe { (*node_ptr).key.as_ptr() };
388 self.map.insert(KeyRef { k: keyref }, node);
389
390 replaced.filter(|_| capture)
391 }
392 }
393 }
394
395 #[allow(clippy::type_complexity)]
398 fn replace_or_create_node(&mut self, k: K, v: V) -> (Option<(K, V)>, NonNull<LruEntry<K, V>>) {
399 if self.len() == self.cap().get() {
400 let old_key = KeyRef {
402 k: unsafe { &(*(*(*self.tail).prev).key.as_ptr()) },
403 };
404 let old_node = self.map.remove(&old_key).unwrap();
405 let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
406
407 let replaced = unsafe {
409 (
410 mem::replace(&mut (*node_ptr).key, mem::MaybeUninit::new(k)).assume_init(),
411 mem::replace(&mut (*node_ptr).val, mem::MaybeUninit::new(v)).assume_init(),
412 )
413 };
414
415 self.detach(node_ptr);
416
417 (Some(replaced), old_node)
418 } else {
419 (None, unsafe {
422 NonNull::new_unchecked(Box::into_raw(Box::new(LruEntry::new(k, v))))
423 })
424 }
425 }
426
427 pub fn get<'a, Q>(&'a mut self, k: &Q) -> Option<&'a V>
447 where
448 K: Borrow<Q>,
449 Q: Hash + Eq + ?Sized,
450 {
451 if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
452 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
453
454 self.detach(node_ptr);
455 self.attach(node_ptr);
456
457 Some(unsafe { &*(*node_ptr).val.as_ptr() })
458 } else {
459 None
460 }
461 }
462
463 pub fn get_mut<'a, Q>(&'a mut self, k: &Q) -> Option<&'a mut V>
483 where
484 K: Borrow<Q>,
485 Q: Hash + Eq + ?Sized,
486 {
487 if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
488 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
489
490 self.detach(node_ptr);
491 self.attach(node_ptr);
492
493 Some(unsafe { &mut *(*node_ptr).val.as_mut_ptr() })
494 } else {
495 None
496 }
497 }
498
499 pub fn get_key_value<'a, Q>(&'a mut self, k: &Q) -> Option<(&'a K, &'a V)>
519 where
520 K: Borrow<Q>,
521 Q: Hash + Eq + ?Sized,
522 {
523 if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
524 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
525
526 self.detach(node_ptr);
527 self.attach(node_ptr);
528
529 Some(unsafe { (&*(*node_ptr).key.as_ptr(), &*(*node_ptr).val.as_ptr()) })
530 } else {
531 None
532 }
533 }
534
535 pub fn get_key_value_mut<'a, Q>(&'a mut self, k: &Q) -> Option<(&'a K, &'a mut V)>
558 where
559 K: Borrow<Q>,
560 Q: Hash + Eq + ?Sized,
561 {
562 if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
563 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
564
565 self.detach(node_ptr);
566 self.attach(node_ptr);
567
568 Some(unsafe {
569 (
570 &*(*node_ptr).key.as_ptr(),
571 &mut *(*node_ptr).val.as_mut_ptr(),
572 )
573 })
574 } else {
575 None
576 }
577 }
578
579 pub fn get_or_insert<F>(&mut self, k: K, f: F) -> &V
602 where
603 F: FnOnce() -> V,
604 {
605 self.get_or_insert_with_key(k, |_| f())
606 }
607
608 pub fn get_or_insert_with_key<F>(&mut self, k: K, f: F) -> &V
631 where
632 F: FnOnce(&K) -> V,
633 {
634 if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
635 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
636
637 self.detach(node_ptr);
638 self.attach(node_ptr);
639
640 unsafe { &*(*node_ptr).val.as_ptr() }
641 } else {
642 let v = f(&k);
643 let (_, node) = self.replace_or_create_node(k, v);
644 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
645
646 self.attach(node_ptr);
647
648 let keyref = unsafe { (*node_ptr).key.as_ptr() };
649 self.map.insert(KeyRef { k: keyref }, node);
650 unsafe { &*(*node_ptr).val.as_ptr() }
651 }
652 }
653
654 pub fn get_or_insert_ref<'a, Q, F>(&'a mut self, k: &'_ Q, f: F) -> &'a V
680 where
681 K: Borrow<Q>,
682 Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
683 F: FnOnce() -> V,
684 {
685 if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
686 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
687
688 self.detach(node_ptr);
689 self.attach(node_ptr);
690
691 unsafe { &*(*node_ptr).val.as_ptr() }
692 } else {
693 let v = f();
694 let (_, node) = self.replace_or_create_node(k.to_owned(), v);
695 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
696
697 self.attach(node_ptr);
698
699 let keyref = unsafe { (*node_ptr).key.as_ptr() };
700 self.map.insert(KeyRef { k: keyref }, node);
701 unsafe { &*(*node_ptr).val.as_ptr() }
702 }
703 }
704
705 pub fn try_get_or_insert<F, E>(&mut self, k: K, f: F) -> Result<&V, E>
733 where
734 F: FnOnce() -> Result<V, E>,
735 {
736 self.try_get_or_insert_with_key(k, |_| f())
737 }
738
739 pub fn try_get_or_insert_with_key<F, E>(&mut self, k: K, f: F) -> Result<&V, E>
767 where
768 F: FnOnce(&K) -> Result<V, E>,
769 {
770 if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
771 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
772
773 self.detach(node_ptr);
774 self.attach(node_ptr);
775
776 unsafe { Ok(&*(*node_ptr).val.as_ptr()) }
777 } else {
778 let v = f(&k)?;
779 let (_, node) = self.replace_or_create_node(k, v);
780 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
781
782 self.attach(node_ptr);
783
784 let keyref = unsafe { (*node_ptr).key.as_ptr() };
785 self.map.insert(KeyRef { k: keyref }, node);
786 Ok(unsafe { &*(*node_ptr).val.as_ptr() })
787 }
788 }
789
790 pub fn try_get_or_insert_ref<'a, Q, F, E>(&'a mut self, k: &'_ Q, f: F) -> Result<&'a V, E>
820 where
821 K: Borrow<Q>,
822 Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
823 F: FnOnce() -> Result<V, E>,
824 {
825 if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
826 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
827
828 self.detach(node_ptr);
829 self.attach(node_ptr);
830
831 unsafe { Ok(&*(*node_ptr).val.as_ptr()) }
832 } else {
833 let v = f()?;
834 let (_, node) = self.replace_or_create_node(k.to_owned(), v);
835 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
836
837 self.attach(node_ptr);
838
839 let keyref = unsafe { (*node_ptr).key.as_ptr() };
840 self.map.insert(KeyRef { k: keyref }, node);
841 Ok(unsafe { &*(*node_ptr).val.as_ptr() })
842 }
843 }
844
845 pub fn get_or_insert_mut<F>(&mut self, k: K, f: F) -> &mut V
868 where
869 F: FnOnce() -> V,
870 {
871 self.get_or_insert_mut_with_key(k, |_| f())
872 }
873
874 pub fn get_or_insert_mut_with_key<F>(&mut self, k: K, f: F) -> &mut V
898 where
899 F: FnOnce(&K) -> V,
900 {
901 if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
902 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
903
904 self.detach(node_ptr);
905 self.attach(node_ptr);
906
907 unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
908 } else {
909 let v = f(&k);
910 let (_, node) = self.replace_or_create_node(k, v);
911 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
912
913 self.attach(node_ptr);
914
915 let keyref = unsafe { (*node_ptr).key.as_ptr() };
916 self.map.insert(KeyRef { k: keyref }, node);
917 unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
918 }
919 }
920
921 pub fn get_or_insert_mut_ref<'a, Q, F>(&'a mut self, k: &'_ Q, f: F) -> &'a mut V
946 where
947 K: Borrow<Q>,
948 Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
949 F: FnOnce() -> V,
950 {
951 if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
952 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
953
954 self.detach(node_ptr);
955 self.attach(node_ptr);
956
957 unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
958 } else {
959 let v = f();
960 let (_, node) = self.replace_or_create_node(k.to_owned(), v);
961 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
962
963 self.attach(node_ptr);
964
965 let keyref = unsafe { (*node_ptr).key.as_ptr() };
966 self.map.insert(KeyRef { k: keyref }, node);
967 unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
968 }
969 }
970
971 pub fn try_get_or_insert_mut<F, E>(&mut self, k: K, f: F) -> Result<&mut V, E>
1000 where
1001 F: FnOnce() -> Result<V, E>,
1002 {
1003 self.try_get_or_insert_mut_with_key(k, |_| f())
1004 }
1005
1006 pub fn try_get_or_insert_mut_with_key<F, E>(&mut self, k: K, f: F) -> Result<&mut V, E>
1034 where
1035 F: FnOnce(&K) -> Result<V, E>,
1036 {
1037 if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
1038 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1039
1040 self.detach(node_ptr);
1041 self.attach(node_ptr);
1042
1043 unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
1044 } else {
1045 let v = f(&k)?;
1046 let (_, node) = self.replace_or_create_node(k, v);
1047 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1048
1049 self.attach(node_ptr);
1050
1051 let keyref = unsafe { (*node_ptr).key.as_ptr() };
1052 self.map.insert(KeyRef { k: keyref }, node);
1053 unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
1054 }
1055 }
1056
1057 pub fn try_get_or_insert_mut_ref<'a, Q, F, E>(
1089 &'a mut self,
1090 k: &'_ Q,
1091 f: F,
1092 ) -> Result<&'a mut V, E>
1093 where
1094 K: Borrow<Q>,
1095 Q: Hash + Eq + ?Sized + alloc::borrow::ToOwned<Owned = K>,
1096 F: FnOnce() -> Result<V, E>,
1097 {
1098 if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
1099 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1100
1101 self.detach(node_ptr);
1102 self.attach(node_ptr);
1103
1104 unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
1105 } else {
1106 let v = f()?;
1107 let (_, node) = self.replace_or_create_node(k.to_owned(), v);
1108 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1109
1110 self.attach(node_ptr);
1111
1112 let keyref = unsafe { (*node_ptr).key.as_ptr() };
1113 self.map.insert(KeyRef { k: keyref }, node);
1114 unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
1115 }
1116 }
1117
1118 pub fn peek<'a, Q>(&'a self, k: &Q) -> Option<&'a V>
1136 where
1137 K: Borrow<Q>,
1138 Q: Hash + Eq + ?Sized,
1139 {
1140 self.map
1141 .get(KeyWrapper::from_ref(k))
1142 .map(|node| unsafe { &*node.as_ref().val.as_ptr() })
1143 }
1144
1145 pub fn peek_mut<'a, Q>(&'a mut self, k: &Q) -> Option<&'a mut V>
1163 where
1164 K: Borrow<Q>,
1165 Q: Hash + Eq + ?Sized,
1166 {
1167 match self.map.get_mut(KeyWrapper::from_ref(k)) {
1168 None => None,
1169 Some(node) => Some(unsafe { &mut *(*node.as_ptr()).val.as_mut_ptr() }),
1170 }
1171 }
1172
1173 pub fn peek_lru(&self) -> Option<(&K, &V)> {
1190 if self.is_empty() {
1191 return None;
1192 }
1193
1194 let (key, val);
1195 unsafe {
1196 let node = (*self.tail).prev;
1197 key = &(*(*node).key.as_ptr()) as &K;
1198 val = &(*(*node).val.as_ptr()) as &V;
1199 }
1200
1201 Some((key, val))
1202 }
1203
1204 pub fn peek_mru(&self) -> Option<(&K, &V)> {
1221 if self.is_empty() {
1222 return None;
1223 }
1224
1225 let (key, val);
1226 unsafe {
1227 let node: *mut LruEntry<K, V> = (*self.head).next;
1228 key = &(*(*node).key.as_ptr()) as &K;
1229 val = &(*(*node).val.as_ptr()) as &V;
1230 }
1231
1232 Some((key, val))
1233 }
1234
1235 pub fn contains<Q>(&self, k: &Q) -> bool
1254 where
1255 K: Borrow<Q>,
1256 Q: Hash + Eq + ?Sized,
1257 {
1258 self.map.contains_key(KeyWrapper::from_ref(k))
1259 }
1260
1261 pub fn pop<Q>(&mut self, k: &Q) -> Option<V>
1279 where
1280 K: Borrow<Q>,
1281 Q: Hash + Eq + ?Sized,
1282 {
1283 match self.map.remove(KeyWrapper::from_ref(k)) {
1284 None => None,
1285 Some(old_node) => {
1286 let mut old_node = unsafe {
1287 let mut old_node = *Box::from_raw(old_node.as_ptr());
1288 ptr::drop_in_place(old_node.key.as_mut_ptr());
1289
1290 old_node
1291 };
1292
1293 self.detach(&mut old_node);
1294
1295 let LruEntry { key: _, val, .. } = old_node;
1296 unsafe { Some(val.assume_init()) }
1297 }
1298 }
1299 }
1300
1301 pub fn pop_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
1321 where
1322 K: Borrow<Q>,
1323 Q: Hash + Eq + ?Sized,
1324 {
1325 match self.map.remove(KeyWrapper::from_ref(k)) {
1326 None => None,
1327 Some(old_node) => {
1328 let mut old_node = unsafe { *Box::from_raw(old_node.as_ptr()) };
1329
1330 self.detach(&mut old_node);
1331
1332 let LruEntry { key, val, .. } = old_node;
1333 unsafe { Some((key.assume_init(), val.assume_init())) }
1334 }
1335 }
1336 }
1337
1338 pub fn pop_lru(&mut self) -> Option<(K, V)> {
1359 let node = self.remove_last()?;
1360 let node = *node;
1362 let LruEntry { key, val, .. } = node;
1363 unsafe { Some((key.assume_init(), val.assume_init())) }
1364 }
1365
1366 pub fn pop_mru(&mut self) -> Option<(K, V)> {
1387 let node = self.remove_first()?;
1388 let node = *node;
1390 let LruEntry { key, val, .. } = node;
1391 unsafe { Some((key.assume_init(), val.assume_init())) }
1392 }
1393
1394 pub fn promote<Q>(&mut self, k: &Q) -> bool
1421 where
1422 K: Borrow<Q>,
1423 Q: Hash + Eq + ?Sized,
1424 {
1425 if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
1426 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1427 self.detach(node_ptr);
1428 self.attach(node_ptr);
1429 true
1430 } else {
1431 false
1432 }
1433 }
1434
1435 pub fn demote<Q>(&mut self, k: &Q) -> bool
1464 where
1465 K: Borrow<Q>,
1466 Q: Hash + Eq + ?Sized,
1467 {
1468 if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
1469 let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1470 self.detach(node_ptr);
1471 self.attach_last(node_ptr);
1472 true
1473 } else {
1474 false
1475 }
1476 }
1477
1478 pub fn find_and_promote<F>(&mut self, mut predicate: F) -> Option<(&K, &V)>
1499 where
1500 F: FnMut((&K, &V)) -> bool,
1501 {
1502 let mut node = unsafe { (*self.head).next };
1503
1504 while !core::ptr::eq(node, self.tail) {
1505 let matches = {
1506 let key = unsafe { &*(*node).key.as_ptr() };
1507 let val = unsafe { &*(*node).val.as_ptr() };
1508 predicate((key, val))
1509 };
1510
1511 if matches {
1512 self.detach(node);
1513 self.attach(node);
1514 return Some(unsafe { (&*(*node).key.as_ptr(), &*(*node).val.as_ptr()) });
1515 }
1516
1517 unsafe { node = (*node).next };
1518 }
1519
1520 None
1521 }
1522
1523 pub fn len(&self) -> usize {
1543 self.map.len()
1544 }
1545
1546 pub fn is_empty(&self) -> bool {
1560 self.map.len() == 0
1561 }
1562
1563 pub fn cap(&self) -> NonZeroUsize {
1574 self.cap
1575 }
1576
1577 pub fn resize(&mut self, cap: NonZeroUsize) {
1600 if cap == self.cap {
1602 return;
1603 }
1604
1605 while self.map.len() > cap.get() {
1606 self.pop_lru();
1607 }
1608 self.map.shrink_to_fit();
1609
1610 self.cap = cap;
1611 }
1612
1613 pub fn clear(&mut self) {
1633 while self.pop_lru().is_some() {}
1634 }
1635
1636 pub fn iter(&self) -> Iter<'_, K, V> {
1655 Iter {
1656 len: self.len(),
1657 ptr: unsafe { (*self.head).next },
1658 end: unsafe { (*self.tail).prev },
1659 phantom: PhantomData,
1660 }
1661 }
1662
1663 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
1691 IterMut {
1692 len: self.len(),
1693 ptr: unsafe { (*self.head).next },
1694 end: unsafe { (*self.tail).prev },
1695 phantom: PhantomData,
1696 }
1697 }
1698
1699 fn remove_first(&mut self) -> Option<Box<LruEntry<K, V>>> {
1700 let next;
1701 unsafe { next = (*self.head).next }
1702 if !core::ptr::eq(next, self.tail) {
1703 let old_key = KeyRef {
1704 k: unsafe { &(*(*(*self.head).next).key.as_ptr()) },
1705 };
1706 let old_node = self.map.remove(&old_key).unwrap();
1707 let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
1708 self.detach(node_ptr);
1709 unsafe { Some(Box::from_raw(node_ptr)) }
1710 } else {
1711 None
1712 }
1713 }
1714
1715 fn remove_last(&mut self) -> Option<Box<LruEntry<K, V>>> {
1716 let prev;
1717 unsafe { prev = (*self.tail).prev }
1718 if !core::ptr::eq(prev, self.head) {
1719 let old_key = KeyRef {
1720 k: unsafe { &(*(*(*self.tail).prev).key.as_ptr()) },
1721 };
1722 let old_node = self.map.remove(&old_key).unwrap();
1723 let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
1724 self.detach(node_ptr);
1725 unsafe { Some(Box::from_raw(node_ptr)) }
1726 } else {
1727 None
1728 }
1729 }
1730
1731 fn detach(&mut self, node: *mut LruEntry<K, V>) {
1732 unsafe {
1733 (*(*node).prev).next = (*node).next;
1734 (*(*node).next).prev = (*node).prev;
1735 }
1736 }
1737
1738 fn attach(&mut self, node: *mut LruEntry<K, V>) {
1740 unsafe {
1741 (*node).next = (*self.head).next;
1742 (*node).prev = self.head;
1743 (*self.head).next = node;
1744 (*(*node).next).prev = node;
1745 }
1746 }
1747
1748 fn attach_last(&mut self, node: *mut LruEntry<K, V>) {
1750 unsafe {
1751 (*node).next = self.tail;
1752 (*node).prev = (*self.tail).prev;
1753 (*self.tail).prev = node;
1754 (*(*node).prev).next = node;
1755 }
1756 }
1757}
1758
1759impl<K, V, S> Drop for LruCache<K, V, S> {
1760 fn drop(&mut self) {
1761 self.map.drain().for_each(|(_, node)| unsafe {
1762 let mut node = *Box::from_raw(node.as_ptr());
1763 ptr::drop_in_place((node).key.as_mut_ptr());
1764 ptr::drop_in_place((node).val.as_mut_ptr());
1765 });
1766 let _head = unsafe { *Box::from_raw(self.head) };
1770 let _tail = unsafe { *Box::from_raw(self.tail) };
1771 }
1772}
1773
1774impl<'a, K: Hash + Eq, V, S: BuildHasher> IntoIterator for &'a LruCache<K, V, S> {
1775 type Item = (&'a K, &'a V);
1776 type IntoIter = Iter<'a, K, V>;
1777
1778 fn into_iter(self) -> Iter<'a, K, V> {
1779 self.iter()
1780 }
1781}
1782
1783impl<'a, K: Hash + Eq, V, S: BuildHasher> IntoIterator for &'a mut LruCache<K, V, S> {
1784 type Item = (&'a K, &'a mut V);
1785 type IntoIter = IterMut<'a, K, V>;
1786
1787 fn into_iter(self) -> IterMut<'a, K, V> {
1788 self.iter_mut()
1789 }
1790}
1791
1792unsafe impl<K: Send, V: Send, S: Send> Send for LruCache<K, V, S> {}
1796unsafe impl<K: Sync, V: Sync, S: Sync> Sync for LruCache<K, V, S> {}
1797
1798impl<K: Hash + Eq, V, S: BuildHasher> fmt::Debug for LruCache<K, V, S> {
1799 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1800 f.debug_struct("LruCache")
1801 .field("len", &self.len())
1802 .field("cap", &self.cap())
1803 .finish()
1804 }
1805}
1806
1807pub struct Iter<'a, K: 'a, V: 'a> {
1815 len: usize,
1816
1817 ptr: *const LruEntry<K, V>,
1818 end: *const LruEntry<K, V>,
1819
1820 phantom: PhantomData<&'a K>,
1821}
1822
1823impl<'a, K, V> Iterator for Iter<'a, K, V> {
1824 type Item = (&'a K, &'a V);
1825
1826 fn next(&mut self) -> Option<(&'a K, &'a V)> {
1827 if self.len == 0 {
1828 return None;
1829 }
1830
1831 let key = unsafe { &(*(*self.ptr).key.as_ptr()) as &K };
1832 let val = unsafe { &(*(*self.ptr).val.as_ptr()) as &V };
1833
1834 self.len -= 1;
1835 self.ptr = unsafe { (*self.ptr).next };
1836
1837 Some((key, val))
1838 }
1839
1840 fn size_hint(&self) -> (usize, Option<usize>) {
1841 (self.len, Some(self.len))
1842 }
1843
1844 fn count(self) -> usize {
1845 self.len
1846 }
1847}
1848
1849impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
1850 fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
1851 if self.len == 0 {
1852 return None;
1853 }
1854
1855 let key = unsafe { &(*(*self.end).key.as_ptr()) as &K };
1856 let val = unsafe { &(*(*self.end).val.as_ptr()) as &V };
1857
1858 self.len -= 1;
1859 self.end = unsafe { (*self.end).prev };
1860
1861 Some((key, val))
1862 }
1863}
1864
1865impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {}
1866impl<'a, K, V> FusedIterator for Iter<'a, K, V> {}
1867
1868impl<'a, K, V> Clone for Iter<'a, K, V> {
1869 fn clone(&self) -> Iter<'a, K, V> {
1870 Iter {
1871 len: self.len,
1872 ptr: self.ptr,
1873 end: self.end,
1874 phantom: PhantomData,
1875 }
1876 }
1877}
1878
1879unsafe impl<'a, K: Send, V: Send> Send for Iter<'a, K, V> {}
1882unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
1883
1884pub struct IterMut<'a, K: 'a, V: 'a> {
1892 len: usize,
1893
1894 ptr: *mut LruEntry<K, V>,
1895 end: *mut LruEntry<K, V>,
1896
1897 phantom: PhantomData<&'a K>,
1898}
1899
1900impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1901 type Item = (&'a K, &'a mut V);
1902
1903 fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
1904 if self.len == 0 {
1905 return None;
1906 }
1907
1908 let key = unsafe { &(*(*self.ptr).key.as_ptr()) as &K };
1909 let val = unsafe { &mut (*(*self.ptr).val.as_mut_ptr()) as &mut V };
1910
1911 self.len -= 1;
1912 self.ptr = unsafe { (*self.ptr).next };
1913
1914 Some((key, val))
1915 }
1916
1917 fn size_hint(&self) -> (usize, Option<usize>) {
1918 (self.len, Some(self.len))
1919 }
1920
1921 fn count(self) -> usize {
1922 self.len
1923 }
1924}
1925
1926impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> {
1927 fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
1928 if self.len == 0 {
1929 return None;
1930 }
1931
1932 let key = unsafe { &(*(*self.end).key.as_ptr()) as &K };
1933 let val = unsafe { &mut (*(*self.end).val.as_mut_ptr()) as &mut V };
1934
1935 self.len -= 1;
1936 self.end = unsafe { (*self.end).prev };
1937
1938 Some((key, val))
1939 }
1940}
1941
1942impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {}
1943impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}
1944
1945unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {}
1948unsafe impl<'a, K: Sync, V: Sync> Sync for IterMut<'a, K, V> {}
1949
1950pub struct IntoIter<K, V>
1958where
1959 K: Hash + Eq,
1960{
1961 cache: LruCache<K, V>,
1962}
1963
1964impl<K, V> Iterator for IntoIter<K, V>
1965where
1966 K: Hash + Eq,
1967{
1968 type Item = (K, V);
1969
1970 fn next(&mut self) -> Option<(K, V)> {
1971 self.cache.pop_lru()
1972 }
1973
1974 fn size_hint(&self) -> (usize, Option<usize>) {
1975 let len = self.cache.len();
1976 (len, Some(len))
1977 }
1978
1979 fn count(self) -> usize {
1980 self.cache.len()
1981 }
1982}
1983
1984impl<K, V> ExactSizeIterator for IntoIter<K, V> where K: Hash + Eq {}
1985impl<K, V> FusedIterator for IntoIter<K, V> where K: Hash + Eq {}
1986
1987impl<K: Hash + Eq, V> IntoIterator for LruCache<K, V> {
1988 type Item = (K, V);
1989 type IntoIter = IntoIter<K, V>;
1990
1991 fn into_iter(self) -> IntoIter<K, V> {
1992 IntoIter { cache: self }
1993 }
1994}
1995
1996#[cfg(test)]
1997mod tests {
1998 use super::LruCache;
1999 use core::{fmt::Debug, num::NonZeroUsize};
2000 use scoped_threadpool::Pool;
2001 use std::rc::Rc;
2002 use std::sync::atomic::{AtomicUsize, Ordering};
2003
2004 fn assert_opt_eq<V: PartialEq + Debug>(opt: Option<&V>, v: V) {
2005 assert!(opt.is_some());
2006 assert_eq!(opt.unwrap(), &v);
2007 }
2008
2009 fn assert_opt_eq_mut<V: PartialEq + Debug>(opt: Option<&mut V>, v: V) {
2010 assert!(opt.is_some());
2011 assert_eq!(opt.unwrap(), &v);
2012 }
2013
2014 fn assert_opt_eq_tuple<K: PartialEq + Debug, V: PartialEq + Debug>(
2015 opt: Option<(&K, &V)>,
2016 kv: (K, V),
2017 ) {
2018 assert!(opt.is_some());
2019 let res = opt.unwrap();
2020 assert_eq!(res.0, &kv.0);
2021 assert_eq!(res.1, &kv.1);
2022 }
2023
2024 fn assert_opt_eq_mut_tuple<K: PartialEq + Debug, V: PartialEq + Debug>(
2025 opt: Option<(&K, &mut V)>,
2026 kv: (K, V),
2027 ) {
2028 assert!(opt.is_some());
2029 let res = opt.unwrap();
2030 assert_eq!(res.0, &kv.0);
2031 assert_eq!(res.1, &kv.1);
2032 }
2033
2034 #[test]
2035 fn test_unbounded() {
2036 let mut cache = LruCache::unbounded();
2037 for i in 0..13370 {
2038 cache.put(i, ());
2039 }
2040 assert_eq!(cache.len(), 13370);
2041 }
2042
2043 #[test]
2044 #[cfg(feature = "hashbrown")]
2045 fn test_with_hasher() {
2046 use core::num::NonZeroUsize;
2047
2048 use hashbrown::DefaultHashBuilder;
2049
2050 let s = DefaultHashBuilder::default();
2051 let mut cache = LruCache::with_hasher(NonZeroUsize::new(16).unwrap(), s);
2052
2053 for i in 0..13370 {
2054 cache.put(i, ());
2055 }
2056 assert_eq!(cache.len(), 16);
2057 }
2058
2059 #[test]
2060 fn test_put_and_get() {
2061 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2062 assert!(cache.is_empty());
2063
2064 assert_eq!(cache.put("apple", "red"), None);
2065 assert_eq!(cache.put("banana", "yellow"), None);
2066
2067 assert_eq!(cache.cap().get(), 2);
2068 assert_eq!(cache.len(), 2);
2069 assert!(!cache.is_empty());
2070 assert_opt_eq(cache.get(&"apple"), "red");
2071 assert_opt_eq(cache.get(&"banana"), "yellow");
2072 }
2073
2074 #[test]
2075 fn test_put_and_get_or_insert() {
2076 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2077 assert!(cache.is_empty());
2078
2079 assert_eq!(cache.put("apple", "red"), None);
2080 assert_eq!(cache.put("banana", "yellow"), None);
2081
2082 assert_eq!(cache.cap().get(), 2);
2083 assert_eq!(cache.len(), 2);
2084 assert!(!cache.is_empty());
2085 assert_eq!(cache.get_or_insert("apple", || "orange"), &"red");
2086 assert_eq!(cache.get_or_insert("banana", || "orange"), &"yellow");
2087 assert_eq!(cache.get_or_insert("lemon", || "orange"), &"orange");
2088 assert_eq!(cache.get_or_insert("lemon", || "red"), &"orange");
2089 }
2090
2091 #[test]
2092 fn test_put_and_get_or_insert_with_key() {
2093 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2094 assert!(cache.is_empty());
2095
2096 assert_eq!(cache.put("apple", 2), None);
2097 assert_eq!(cache.put("banana", 8), None);
2098
2099 assert_eq!(cache.cap().get(), 2);
2100 assert_eq!(cache.len(), 2);
2101 assert!(!cache.is_empty());
2102 assert_eq!(cache.get_or_insert_with_key("apple", |k| k.len()), &2);
2103 assert_eq!(cache.get_or_insert_with_key("banana", |k| k.len()), &8);
2104 assert_eq!(cache.get_or_insert_with_key("lemon", |k| k.len()), &5);
2105 assert_eq!(cache.get_or_insert_with_key("lemon", |k| k.len() + 3), &5);
2106 }
2107
2108 #[test]
2109 fn test_get_or_insert_ref() {
2110 use alloc::borrow::ToOwned;
2111 use alloc::string::String;
2112
2113 let key1 = Rc::new("1".to_owned());
2114 let key2 = Rc::new("2".to_owned());
2115 let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
2116 assert!(cache.is_empty());
2117 assert_eq!(cache.get_or_insert_ref(&key1, || "One".to_owned()), "One");
2118 assert_eq!(cache.get_or_insert_ref(&key2, || "Two".to_owned()), "Two");
2119 assert_eq!(cache.len(), 2);
2120 assert!(!cache.is_empty());
2121 assert_eq!(
2122 cache.get_or_insert_ref(&key2, || "Not two".to_owned()),
2123 "Two"
2124 );
2125 assert_eq!(
2126 cache.get_or_insert_ref(&key2, || "Again not two".to_owned()),
2127 "Two"
2128 );
2129 assert_eq!(Rc::strong_count(&key1), 2);
2130 assert_eq!(Rc::strong_count(&key2), 2);
2131 }
2132
2133 #[test]
2134 fn test_try_get_or_insert() {
2135 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2136
2137 assert_eq!(
2138 cache.try_get_or_insert::<_, &str>("apple", || Ok("red")),
2139 Ok(&"red")
2140 );
2141 assert_eq!(
2142 cache.try_get_or_insert::<_, &str>("apple", || Err("failed")),
2143 Ok(&"red")
2144 );
2145 assert_eq!(
2146 cache.try_get_or_insert::<_, &str>("banana", || Ok("orange")),
2147 Ok(&"orange")
2148 );
2149 assert_eq!(
2150 cache.try_get_or_insert::<_, &str>("lemon", || Err("failed")),
2151 Err("failed")
2152 );
2153 assert_eq!(
2154 cache.try_get_or_insert::<_, &str>("banana", || Err("failed")),
2155 Ok(&"orange")
2156 );
2157 }
2158
2159 #[test]
2160 fn test_try_get_or_insert_with_key() {
2161 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2162
2163 assert_eq!(
2164 cache.try_get_or_insert_with_key::<_, &str>("apple", |k| Ok(k.len())),
2165 Ok(&5)
2166 );
2167 assert_eq!(
2168 cache.try_get_or_insert_with_key::<_, &str>("apple", |_| Err("failed")),
2169 Ok(&5)
2170 );
2171 assert_eq!(
2172 cache.try_get_or_insert_with_key::<_, &str>("banana", |k| Ok(k.len())),
2173 Ok(&6)
2174 );
2175 assert_eq!(
2176 cache.try_get_or_insert_with_key::<_, &str>("lemon", |_| Err("failed")),
2177 Err("failed")
2178 );
2179 assert_eq!(
2180 cache.try_get_or_insert_with_key::<_, &str>("banana", |_| Err("failed")),
2181 Ok(&6)
2182 );
2183 }
2184
2185 #[test]
2186 fn test_try_get_or_insert_ref() {
2187 use alloc::borrow::ToOwned;
2188 use alloc::string::String;
2189
2190 let key1 = Rc::new("1".to_owned());
2191 let key2 = Rc::new("2".to_owned());
2192 let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
2193 let f = || -> Result<String, ()> { Err(()) };
2194 let a = || -> Result<String, ()> { Ok("One".to_owned()) };
2195 let b = || -> Result<String, ()> { Ok("Two".to_owned()) };
2196 assert_eq!(cache.try_get_or_insert_ref(&key1, a), Ok(&"One".to_owned()));
2197 assert_eq!(cache.try_get_or_insert_ref(&key2, f), Err(()));
2198 assert_eq!(cache.try_get_or_insert_ref(&key2, b), Ok(&"Two".to_owned()));
2199 assert_eq!(cache.try_get_or_insert_ref(&key2, a), Ok(&"Two".to_owned()));
2200 assert_eq!(cache.len(), 2);
2201 assert_eq!(Rc::strong_count(&key1), 2);
2202 assert_eq!(Rc::strong_count(&key2), 2);
2203 }
2204
2205 #[test]
2206 fn test_put_and_get_or_insert_mut() {
2207 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2208 assert!(cache.is_empty());
2209
2210 assert_eq!(cache.put("apple", "red"), None);
2211 assert_eq!(cache.put("banana", "yellow"), None);
2212
2213 assert_eq!(cache.cap().get(), 2);
2214 assert_eq!(cache.len(), 2);
2215
2216 let v = cache.get_or_insert_mut("apple", || "orange");
2217 assert_eq!(v, &"red");
2218 *v = "blue";
2219
2220 assert_eq!(cache.get_or_insert_mut("apple", || "orange"), &"blue");
2221 assert_eq!(cache.get_or_insert_mut("banana", || "orange"), &"yellow");
2222 assert_eq!(cache.get_or_insert_mut("lemon", || "orange"), &"orange");
2223 assert_eq!(cache.get_or_insert_mut("lemon", || "red"), &"orange");
2224 }
2225
2226 #[test]
2227 fn test_put_and_get_or_insert_mut_with_key() {
2228 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2229 assert!(cache.is_empty());
2230
2231 assert_eq!(cache.put("apple", 2), None);
2232 assert_eq!(cache.put("banana", 8), None);
2233
2234 assert_eq!(cache.cap().get(), 2);
2235 assert_eq!(cache.len(), 2);
2236
2237 let v = cache.get_or_insert_mut_with_key("apple", |k| k.len());
2238 assert_eq!(v, &2);
2239 *v = 4;
2240
2241 assert_eq!(cache.get_or_insert_mut_with_key("apple", |k| k.len()), &4);
2242 assert_eq!(cache.get_or_insert_mut_with_key("banana", |k| k.len()), &8);
2243 assert_eq!(cache.get_or_insert_mut_with_key("lemon", |k| k.len()), &5);
2244 assert_eq!(cache.get_or_insert_mut_with_key("lemon", |_| 0), &5);
2245 }
2246
2247 #[test]
2248 fn test_get_or_insert_mut_ref() {
2249 use alloc::borrow::ToOwned;
2250 use alloc::string::String;
2251
2252 let key1 = Rc::new("1".to_owned());
2253 let key2 = Rc::new("2".to_owned());
2254 let mut cache = LruCache::<Rc<String>, &'static str>::new(NonZeroUsize::new(2).unwrap());
2255 assert_eq!(cache.get_or_insert_mut_ref(&key1, || "One"), &mut "One");
2256 let v = cache.get_or_insert_mut_ref(&key2, || "Two");
2257 *v = "New two";
2258 assert_eq!(cache.get_or_insert_mut_ref(&key2, || "Two"), &mut "New two");
2259 assert_eq!(Rc::strong_count(&key1), 2);
2260 assert_eq!(Rc::strong_count(&key2), 2);
2261 }
2262
2263 #[test]
2264 fn test_try_get_or_insert_mut() {
2265 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2266
2267 cache.put(1, "a");
2268 cache.put(2, "b");
2269 cache.put(2, "c");
2270
2271 let f = || -> Result<&str, &str> { Err("failed") };
2272 let a = || -> Result<&str, &str> { Ok("a") };
2273 let b = || -> Result<&str, &str> { Ok("b") };
2274 if let Ok(v) = cache.try_get_or_insert_mut(2, a) {
2275 *v = "d";
2276 }
2277 assert_eq!(cache.try_get_or_insert_mut(2, a), Ok(&mut "d"));
2278 assert_eq!(cache.try_get_or_insert_mut(3, f), Err("failed"));
2279 assert_eq!(cache.try_get_or_insert_mut(4, b), Ok(&mut "b"));
2280 assert_eq!(cache.try_get_or_insert_mut(4, a), Ok(&mut "b"));
2281 }
2282
2283 #[test]
2284 fn test_try_get_or_insert_mut_with_key() {
2285 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2286
2287 cache.put("One", 1);
2288 cache.put("Two", 2);
2289 cache.put("Two", 3);
2290
2291 let f = |_: &&str| -> Result<usize, &str> { Err("failed") };
2292 let len = |k: &&str| -> Result<usize, &str> { Ok(k.len()) };
2293 let zero = |_: &&str| -> Result<usize, &str> { Ok(0) };
2294 if let Ok(v) = cache.try_get_or_insert_mut_with_key("Two", f) {
2295 *v = 6;
2296 }
2297 assert_eq!(cache.try_get_or_insert_mut_with_key("Two", len), Ok(&mut 6));
2298 assert_eq!(
2299 cache.try_get_or_insert_mut_with_key("Three", f),
2300 Err("failed")
2301 );
2302 assert_eq!(
2303 cache.try_get_or_insert_mut_with_key("Four", len),
2304 Ok(&mut 4)
2305 );
2306 assert_eq!(
2307 cache.try_get_or_insert_mut_with_key("Four", zero),
2308 Ok(&mut 4)
2309 );
2310 }
2311
2312 #[test]
2313 fn test_try_get_or_insert_mut_ref() {
2314 use alloc::borrow::ToOwned;
2315 use alloc::string::String;
2316
2317 let key1 = Rc::new("1".to_owned());
2318 let key2 = Rc::new("2".to_owned());
2319 let mut cache = LruCache::<Rc<String>, String>::new(NonZeroUsize::new(2).unwrap());
2320 let f = || -> Result<String, ()> { Err(()) };
2321 let a = || -> Result<String, ()> { Ok("One".to_owned()) };
2322 let b = || -> Result<String, ()> { Ok("Two".to_owned()) };
2323 assert_eq!(
2324 cache.try_get_or_insert_mut_ref(&key1, a),
2325 Ok(&mut "One".to_owned())
2326 );
2327 assert_eq!(cache.try_get_or_insert_mut_ref(&key2, f), Err(()));
2328 if let Ok(v) = cache.try_get_or_insert_mut_ref(&key2, b) {
2329 assert_eq!(v, &mut "Two");
2330 *v = "New two".to_owned();
2331 }
2332 assert_eq!(
2333 cache.try_get_or_insert_mut_ref(&key2, a),
2334 Ok(&mut "New two".to_owned())
2335 );
2336 assert_eq!(Rc::strong_count(&key1), 2);
2337 assert_eq!(Rc::strong_count(&key2), 2);
2338 }
2339
2340 #[test]
2341 fn test_put_and_get_mut() {
2342 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2343
2344 cache.put("apple", "red");
2345 cache.put("banana", "yellow");
2346
2347 assert_eq!(cache.cap().get(), 2);
2348 assert_eq!(cache.len(), 2);
2349 assert_opt_eq_mut(cache.get_mut(&"apple"), "red");
2350 assert_opt_eq_mut(cache.get_mut(&"banana"), "yellow");
2351 }
2352
2353 #[test]
2354 fn test_get_mut_and_update() {
2355 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2356
2357 cache.put("apple", 1);
2358 cache.put("banana", 3);
2359
2360 {
2361 let v = cache.get_mut(&"apple").unwrap();
2362 *v = 4;
2363 }
2364
2365 assert_eq!(cache.cap().get(), 2);
2366 assert_eq!(cache.len(), 2);
2367 assert_opt_eq_mut(cache.get_mut(&"apple"), 4);
2368 assert_opt_eq_mut(cache.get_mut(&"banana"), 3);
2369 }
2370
2371 #[test]
2372 fn test_put_update() {
2373 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2374
2375 assert_eq!(cache.put("apple", "red"), None);
2376 assert_eq!(cache.put("apple", "green"), Some("red"));
2377
2378 assert_eq!(cache.len(), 1);
2379 assert_opt_eq(cache.get(&"apple"), "green");
2380 }
2381
2382 #[test]
2383 fn test_put_removes_oldest() {
2384 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2385
2386 assert_eq!(cache.put("apple", "red"), None);
2387 assert_eq!(cache.put("banana", "yellow"), None);
2388 assert_eq!(cache.put("pear", "green"), None);
2389
2390 assert!(cache.get(&"apple").is_none());
2391 assert_opt_eq(cache.get(&"banana"), "yellow");
2392 assert_opt_eq(cache.get(&"pear"), "green");
2393
2394 assert_eq!(cache.put("apple", "green"), None);
2397 assert_eq!(cache.put("tomato", "red"), None);
2398
2399 assert!(cache.get(&"pear").is_none());
2400 assert_opt_eq(cache.get(&"apple"), "green");
2401 assert_opt_eq(cache.get(&"tomato"), "red");
2402 }
2403
2404 #[test]
2405 fn test_peek() {
2406 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2407
2408 cache.put("apple", "red");
2409 cache.put("banana", "yellow");
2410
2411 assert_opt_eq(cache.peek(&"banana"), "yellow");
2412 assert_opt_eq(cache.peek(&"apple"), "red");
2413
2414 cache.put("pear", "green");
2415
2416 assert!(cache.peek(&"apple").is_none());
2417 assert_opt_eq(cache.peek(&"banana"), "yellow");
2418 assert_opt_eq(cache.peek(&"pear"), "green");
2419 }
2420
2421 #[test]
2422 fn test_peek_mut() {
2423 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2424
2425 cache.put("apple", "red");
2426 cache.put("banana", "yellow");
2427
2428 assert_opt_eq_mut(cache.peek_mut(&"banana"), "yellow");
2429 assert_opt_eq_mut(cache.peek_mut(&"apple"), "red");
2430 assert!(cache.peek_mut(&"pear").is_none());
2431
2432 cache.put("pear", "green");
2433
2434 assert!(cache.peek_mut(&"apple").is_none());
2435 assert_opt_eq_mut(cache.peek_mut(&"banana"), "yellow");
2436 assert_opt_eq_mut(cache.peek_mut(&"pear"), "green");
2437
2438 {
2439 let v = cache.peek_mut(&"banana").unwrap();
2440 *v = "green";
2441 }
2442
2443 assert_opt_eq_mut(cache.peek_mut(&"banana"), "green");
2444 }
2445
2446 #[test]
2447 fn test_peek_lru() {
2448 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2449
2450 assert!(cache.peek_lru().is_none());
2451
2452 cache.put("apple", "red");
2453 cache.put("banana", "yellow");
2454 assert_opt_eq_tuple(cache.peek_lru(), ("apple", "red"));
2455
2456 cache.get(&"apple");
2457 assert_opt_eq_tuple(cache.peek_lru(), ("banana", "yellow"));
2458
2459 cache.clear();
2460 assert!(cache.peek_lru().is_none());
2461 }
2462
2463 #[test]
2464 fn test_peek_mru() {
2465 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2466
2467 assert!(cache.peek_mru().is_none());
2468
2469 cache.put("apple", "red");
2470 cache.put("banana", "yellow");
2471 assert_opt_eq_tuple(cache.peek_mru(), ("banana", "yellow"));
2472
2473 cache.get(&"apple");
2474 assert_opt_eq_tuple(cache.peek_mru(), ("apple", "red"));
2475
2476 cache.clear();
2477 assert!(cache.peek_mru().is_none());
2478 }
2479
2480 #[test]
2481 fn test_contains() {
2482 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2483
2484 cache.put("apple", "red");
2485 cache.put("banana", "yellow");
2486 cache.put("pear", "green");
2487
2488 assert!(!cache.contains(&"apple"));
2489 assert!(cache.contains(&"banana"));
2490 assert!(cache.contains(&"pear"));
2491 }
2492
2493 #[test]
2494 fn test_pop() {
2495 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2496
2497 cache.put("apple", "red");
2498 cache.put("banana", "yellow");
2499
2500 assert_eq!(cache.len(), 2);
2501 assert_opt_eq(cache.get(&"apple"), "red");
2502 assert_opt_eq(cache.get(&"banana"), "yellow");
2503
2504 let popped = cache.pop(&"apple");
2505 assert!(popped.is_some());
2506 assert_eq!(popped.unwrap(), "red");
2507 assert_eq!(cache.len(), 1);
2508 assert!(cache.get(&"apple").is_none());
2509 assert_opt_eq(cache.get(&"banana"), "yellow");
2510 }
2511
2512 #[test]
2513 fn test_pop_entry() {
2514 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2515 cache.put("apple", "red");
2516 cache.put("banana", "yellow");
2517
2518 assert_eq!(cache.len(), 2);
2519 assert_opt_eq(cache.get(&"apple"), "red");
2520 assert_opt_eq(cache.get(&"banana"), "yellow");
2521
2522 let popped = cache.pop_entry(&"apple");
2523 assert!(popped.is_some());
2524 assert_eq!(popped.unwrap(), ("apple", "red"));
2525 assert_eq!(cache.len(), 1);
2526 assert!(cache.get(&"apple").is_none());
2527 assert_opt_eq(cache.get(&"banana"), "yellow");
2528 }
2529
2530 #[test]
2531 fn test_pop_lru() {
2532 let mut cache = LruCache::new(NonZeroUsize::new(200).unwrap());
2533
2534 for i in 0..75 {
2535 cache.put(i, "A");
2536 }
2537 for i in 0..75 {
2538 cache.put(i + 100, "B");
2539 }
2540 for i in 0..75 {
2541 cache.put(i + 200, "C");
2542 }
2543 assert_eq!(cache.len(), 200);
2544
2545 for i in 0..75 {
2546 assert_opt_eq(cache.get(&(74 - i + 100)), "B");
2547 }
2548 assert_opt_eq(cache.get(&25), "A");
2549
2550 for i in 26..75 {
2551 assert_eq!(cache.pop_lru(), Some((i, "A")));
2552 }
2553 for i in 0..75 {
2554 assert_eq!(cache.pop_lru(), Some((i + 200, "C")));
2555 }
2556 for i in 0..75 {
2557 assert_eq!(cache.pop_lru(), Some((74 - i + 100, "B")));
2558 }
2559 assert_eq!(cache.pop_lru(), Some((25, "A")));
2560 for _ in 0..50 {
2561 assert_eq!(cache.pop_lru(), None);
2562 }
2563 }
2564
2565 #[test]
2566 fn test_pop_mru() {
2567 let mut cache = LruCache::new(NonZeroUsize::new(200).unwrap());
2568
2569 for i in 0..75 {
2570 cache.put(i, "A");
2571 }
2572 for i in 0..75 {
2573 cache.put(i + 100, "B");
2574 }
2575 for i in 0..75 {
2576 cache.put(i + 200, "C");
2577 }
2578 assert_eq!(cache.len(), 200);
2579
2580 for i in 0..75 {
2581 assert_opt_eq(cache.get(&(74 - i + 100)), "B");
2582 }
2583 assert_opt_eq(cache.get(&25), "A");
2584
2585 assert_eq!(cache.pop_mru(), Some((25, "A")));
2586 for i in 0..75 {
2587 assert_eq!(cache.pop_mru(), Some((i + 100, "B")));
2588 }
2589 for i in 0..75 {
2590 assert_eq!(cache.pop_mru(), Some((74 - i + 200, "C")));
2591 }
2592 for i in (26..75).into_iter().rev() {
2593 assert_eq!(cache.pop_mru(), Some((i, "A")));
2594 }
2595 for _ in 0..50 {
2596 assert_eq!(cache.pop_mru(), None);
2597 }
2598 }
2599
2600 #[test]
2601 fn test_clear() {
2602 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2603
2604 cache.put("apple", "red");
2605 cache.put("banana", "yellow");
2606
2607 assert_eq!(cache.len(), 2);
2608 assert_opt_eq(cache.get(&"apple"), "red");
2609 assert_opt_eq(cache.get(&"banana"), "yellow");
2610
2611 cache.clear();
2612 assert_eq!(cache.len(), 0);
2613 }
2614
2615 #[test]
2616 fn test_resize_larger() {
2617 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2618
2619 cache.put(1, "a");
2620 cache.put(2, "b");
2621 cache.resize(NonZeroUsize::new(4).unwrap());
2622 cache.put(3, "c");
2623 cache.put(4, "d");
2624
2625 assert_eq!(cache.len(), 4);
2626 assert_eq!(cache.get(&1), Some(&"a"));
2627 assert_eq!(cache.get(&2), Some(&"b"));
2628 assert_eq!(cache.get(&3), Some(&"c"));
2629 assert_eq!(cache.get(&4), Some(&"d"));
2630 }
2631
2632 #[test]
2633 fn test_resize_smaller() {
2634 let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2635
2636 cache.put(1, "a");
2637 cache.put(2, "b");
2638 cache.put(3, "c");
2639 cache.put(4, "d");
2640
2641 cache.resize(NonZeroUsize::new(2).unwrap());
2642
2643 assert_eq!(cache.len(), 2);
2644 assert!(cache.get(&1).is_none());
2645 assert!(cache.get(&2).is_none());
2646 assert_eq!(cache.get(&3), Some(&"c"));
2647 assert_eq!(cache.get(&4), Some(&"d"));
2648 }
2649
2650 #[test]
2651 fn test_send() {
2652 use std::thread;
2653
2654 let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2655 cache.put(1, "a");
2656
2657 let handle = thread::spawn(move || {
2658 assert_eq!(cache.get(&1), Some(&"a"));
2659 });
2660
2661 assert!(handle.join().is_ok());
2662 }
2663
2664 #[test]
2665 fn test_multiple_threads() {
2666 let mut pool = Pool::new(1);
2667 let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
2668 cache.put(1, "a");
2669
2670 let cache_ref = &cache;
2671 pool.scoped(|scoped| {
2672 scoped.execute(move || {
2673 assert_eq!(cache_ref.peek(&1), Some(&"a"));
2674 });
2675 });
2676
2677 assert_eq!((cache_ref).peek(&1), Some(&"a"));
2678 }
2679
2680 #[test]
2681 fn test_iter_forwards() {
2682 let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2683 cache.put("a", 1);
2684 cache.put("b", 2);
2685 cache.put("c", 3);
2686
2687 {
2688 let mut iter = cache.iter();
2690 assert_eq!(iter.len(), 3);
2691 assert_opt_eq_tuple(iter.next(), ("c", 3));
2692
2693 assert_eq!(iter.len(), 2);
2694 assert_opt_eq_tuple(iter.next(), ("b", 2));
2695
2696 assert_eq!(iter.len(), 1);
2697 assert_opt_eq_tuple(iter.next(), ("a", 1));
2698
2699 assert_eq!(iter.len(), 0);
2700 assert_eq!(iter.next(), None);
2701 }
2702 {
2703 let mut iter = cache.iter_mut();
2705 assert_eq!(iter.len(), 3);
2706 assert_opt_eq_mut_tuple(iter.next(), ("c", 3));
2707
2708 assert_eq!(iter.len(), 2);
2709 assert_opt_eq_mut_tuple(iter.next(), ("b", 2));
2710
2711 assert_eq!(iter.len(), 1);
2712 assert_opt_eq_mut_tuple(iter.next(), ("a", 1));
2713
2714 assert_eq!(iter.len(), 0);
2715 assert_eq!(iter.next(), None);
2716 }
2717 }
2718
2719 #[test]
2720 fn test_iter_backwards() {
2721 let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2722 cache.put("a", 1);
2723 cache.put("b", 2);
2724 cache.put("c", 3);
2725
2726 {
2727 let mut iter = cache.iter();
2729 assert_eq!(iter.len(), 3);
2730 assert_opt_eq_tuple(iter.next_back(), ("a", 1));
2731
2732 assert_eq!(iter.len(), 2);
2733 assert_opt_eq_tuple(iter.next_back(), ("b", 2));
2734
2735 assert_eq!(iter.len(), 1);
2736 assert_opt_eq_tuple(iter.next_back(), ("c", 3));
2737
2738 assert_eq!(iter.len(), 0);
2739 assert_eq!(iter.next_back(), None);
2740 }
2741
2742 {
2743 let mut iter = cache.iter_mut();
2745 assert_eq!(iter.len(), 3);
2746 assert_opt_eq_mut_tuple(iter.next_back(), ("a", 1));
2747
2748 assert_eq!(iter.len(), 2);
2749 assert_opt_eq_mut_tuple(iter.next_back(), ("b", 2));
2750
2751 assert_eq!(iter.len(), 1);
2752 assert_opt_eq_mut_tuple(iter.next_back(), ("c", 3));
2753
2754 assert_eq!(iter.len(), 0);
2755 assert_eq!(iter.next_back(), None);
2756 }
2757 }
2758
2759 #[test]
2760 fn test_iter_forwards_and_backwards() {
2761 let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2762 cache.put("a", 1);
2763 cache.put("b", 2);
2764 cache.put("c", 3);
2765
2766 {
2767 let mut iter = cache.iter();
2769 assert_eq!(iter.len(), 3);
2770 assert_opt_eq_tuple(iter.next(), ("c", 3));
2771
2772 assert_eq!(iter.len(), 2);
2773 assert_opt_eq_tuple(iter.next_back(), ("a", 1));
2774
2775 assert_eq!(iter.len(), 1);
2776 assert_opt_eq_tuple(iter.next(), ("b", 2));
2777
2778 assert_eq!(iter.len(), 0);
2779 assert_eq!(iter.next_back(), None);
2780 }
2781 {
2782 let mut iter = cache.iter_mut();
2784 assert_eq!(iter.len(), 3);
2785 assert_opt_eq_mut_tuple(iter.next(), ("c", 3));
2786
2787 assert_eq!(iter.len(), 2);
2788 assert_opt_eq_mut_tuple(iter.next_back(), ("a", 1));
2789
2790 assert_eq!(iter.len(), 1);
2791 assert_opt_eq_mut_tuple(iter.next(), ("b", 2));
2792
2793 assert_eq!(iter.len(), 0);
2794 assert_eq!(iter.next_back(), None);
2795 }
2796 }
2797
2798 #[test]
2799 fn test_iter_multiple_threads() {
2800 let mut pool = Pool::new(1);
2801 let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2802 cache.put("a", 1);
2803 cache.put("b", 2);
2804 cache.put("c", 3);
2805
2806 let mut iter = cache.iter();
2807 assert_eq!(iter.len(), 3);
2808 assert_opt_eq_tuple(iter.next(), ("c", 3));
2809
2810 {
2811 let iter_ref = &mut iter;
2812 pool.scoped(|scoped| {
2813 scoped.execute(move || {
2814 assert_eq!(iter_ref.len(), 2);
2815 assert_opt_eq_tuple(iter_ref.next(), ("b", 2));
2816 });
2817 });
2818 }
2819
2820 assert_eq!(iter.len(), 1);
2821 assert_opt_eq_tuple(iter.next(), ("a", 1));
2822
2823 assert_eq!(iter.len(), 0);
2824 assert_eq!(iter.next(), None);
2825 }
2826
2827 #[test]
2828 fn test_iter_clone() {
2829 let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2830 cache.put("a", 1);
2831 cache.put("b", 2);
2832
2833 let mut iter = cache.iter();
2834 let mut iter_clone = iter.clone();
2835
2836 assert_eq!(iter.len(), 2);
2837 assert_opt_eq_tuple(iter.next(), ("b", 2));
2838 assert_eq!(iter_clone.len(), 2);
2839 assert_opt_eq_tuple(iter_clone.next(), ("b", 2));
2840
2841 assert_eq!(iter.len(), 1);
2842 assert_opt_eq_tuple(iter.next(), ("a", 1));
2843 assert_eq!(iter_clone.len(), 1);
2844 assert_opt_eq_tuple(iter_clone.next(), ("a", 1));
2845
2846 assert_eq!(iter.len(), 0);
2847 assert_eq!(iter.next(), None);
2848 assert_eq!(iter_clone.len(), 0);
2849 assert_eq!(iter_clone.next(), None);
2850 }
2851
2852 #[test]
2853 fn test_into_iter() {
2854 let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2855 cache.put("a", 1);
2856 cache.put("b", 2);
2857 cache.put("c", 3);
2858
2859 let mut iter = cache.into_iter();
2860 assert_eq!(iter.len(), 3);
2861 assert_eq!(iter.next(), Some(("a", 1)));
2862
2863 assert_eq!(iter.len(), 2);
2864 assert_eq!(iter.next(), Some(("b", 2)));
2865
2866 assert_eq!(iter.len(), 1);
2867 assert_eq!(iter.next(), Some(("c", 3)));
2868
2869 assert_eq!(iter.len(), 0);
2870 assert_eq!(iter.next(), None);
2871 }
2872
2873 #[test]
2874 fn test_that_pop_actually_detaches_node() {
2875 let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
2876
2877 cache.put("a", 1);
2878 cache.put("b", 2);
2879 cache.put("c", 3);
2880 cache.put("d", 4);
2881 cache.put("e", 5);
2882
2883 assert_eq!(cache.pop(&"c"), Some(3));
2884
2885 cache.put("f", 6);
2886
2887 let mut iter = cache.iter();
2888 assert_opt_eq_tuple(iter.next(), ("f", 6));
2889 assert_opt_eq_tuple(iter.next(), ("e", 5));
2890 assert_opt_eq_tuple(iter.next(), ("d", 4));
2891 assert_opt_eq_tuple(iter.next(), ("b", 2));
2892 assert_opt_eq_tuple(iter.next(), ("a", 1));
2893 assert!(iter.next().is_none());
2894 }
2895
2896 #[test]
2897 fn test_get_with_borrow() {
2898 use alloc::string::String;
2899
2900 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2901
2902 let key = String::from("apple");
2903 cache.put(key, "red");
2904
2905 assert_opt_eq(cache.get("apple"), "red");
2906 }
2907
2908 #[test]
2909 fn test_get_mut_with_borrow() {
2910 use alloc::string::String;
2911
2912 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2913
2914 let key = String::from("apple");
2915 cache.put(key, "red");
2916
2917 assert_opt_eq_mut(cache.get_mut("apple"), "red");
2918 }
2919
2920 #[test]
2921 fn test_no_memory_leaks() {
2922 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2923
2924 struct DropCounter;
2925
2926 impl Drop for DropCounter {
2927 fn drop(&mut self) {
2928 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2929 }
2930 }
2931
2932 let n = 100;
2933 for _ in 0..n {
2934 let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2935 for i in 0..n {
2936 cache.put(i, DropCounter {});
2937 }
2938 }
2939 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
2940 }
2941
2942 #[test]
2943 fn test_no_memory_leaks_with_clear() {
2944 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2945
2946 struct DropCounter;
2947
2948 impl Drop for DropCounter {
2949 fn drop(&mut self) {
2950 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2951 }
2952 }
2953
2954 let n = 100;
2955 for _ in 0..n {
2956 let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2957 for i in 0..n {
2958 cache.put(i, DropCounter {});
2959 }
2960 cache.clear();
2961 }
2962 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
2963 }
2964
2965 #[test]
2966 fn test_no_memory_leaks_with_resize() {
2967 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2968
2969 struct DropCounter;
2970
2971 impl Drop for DropCounter {
2972 fn drop(&mut self) {
2973 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2974 }
2975 }
2976
2977 let n = 100;
2978 for _ in 0..n {
2979 let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2980 for i in 0..n {
2981 cache.put(i, DropCounter {});
2982 }
2983 cache.clear();
2984 }
2985 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
2986 }
2987
2988 #[test]
2989 fn test_no_memory_leaks_with_pop() {
2990 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2991
2992 #[derive(Hash, Eq)]
2993 struct KeyDropCounter(usize);
2994
2995 impl PartialEq for KeyDropCounter {
2996 fn eq(&self, other: &Self) -> bool {
2997 self.0.eq(&other.0)
2998 }
2999 }
3000
3001 impl Drop for KeyDropCounter {
3002 fn drop(&mut self) {
3003 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3004 }
3005 }
3006
3007 let n = 100;
3008 for _ in 0..n {
3009 let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
3010
3011 for i in 0..100 {
3012 cache.put(KeyDropCounter(i), i);
3013 cache.pop(&KeyDropCounter(i));
3014 }
3015 }
3016
3017 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n * 2);
3018 }
3019
3020 #[test]
3021 fn test_find_and_promote() {
3022 let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3023 cache.put(1, "a");
3024 cache.put(2, "b");
3025 cache.put(3, "c");
3026
3027 let found = cache.find_and_promote(|(_, value)| *value == "b");
3028 assert_eq!(found, Some((&2, &"b")));
3029 assert_eq!(cache.pop_lru(), Some((1, "a")));
3030 assert_eq!(cache.pop_lru(), Some((3, "c")));
3031 assert_eq!(cache.pop_lru(), Some((2, "b")));
3032 assert_eq!(cache.pop_lru(), None);
3033 }
3034
3035 #[test]
3036 fn test_find_and_promote_no_match() {
3037 let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3038 cache.put(1, "a");
3039 cache.put(2, "b");
3040 cache.put(3, "c");
3041
3042 let found = cache.find_and_promote(|(_, value)| *value == "d");
3043 assert_eq!(found, None);
3044 assert_eq!(cache.pop_lru(), Some((1, "a")));
3045 assert_eq!(cache.pop_lru(), Some((2, "b")));
3046 assert_eq!(cache.pop_lru(), Some((3, "c")));
3047 assert_eq!(cache.pop_lru(), None);
3048 }
3049
3050 #[test]
3051 fn test_find_and_promote_multiple_matches_picks_first_in_mru_order() {
3052 let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3053 cache.put(1, "b");
3054 cache.put(2, "b");
3055 cache.put(3, "x");
3056
3057 let found = cache.find_and_promote(|(_, value)| *value == "b");
3058 assert_eq!(found, Some((&2, &"b")));
3059 assert_eq!(cache.pop_lru(), Some((1, "b")));
3060 assert_eq!(cache.pop_lru(), Some((3, "x")));
3061 assert_eq!(cache.pop_lru(), Some((2, "b")));
3062 assert_eq!(cache.pop_lru(), None);
3063 }
3064
3065 #[test]
3066 fn test_promote_and_demote() {
3067 let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
3068 for i in 0..5 {
3069 cache.push(i, i);
3070 }
3071 cache.promote(&1);
3072 cache.promote(&0);
3073 cache.demote(&3);
3074 cache.demote(&4);
3075 assert_eq!(cache.pop_lru(), Some((4, 4)));
3076 assert_eq!(cache.pop_lru(), Some((3, 3)));
3077 assert_eq!(cache.pop_lru(), Some((2, 2)));
3078 assert_eq!(cache.pop_lru(), Some((1, 1)));
3079 assert_eq!(cache.pop_lru(), Some((0, 0)));
3080 assert_eq!(cache.pop_lru(), None);
3081 }
3082
3083 #[test]
3084 fn test_get_key_value() {
3085 use alloc::string::String;
3086
3087 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
3088
3089 let key = String::from("apple");
3090 cache.put(key, "red");
3091
3092 assert_eq!(
3093 cache.get_key_value("apple"),
3094 Some((&String::from("apple"), &"red"))
3095 );
3096 assert_eq!(cache.get_key_value("banana"), None);
3097 }
3098
3099 #[test]
3100 fn test_get_key_value_mut() {
3101 use alloc::string::String;
3102
3103 let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
3104
3105 let key = String::from("apple");
3106 cache.put(key, "red");
3107
3108 let (k, v) = cache.get_key_value_mut("apple").unwrap();
3109 assert_eq!(k, &String::from("apple"));
3110 assert_eq!(v, &mut "red");
3111 *v = "green";
3112
3113 assert_eq!(
3114 cache.get_key_value("apple"),
3115 Some((&String::from("apple"), &"green"))
3116 );
3117 assert_eq!(cache.get_key_value("banana"), None);
3118 }
3119
3120 #[test]
3121 fn test_clone() {
3122 let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
3123 cache.put("a", 1);
3124 cache.put("b", 2);
3125 cache.put("c", 3);
3126
3127 let mut cloned = cache.clone();
3128
3129 assert_eq!(cache.pop_lru(), Some(("a", 1)));
3130 assert_eq!(cloned.pop_lru(), Some(("a", 1)));
3131
3132 assert_eq!(cache.pop_lru(), Some(("b", 2)));
3133 assert_eq!(cloned.pop_lru(), Some(("b", 2)));
3134
3135 assert_eq!(cache.pop_lru(), Some(("c", 3)));
3136 assert_eq!(cloned.pop_lru(), Some(("c", 3)));
3137
3138 assert_eq!(cache.pop_lru(), None);
3139 assert_eq!(cloned.pop_lru(), None);
3140 }
3141
3142 #[test]
3143 fn test_clone_unbounded() {
3144 let mut cache = LruCache::unbounded();
3145 cache.put("a", 1);
3146 cache.put("b", 2);
3147 cache.put("c", 3);
3148
3149 let mut cloned = cache.clone();
3150
3151 assert_eq!(cache.pop_lru(), Some(("a", 1)));
3152 assert_eq!(cloned.pop_lru(), Some(("a", 1)));
3153
3154 assert_eq!(cache.pop_lru(), Some(("b", 2)));
3155 assert_eq!(cloned.pop_lru(), Some(("b", 2)));
3156
3157 assert_eq!(cache.pop_lru(), Some(("c", 3)));
3158 assert_eq!(cloned.pop_lru(), Some(("c", 3)));
3159
3160 assert_eq!(cache.pop_lru(), None);
3161 assert_eq!(cloned.pop_lru(), None);
3162 }
3163
3164 #[test]
3165 fn iter_mut_stacked_borrows_violation() {
3166 let mut cache: LruCache<i32, i32> = LruCache::new(NonZeroUsize::new(3).unwrap());
3167 cache.put(1, 10);
3168 cache.put(2, 20);
3169 cache.put(3, 30);
3170
3171 for (_k, v) in cache.iter_mut() {
3172 *v *= 2;
3173 }
3174
3175 assert_eq!(cache.get(&1), Some(&20));
3176 assert_eq!(cache.get(&2), Some(&40));
3177 assert_eq!(cache.get(&3), Some(&60));
3178 }
3179}
3180
3181fn _test_lifetimes() {}