1use std::{
14 borrow::Borrow, hash::{BuildHasher, Hash},
15 fmt::{self, Debug},
16 marker::PhantomData, mem, ops::{Index, IndexMut}, ptr::{self, NonNull}
17};
18
19use crate::{HashMap, DefaultHasher};
20use super::{KeyRef, KeyWrapper};
21
22#[cfg(feature = "ttl")]
23use crate::get_milltimestamp;
24#[cfg(feature = "ttl")]
25const DEFAULT_CHECK_STEP: u64 = 120;
26
27const DEFAULT_TIMESK: usize = 2;
28
29pub(crate) struct LruKEntry<K, V> {
31 pub key: mem::MaybeUninit<K>,
32 pub val: mem::MaybeUninit<V>,
33 pub times: usize,
34 pub prev: *mut LruKEntry<K, V>,
35 pub next: *mut LruKEntry<K, V>,
36 #[cfg(feature = "ttl")]
39 pub expire: u64,
40}
41
42impl<K, V> LruKEntry<K, V> {
43 pub fn new_empty() -> Self {
44 LruKEntry {
45 key: mem::MaybeUninit::uninit(),
46 val: mem::MaybeUninit::uninit(),
47 times: 0,
48 prev: ptr::null_mut(),
49 next: ptr::null_mut(),
50 #[cfg(feature = "ttl")]
51 expire: u64::MAX,
52 }
53 }
54
55 pub fn new(k: K, v: V) -> Self {
56 LruKEntry {
57 key: mem::MaybeUninit::new(k),
58 val: mem::MaybeUninit::new(v),
59 times: 0,
60 prev: ptr::null_mut(),
61 next: ptr::null_mut(),
62 #[cfg(feature = "ttl")]
63 expire: u64::MAX,
64 }
65 }
66
67
68 #[cfg(feature = "ttl")]
69 #[inline(always)]
70 pub fn is_expire(&self) -> bool {
71 get_milltimestamp() >= self.expire
72 }
73
74
75 #[cfg(feature = "ttl")]
76 #[inline(always)]
77 pub fn is_little(&self, time: &u64) -> bool {
78 time >= &self.expire
79 }
80
81
82 #[cfg(feature = "ttl")]
83 #[inline(always)]
84 pub fn get_ttl(&self) -> u64 {
85 if self.expire == u64::MAX {
86 self.expire
87 } else {
88 self.expire.saturating_sub(get_milltimestamp()) / 1000
89 }
90 }
91}
92
93
94pub struct LruKCache<K, V, S> {
119 map: HashMap<KeyRef<K>, NonNull<LruKEntry<K, V>>, S>,
120 cap: usize,
121 times: usize,
123 head_times: *mut LruKEntry<K, V>,
125 tail_times: *mut LruKEntry<K, V>,
126 head: *mut LruKEntry<K, V>,
128 tail: *mut LruKEntry<K, V>,
129 lru_count: usize,
131
132 #[cfg(feature = "ttl")]
134 check_next: u64,
135 #[cfg(feature = "ttl")]
137 check_step: u64,
138 #[cfg(feature = "ttl")]
140 has_ttl: bool,
141}
142
143impl<K: Hash + Eq, V> Default for LruKCache<K, V, DefaultHasher> {
144 fn default() -> Self {
145 LruKCache::new(100 )
146 }
147}
148
149impl<K: Hash + Eq, V> LruKCache<K, V, DefaultHasher> {
150 pub fn new(cap: usize) -> Self {
151 LruKCache::with_hasher(cap, DEFAULT_TIMESK, DefaultHasher::default())
152 }
153
154 pub fn with_times(cap: usize, times: usize) -> Self {
155 LruKCache::with_hasher(cap, times, DefaultHasher::default())
156 }
157}
158
159impl<K, V, S> LruKCache<K, V, S> {
160 pub fn with_hasher(cap: usize, times: usize, hash_builder: S) -> LruKCache<K, V, S> {
162 let cap = cap.max(1);
163 let map = HashMap::with_capacity_and_hasher(cap, hash_builder);
164 let head = Box::into_raw(Box::new(LruKEntry::new_empty()));
165 let tail = Box::into_raw(Box::new(LruKEntry::new_empty()));
166 unsafe {
167 (*head).next = tail;
168 (*tail).prev = head;
169 }
170 let head_times = Box::into_raw(Box::new(LruKEntry::new_empty()));
171 let tail_times = Box::into_raw(Box::new(LruKEntry::new_empty()));
172 unsafe {
173 (*head_times).next = tail_times;
174 (*tail_times).prev = head_times;
175 }
176 Self {
177 map,
178 cap,
179 times,
180 head_times,
181 tail_times,
182 head,
183 tail,
184 lru_count: 0,
185 #[cfg(feature = "ttl")]
186 check_step: DEFAULT_CHECK_STEP,
187 #[cfg(feature = "ttl")]
188 check_next: get_milltimestamp()+DEFAULT_CHECK_STEP * 1000,
189 #[cfg(feature = "ttl")]
190 has_ttl: false,
191 }
192 }
193
194 #[cfg(feature="ttl")]
196 pub fn get_check_step(&self) -> u64 {
197 self.check_step
198 }
199
200 #[cfg(feature="ttl")]
206 pub fn set_check_step(&mut self, check_step: u64) {
207 self.check_step = check_step;
208 self.check_next = get_milltimestamp() + self.check_step * 1000;
209 }
210 pub fn capacity(&self) -> usize {
212 self.cap
213 }
214
215 pub fn clear(&mut self) {
231 self.map.drain().for_each(|(_, entry)| {
232 let _node = unsafe { *Box::from_raw(entry.as_ptr()) };
233 });
234 unsafe {
235 (*self.head).next = self.tail;
236 (*self.tail).prev = self.head;
237 self.lru_count = 0;
238
239 (*self.head_times).next = self.tail_times;
240 (*self.tail_times).prev = self.head_times;
241 }
242 }
243
244 pub fn len(&self) -> usize {
246 self.map.len()
247 }
248
249 pub fn is_empty(&self) -> bool {
250 self.map.len() == 0
251 }
252
253 fn detach(&mut self, entry: *mut LruKEntry<K, V>) {
255 unsafe {
256 (*(*entry).prev).next = (*entry).next;
257 (*(*entry).next).prev = (*entry).prev;
258
259 if (*entry).times < self.times {
260 self.lru_count -= 1;
261 }
262 }
263 }
264
265 fn attach(&mut self, entry: *mut LruKEntry<K, V>) {
267 unsafe {
268 (*entry).times = (*entry).times.saturating_add(1);
269 if (*entry).times < self.times {
270 self.lru_count += 1;
271 (*entry).next = (*self.head).next;
272 (*(*entry).next).prev = entry;
273 (*entry).prev = self.head;
274 (*self.head).next = entry;
275 } else {
276 (*entry).next = (*self.head_times).next;
277 (*(*entry).next).prev = entry;
278 (*entry).prev = self.head_times;
279 (*self.head_times).next = entry;
280 }
281 }
282 }
283
284 pub fn reserve(&mut self, additional: usize) -> &mut Self {
286 self.cap += additional;
287 self
288 }
289
290 pub fn iter(&self) -> Iter<'_, K, V> {
309 Iter {
310 len: self.map.len(),
311 times_ptr: self.head_times,
312 times_end: self.tail_times,
313 ptr: self.head,
314 end: self.tail,
315 phantom: PhantomData
316 }
317 }
318 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
335 IterMut { len: self.map.len(), times_ptr: self.head_times, times_end: self.tail_times, ptr: self.head, end: self.tail, phantom: PhantomData }
336 }
337
338 pub fn keys(&self) -> Keys<'_, K, V> {
356 Keys {
357 iter: self.iter()
358 }
359 }
360
361 pub fn values(&self) -> Values<'_, K, V> {
379 Values {
380 iter: self.iter()
381 }
382 }
383
384 pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
402 ValuesMut {
403 iter: self.iter_mut()
404 }
405 }
406 pub fn hasher(&self) -> &S {
407 self.map.hasher()
408 }
409}
410
411impl<K: Hash + Eq, V, S: BuildHasher> LruKCache<K, V, S> {
412
413 pub fn drain(&mut self) -> Drain<'_, K, V, S> {
429 Drain { base: self }
430 }
431
432
433 pub fn pop_usual(&mut self) -> Option<(K, V)> {
446 if self.len() == 0 {
447 return None;
448 }
449 unsafe {
450 let node = if self.len() - self.lru_count > 0 {
451 let node = (*self.head_times).next;
452 self.detach(node);
453 let key = KeyRef::new((*node).key.as_ptr());
454 let value = self.map.remove(&key).expect("must ok");
455 *Box::from_raw(value.as_ptr())
456 } else {
457 let node = (*self.head).next;
458 self.detach(node);
459 let key = KeyRef::new((*node).key.as_ptr());
460 let value = self.map.remove(&key).expect("must ok");
461 *Box::from_raw(value.as_ptr())
462 };
463 let LruKEntry { key, val, .. } = node;
464 Some((key.assume_init(), val.assume_init()))
465 }
466 }
467
468 pub fn pop_unusual(&mut self) -> Option<(K, V)> {
481 if self.len() == 0 {
482 return None;
483 }
484 unsafe {
485 let node = if self.lru_count > 0 {
486 let node = (*self.tail).prev;
487 self.detach(node);
488 let key = KeyRef::new((*node).key.as_ptr());
489 let value = self.map.remove(&key).expect("must ok");
490 *Box::from_raw(value.as_ptr())
491 } else {
492 let node = (*self.tail_times).prev;
493 self.detach(node);
494 let key = KeyRef::new((*node).key.as_ptr());
495 let value = self.map.remove(&key).expect("must ok");
496 *Box::from_raw(value.as_ptr())
497 };
498 let LruKEntry { key, val, .. } = node;
499 Some((key.assume_init(), val.assume_init()))
500 }
501 }
502
503
504 pub fn peek_usual(&mut self) -> Option<(&K, &V)> {
517 if self.len() == 0 {
518 return None;
519 }
520 unsafe {
521 if self.len() - self.lru_count > 0 {
522 let node = (*self.head_times).next;
523 Some((&*(*node).key.as_ptr(), &*(*node).val.as_ptr()))
524 } else {
525 let node = (*self.head).next;
526 Some((&*(*node).key.as_ptr(), &*(*node).val.as_ptr()))
527 }
528 }
529 }
530
531 pub fn peek_unusual(&mut self) -> Option<(&K, &V)> {
544 if self.len() == 0 {
545 return None;
546 }
547 unsafe {
548 if self.lru_count > 0 {
549 let node = (*self.tail).prev;
550 Some((&*(*node).key.as_ptr(), &*(*node).val.as_ptr()))
551 } else {
552 let node = (*self.tail_times).prev;
553 Some((&*(*node).key.as_ptr(), &*(*node).val.as_ptr()))
554 }
555 }
556 }
557
558 pub fn contains_key<Q>(&mut self, k: &Q) -> bool
559 where
560 K: Borrow<Q>,
561 Q: Hash + Eq + ?Sized,
562 {
563 self.map.contains_key(KeyWrapper::from_ref(k))
564 }
565
566 pub fn raw_get<Q>(&self, k: &Q) -> Option<&V>
578 where
579 K: Borrow<Q>,
580 Q: Hash + Eq + ?Sized,
581 {
582 match self.map.get(KeyWrapper::from_ref(k)) {
583 Some(l) => {
584 let node = l.as_ptr();
585 unsafe { Some(&*(*node).val.as_ptr()) }
586 }
587 None => None,
588 }
589 }
590
591 #[inline]
603 pub fn get<Q>(&mut self, k: &Q) -> Option<&V>
604 where
605 K: Borrow<Q>,
606 Q: Hash + Eq + ?Sized,
607 {
608 self.get_key_value(k).map(|(_, v)| v)
609 }
610
611 #[inline]
623 pub fn get_key_value<Q>(&mut self, k: &Q) -> Option<(&K, &V)>
624 where
625 K: Borrow<Q>,
626 Q: Hash + Eq + ?Sized,
627 {
628 self.get_mut_key_value(k).map(|(k, v)| (k, &*v))
629 }
630
631 pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
644 where
645 K: Borrow<Q>,
646 Q: Hash + Eq + ?Sized,
647 {
648 self.get_mut_key_value(k).map(|(_, v)| v)
649 }
650
651
652 pub fn get_mut_key_value<Q>(&mut self, k: &Q) -> Option<(&K, &mut V)>
665 where
666 K: Borrow<Q>,
667 Q: Hash + Eq + ?Sized,
668 {
669 match self.get_node(k) {
670 Some(node) => {
671 unsafe { Some((&*(*node).key.as_ptr(), &mut *(*node).val.as_mut_ptr())) }
672 }
673 None => None,
674 }
675 }
676
677
678 pub(crate) fn get_node<Q>(&mut self, k: &Q) -> Option<*mut LruKEntry<K, V>>
679 where
680 K: Borrow<Q>,
681 Q: Hash + Eq + ?Sized,
682 {
683 match self.map.get(KeyWrapper::from_ref(k)) {
684 Some(l) => {
685 let node = l.as_ptr();
686 self.detach(node);
687 #[cfg(feature = "ttl")]
688 unsafe {
689 if self.has_ttl && (*node).is_expire() {
690 self.map.remove(KeyWrapper::from_ref(k));
691 let _ = *Box::from_raw(node);
692 return None;
693 }
694 }
695
696 self.attach(node);
697 Some(node)
698 }
699 None => None,
700 }
701 }
702
703 pub fn insert(&mut self, k: K, v: V) -> Option<V> {
715 self.capture_insert(k, v).map(|(_, v, _)| v)
716 }
717
718 #[cfg(feature="ttl")]
722 #[inline(always)]
723 pub fn insert_with_ttl(&mut self, k: K, v: V, ttl: u64) -> Option<V> {
724 self.capture_insert_with_ttl(k, v, ttl).map(|(_, v, _)| v)
725 }
726
727 #[inline(always)]
728 pub fn capture_insert(&mut self, k: K, v: V) -> Option<(K, V, bool)> {
729 self._capture_insert_with_ttl(k, v, u64::MAX)
730 }
731
732 #[cfg(feature = "ttl")]
733 #[inline(always)]
734 pub fn capture_insert_with_ttl(&mut self, k: K, v: V, ttl: u64) -> Option<(K, V, bool)> {
735 if ttl == 0 { return None };
736 self.has_ttl = true;
737 self._capture_insert_with_ttl(k, v, ttl)
738 }
739
740 #[allow(unused_variables)]
741 fn _capture_insert_with_ttl(&mut self, k: K, mut v: V, ttl: u64) -> Option<(K, V, bool)> {
742 #[cfg(feature="ttl")]
743 self.clear_expire();
744
745 let key = KeyRef::new(&k);
746 match self.map.get_mut(&key) {
747 Some(entry) => {
748 let entry_ptr = entry.as_ptr();
749 unsafe {
750 mem::swap(&mut *(*entry_ptr).val.as_mut_ptr(), &mut v);
751 }
752 #[cfg(feature="ttl")]
753 unsafe {
754 (*entry_ptr).expire = ttl.saturating_mul(1000).saturating_add(get_milltimestamp());
755 }
756 self.detach(entry_ptr);
757 self.attach(entry_ptr);
758
759 Some((k, v, true))
760 }
761 None => {
762 let (val, entry) = self.replace_or_create_node(k, v);
763 let entry_ptr = entry.as_ptr();
764 self.attach(entry_ptr);
765 #[cfg(feature="ttl")]
766 unsafe {
767 (*entry_ptr).expire = ttl.saturating_mul(1000).saturating_add(get_milltimestamp());
768 }
769 unsafe {
770 self.map
771 .insert(KeyRef::new((*entry_ptr).key.as_ptr()), entry);
772 }
773 val.map(|(k, v)| (k, v, false))
774 }
775 }
776 }
777
778 pub fn get_or_insert<F>(&mut self, k: K, f: F) -> &V
779 where
780 F: FnOnce() -> V, {
781 &*self.get_or_insert_mut(k, f)
782 }
783
784
785 pub fn get_or_insert_mut<F>(&mut self, k: K, f: F) -> &mut V
786 where
787 F: FnOnce() -> V, {
788 if let Some(l) = self.map.get(KeyWrapper::from_ref(&k)) {
789 let node = l.as_ptr();
790 self.detach(node);
791 self.attach(node);
792 unsafe { &mut *(*node).val.as_mut_ptr() }
793 } else {
794 let v = f();
795
796 let (_, node) = self.replace_or_create_node(k, v);
797 let node_ptr: *mut LruKEntry<K, V> = node.as_ptr();
798
799 self.attach(node_ptr);
800
801 let keyref = unsafe { (*node_ptr).key.as_ptr() };
802 self.map.insert(KeyRef { k: keyref }, node);
803 unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
804 }
805 }
806
807
808 #[cfg(feature="ttl")]
809 pub fn clear_expire(&mut self) {
810 if !self.has_ttl {
811 return;
812 }
813 let now = get_milltimestamp();
814 if now < self.check_next {
815 return;
816 }
817 self.check_next = now + self.check_step;
818 unsafe {
819 let mut ptr = self.tail;
820 while ptr != self.head {
821 if (*ptr).is_little(&now) {
822 let next = (*ptr).prev;
823 self.detach(ptr);
824 self.map.remove(&KeyRef::new(&*(*ptr).key.as_ptr()));
825 let _ = *Box::from_raw(ptr);
826 ptr = next;
827 } else {
828 ptr = (*ptr).prev;
829 }
830 }
831
832 let mut ptr = self.tail_times;
833 while ptr != self.head_times {
834 if (*ptr).is_little(&now) {
835 let next = (*ptr).prev;
836 self.detach(ptr);
837 self.map.remove(&KeyRef::new(&*(*ptr).key.as_ptr()));
838 let _ = *Box::from_raw(ptr);
839 ptr = next;
840 } else {
841 ptr = (*ptr).prev;
842 }
843 }
844 }
845 }
846
847 #[cfg(feature="ttl")]
848 #[inline(always)]
849 pub fn del_ttl<Q>(&mut self, k: &Q)
850 where
851 K: Borrow<Q>,
852 Q: Hash + Eq + ?Sized, {
853 self.set_ttl(k, u64::MAX);
854 }
855
856 #[cfg(feature="ttl")]
857 pub fn set_ttl<Q>(&mut self, k: &Q, expire: u64) -> bool
858 where
859 K: Borrow<Q>,
860 Q: Hash + Eq + ?Sized, {
861 if let Some(v) = self.get_node(&k) {
862 self.has_ttl = true;
863 unsafe {
864 (*v).expire = get_milltimestamp().saturating_add(expire.saturating_mul(1000));
865 }
866 true
867 } else {
868 false
869 }
870 }
871
872 #[cfg(feature="ttl")]
873 pub fn get_ttl<Q>(&mut self, k: &Q) -> Option<u64>
874 where
875 K: Borrow<Q>,
876 Q: Hash + Eq + ?Sized, {
877 if let Some(v) = self.get_node(&k) {
878 unsafe {
879 if (*v).expire == u64::MAX {
880 Some((*v).expire)
881 } else {
882 Some((*v).expire.saturating_sub(get_milltimestamp()) / 1000)
883 }
884 }
885 } else {
886 None
887 }
888 }
889
890 pub fn remove<Q>(&mut self, k: &Q) -> Option<(K, V)>
903 where
904 K: Borrow<Q>,
905 Q: Hash + Eq + ?Sized,
906 {
907 if let Some(node) = self.remove_node(k) {
908 unsafe {
909 Some((node.key.assume_init(), node.val.assume_init()))
910 }
911 } else {
912 None
913 }
914 }
915
916
917 #[cfg(feature="ttl")]
918 pub fn remove_with_ttl<Q>(&mut self, k: &Q) -> Option<(K, V, u64)>
919 where
920 K: Borrow<Q>,
921 Q: Hash + Eq + ?Sized,
922 {
923 if let Some(node) = self.remove_node(k) {
924 unsafe {
925 let ttl = node.get_ttl();
926 Some((node.key.assume_init(), node.val.assume_init(), ttl))
927 }
928 } else {
929 None
930 }
931 }
932
933 fn remove_node<Q>(&mut self, k: &Q) -> Option<LruKEntry<K, V>>
934 where
935 K: Borrow<Q>,
936 Q: Hash + Eq + ?Sized,
937 {
938 match self.map.remove(KeyWrapper::from_ref(k)) {
939 Some(l) => unsafe {
940 self.detach(l.as_ptr());
941 let node = *Box::from_raw(l.as_ptr());
942 Some(node)
943 },
944 None => None,
945 }
946 }
947
948 fn replace_or_create_node(&mut self, k: K, v: V) -> (Option<(K, V)>, NonNull<LruKEntry<K, V>>) {
949 if self.len() == self.cap {
950 let old_key = if self.lru_count > 0 {
951 KeyRef {
952 k: unsafe { &(*(*(*self.tail).prev).key.as_ptr()) },
953 }
954 } else {
955 KeyRef {
956 k: unsafe { &(*(*(*self.tail_times).prev).key.as_ptr()) },
957 }
958 };
959 let old_node = self.map.remove(&old_key).unwrap();
960 let node_ptr: *mut LruKEntry<K, V> = old_node.as_ptr();
961 unsafe {
962 (*node_ptr).times = 0;
963 }
964 let replaced = unsafe {
965 (
966 mem::replace(&mut (*node_ptr).key, mem::MaybeUninit::new(k)).assume_init(),
967 mem::replace(&mut (*node_ptr).val, mem::MaybeUninit::new(v)).assume_init(),
968 )
969 };
970
971 self.detach(node_ptr);
972
973 (Some(replaced), old_node)
974 } else {
975 (None, unsafe {
976 NonNull::new_unchecked(Box::into_raw(Box::new(LruKEntry::new(k, v))))
977 })
978 }
979 }
980
981 pub fn retain<F>(&mut self, mut f: F)
996 where
997 F: FnMut(&K, &mut V) -> bool,
998 {
999 unsafe {
1000 let mut node = (*self.head).next;
1001 while node != self.tail {
1002 if !f(&*(*node).key.as_ptr(), &mut *(*node).val.as_mut_ptr()) {
1003 let next = (*node).next;
1004 self.map.remove(&KeyRef { k: &*(*node).key.as_ptr()});
1005 self.detach(node);
1006 node = next;
1007 } else {
1008 node = (*node).next;
1009 }
1010 }
1011 }
1012 }
1013}
1014
1015
1016impl<K: Hash + Eq, V: Default, S: BuildHasher> LruKCache<K, V, S> {
1017 pub fn get_or_insert_default(&mut self, k: K) -> &V {
1018 &*self.get_or_insert_mut(k, || V::default())
1019 }
1020
1021 pub fn get_or_insert_default_mut(&mut self, k: K) -> &mut V {
1022 self.get_or_insert_mut(k, || V::default())
1023 }
1024}
1025
1026impl<K: Clone + Hash + Eq, V: Clone, S: Clone + BuildHasher> Clone for LruKCache<K, V, S> {
1027 fn clone(&self) -> Self {
1028
1029 let mut new_lru = LruKCache::with_hasher(self.cap, self.times, self.map.hasher().clone());
1030
1031 for (key, value) in self.iter().rev() {
1032 new_lru.insert(key.clone(), value.clone());
1033 }
1034
1035 new_lru
1036 }
1037}
1038
1039impl<K, V, S> Drop for LruKCache<K, V, S> {
1040 fn drop(&mut self) {
1041 self.clear();
1042
1043 let _head = unsafe { *Box::from_raw(self.head) };
1044 let _tail = unsafe { *Box::from_raw(self.tail) };
1045 }
1046}
1047
1048pub struct IntoIter<K: Hash + Eq, V, S: BuildHasher> {
1050 base: LruKCache<K, V, S>,
1051}
1052
1053impl<K: Hash + Eq, V, S: BuildHasher> Drop for IntoIter<K, V, S> {
1055 #[inline]
1056 fn drop(&mut self) {
1057 for (_, _) in self {}
1058 }
1059}
1060
1061impl<K: Hash + Eq, V, S: BuildHasher> Iterator for IntoIter<K, V, S> {
1062 type Item = (K, V);
1063
1064 fn next(&mut self) -> Option<(K, V)> {
1065 self.base.pop_usual()
1066 }
1067
1068 fn size_hint(&self) -> (usize, Option<usize>) {
1069 (self.base.len(), Some(self.base.len()))
1070 }
1071}
1072
1073impl<K: Hash + Eq, V, S: BuildHasher> IntoIterator for LruKCache<K, V, S> {
1074 type Item = (K, V);
1075 type IntoIter = IntoIter<K, V, S>;
1076
1077 #[inline]
1078 fn into_iter(self) -> IntoIter<K, V, S> {
1079 IntoIter {
1080 base: self
1081 }
1082 }
1083}
1084
1085pub struct Iter<'a, K: 'a, V: 'a> {
1086 len: usize,
1087 times_ptr: *mut LruKEntry<K, V>,
1088 times_end: *mut LruKEntry<K, V>,
1089 ptr: *mut LruKEntry<K, V>,
1090 end: *mut LruKEntry<K, V>,
1091 phantom: PhantomData<&'a usize>,
1092}
1093
1094impl<'a, K, V> Iterator for Iter<'a, K, V> {
1095 type Item = (&'a K, &'a V);
1096
1097 fn next(&mut self) -> Option<Self::Item> {
1098 if self.len == 0 {
1099 return None;
1100 }
1101 unsafe {
1102 let node = if (*self.times_ptr).next != self.times_end {
1103 self.times_ptr = (*self.times_ptr).next;
1104 self.times_ptr
1105 } else {
1106 self.ptr = (*self.ptr).next;
1107 self.ptr
1108 };
1109 self.len -= 1;
1110 Some((&*(*node).key.as_ptr(), &*(*node).val.as_ptr()))
1111 }
1112 }
1113
1114 fn size_hint(&self) -> (usize, Option<usize>) {
1115 (self.len, Some(self.len))
1116 }
1117}
1118
1119impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
1120 fn next_back(&mut self) -> Option<Self::Item> {
1121 if self.len == 0 {
1122 return None;
1123 }
1124
1125 unsafe {
1126 let node = if (*self.end).prev != self.ptr {
1127 self.end = (*self.end).prev;
1128 self.end
1129 } else {
1130 self.times_end = (*self.times_end).prev;
1131 self.times_end
1132 };
1133 self.len -= 1;
1134 Some((&*(*node).key.as_ptr(), &*(*node).val.as_ptr()))
1135 }
1136 }
1137}
1138
1139impl<K: Hash + Eq, V, S: BuildHasher> DoubleEndedIterator for IntoIter<K, V, S> {
1140 #[inline]
1141 fn next_back(&mut self) -> Option<(K, V)> {
1142 self.base.pop_unusual()
1143 }
1144}
1145
1146pub struct IterMut<'a, K: 'a, V: 'a> {
1147 len: usize,
1148 times_ptr: *mut LruKEntry<K, V>,
1149 times_end: *mut LruKEntry<K, V>,
1150 ptr: *mut LruKEntry<K, V>,
1151 end: *mut LruKEntry<K, V>,
1152 phantom: PhantomData<&'a usize>,
1153}
1154
1155impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1156 type Item = (&'a K, &'a mut V);
1157
1158 fn next(&mut self) -> Option<Self::Item> {
1159 if self.len == 0 {
1160 return None;
1161 }
1162 unsafe {
1163 let node = if (*self.times_ptr).next != self.times_end {
1164 self.times_ptr = (*self.times_ptr).next;
1165 self.times_ptr
1166 } else {
1167 self.ptr = (*self.ptr).next;
1168 self.ptr
1169 };
1170 self.len -= 1;
1171 Some((&*(*node).key.as_ptr(), &mut *(*node).val.as_mut_ptr()))
1172 }
1173 }
1174
1175 fn size_hint(&self) -> (usize, Option<usize>) {
1176 (self.len, Some(self.len))
1177 }
1178}
1179
1180impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> {
1181 fn next_back(&mut self) -> Option<Self::Item> {
1182 if self.len == 0 {
1183 return None;
1184 }
1185
1186 unsafe {
1187 let node = if (*self.end).prev != self.ptr {
1188 self.end = (*self.end).prev;
1189 self.end
1190 } else {
1191 self.times_end = (*self.times_end).prev;
1192 self.times_end
1193 };
1194 self.len -= 1;
1195 Some((&*(*node).key.as_ptr(), &mut *(*node).val.as_mut_ptr()))
1196 }
1197 }
1198}
1199pub struct Drain<'a, K: 'a + Hash + Eq, V: 'a, S: BuildHasher> {
1200 pub base: &'a mut LruKCache<K, V, S>,
1201}
1202
1203impl<'a, K: Hash + Eq, V, S: BuildHasher> ExactSizeIterator for Drain<'a, K, V, S> {
1204 fn len(&self) -> usize {
1205 self.base.map.len()
1206 }
1207}
1208
1209impl<'a, K: Hash + Eq, V, S: BuildHasher> Iterator for Drain<'a, K, V, S> {
1210 type Item = (K, V);
1211
1212 fn next(&mut self) -> Option<Self::Item> {
1213 if self.base.len() == 0 {
1214 return None;
1215 }
1216 self.base.pop_unusual()
1217 }
1218}
1219
1220
1221impl<'a, K: Hash + Eq, V, S: BuildHasher> Drop for Drain<'a, K, V, S> {
1222 fn drop(&mut self) {
1223 self.base.clear();
1224 }
1225}
1226
1227pub struct Keys<'a, K, V> {
1228 iter: Iter<'a, K, V>,
1229}
1230
1231impl<'a, K, V> Iterator for Keys<'a, K, V> {
1232 type Item=&'a K;
1233
1234 fn next(&mut self) -> Option<Self::Item> {
1235 self.iter.next().map(|(k, _)| k)
1236 }
1237 fn size_hint(&self) -> (usize, Option<usize>) {
1238 (self.iter.len, Some(self.iter.len))
1239 }
1240}
1241
1242
1243pub struct Values<'a, K, V> {
1244 iter: Iter<'a, K, V>,
1245}
1246
1247impl<'a, K, V> Iterator for Values<'a, K, V> {
1248 type Item=&'a V;
1249
1250 fn next(&mut self) -> Option<Self::Item> {
1251 self.iter.next().map(|(_, v)| v)
1252 }
1253 fn size_hint(&self) -> (usize, Option<usize>) {
1254 (self.iter.len, Some(self.iter.len))
1255 }
1256}
1257
1258
1259pub struct ValuesMut<'a, K, V> {
1260 iter: IterMut<'a, K, V>,
1261}
1262
1263impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
1264 type Item = &'a mut V;
1265
1266 fn next(&mut self) -> Option<Self::Item> {
1267 self.iter.next().map(|(_, v)| v)
1268 }
1269
1270 fn size_hint(&self) -> (usize, Option<usize>) {
1271 (self.iter.len, Some(self.iter.len))
1272 }
1273}
1274
1275impl<K: Hash + Eq, V> FromIterator<(K, V)> for LruKCache<K, V, DefaultHasher> {
1276 fn from_iter<T: IntoIterator<Item=(K, V)>>(iter: T) -> LruKCache<K, V, DefaultHasher> {
1277 let mut lru = LruKCache::new(2);
1278 lru.extend(iter);
1279 lru
1280 }
1281}
1282
1283impl<K: Hash + Eq, V> Extend<(K, V)> for LruKCache<K, V, DefaultHasher> {
1284 fn extend<T: IntoIterator<Item=(K, V)>>(&mut self, iter: T) {
1285 let iter = iter.into_iter();
1286 for (k, v) in iter {
1287 self.reserve(1);
1288 self.insert(k, v);
1289 }
1290 }
1291}
1292
1293impl<K, V, S> PartialEq for LruKCache<K, V, S>
1294 where
1295 K: Eq + Hash,
1296 V: PartialEq,
1297 S: BuildHasher
1298{
1299 fn eq(&self, other: &LruKCache<K, V, S>) -> bool {
1300 if self.len() != other.len() {
1301 return false;
1302 }
1303
1304 self.iter()
1305 .all(|(key, value)| other.raw_get(key).map_or(false, |v| *value == *v))
1306 }
1307}
1308
1309impl<K, V, S> Eq for LruKCache<K, V, S>
1310 where
1311 K: Eq + Hash,
1312 V: PartialEq,
1313 S: BuildHasher
1314{}
1315
1316impl<K, V, S> Debug for LruKCache<K, V, S>
1317where
1318 K: Ord + Debug,
1319 V: Debug,
1320{
1321 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1322 f.debug_map().entries(self.iter()).finish()
1323 }
1324}
1325
1326
1327impl<'a, K, V, S> Index<&'a K> for LruKCache<K, V, S>
1328where
1329 K: Hash+Eq,
1330 S: BuildHasher
1331{
1332 type Output = V;
1333
1334 #[inline]
1335 fn index(&self, index: &K) -> &V {
1336 self.raw_get(index).expect("no entry found for key")
1337 }
1338}
1339
1340
1341impl<'a, K, V, S> IndexMut<&'a K> for LruKCache<K, V, S>
1342where
1343 K: Hash+Eq,
1344 S: BuildHasher
1345{
1346 #[inline]
1347 fn index_mut(&mut self, index: &K) -> &mut V {
1348 self.get_mut(index).expect("no entry found for key")
1349 }
1350}
1351
1352
1353
1354unsafe impl<K: Send, V: Send, S: Send> Send for LruKCache<K, V, S> {}
1355unsafe impl<K: Sync, V: Sync, S: Sync> Sync for LruKCache<K, V, S> {}
1356
1357
1358#[cfg(test)]
1359mod tests {
1360 use crate::DefaultHasher;
1361 use super::LruKCache;
1362
1363 #[test]
1364 fn test_insert() {
1365 let mut m = LruKCache::new(2);
1366 assert_eq!(m.len(), 0);
1367 m.insert(1, 2);
1368 assert_eq!(m.len(), 1);
1369 m.insert(2, 4);
1370 assert_eq!(m.len(), 2);
1371 m.insert(3, 6);
1372 assert_eq!(m.len(), 2);
1373 assert_eq!(m.get(&1), None);
1374 assert_eq!(*m.get(&2).unwrap(), 4);
1375 assert_eq!(*m.get(&3).unwrap(), 6);
1376 }
1377
1378 #[test]
1379 fn test_replace() {
1380 let mut m = LruKCache::new(2);
1381 assert_eq!(m.len(), 0);
1382 m.insert(2, 4);
1383 assert_eq!(m.len(), 1);
1384 m.insert(2, 6);
1385 assert_eq!(m.len(), 1);
1386 assert_eq!(*m.get(&2).unwrap(), 6);
1387 }
1388
1389 #[test]
1390 fn test_clone() {
1391 let mut m = LruKCache::new(2);
1392 assert_eq!(m.len(), 0);
1393 m.insert(1, 2);
1394 assert_eq!(m.len(), 1);
1395 m.insert(2, 4);
1396 assert_eq!(m.len(), 2);
1397 let mut m2 = m.clone();
1398 m.clear();
1399 assert_eq!(*m2.get(&1).unwrap(), 2);
1400 assert_eq!(*m2.get(&2).unwrap(), 4);
1401 assert_eq!(m2.len(), 2);
1402 }
1403
1404 #[test]
1405 fn test_empty_remove() {
1406 let mut m: LruKCache<isize, bool, DefaultHasher> = LruKCache::new(2);
1407 assert_eq!(m.remove(&0), None);
1408 }
1409
1410 #[test]
1411 fn test_empty_iter() {
1412 let mut m: LruKCache<isize, bool, DefaultHasher> = LruKCache::new(2);
1413 assert_eq!(m.iter().next(), None);
1414 assert_eq!(m.iter_mut().next(), None);
1415 assert_eq!(m.len(), 0);
1416 assert!(m.is_empty());
1417 assert_eq!(m.into_iter().next(), None);
1418 }
1419
1420 #[test]
1421 fn test_lots_of_insertions() {
1422 let mut m = LruKCache::new(1000);
1423
1424 for _ in 0..10 {
1427 assert!(m.is_empty());
1428
1429 for i in 1..101 {
1430 m.insert(i, i);
1431
1432 for j in 1..i + 1 {
1433 let r = m.get(&j);
1434 assert_eq!(r, Some(&j));
1435 }
1436
1437 for j in i + 1..101 {
1438 let r = m.get(&j);
1439 assert_eq!(r, None);
1440 }
1441 }
1442
1443 for i in 101..201 {
1444 assert!(!m.contains_key(&i));
1445 }
1446
1447 for i in 1..101 {
1449 assert!(m.remove(&i).is_some());
1450
1451 for j in 1..i + 1 {
1452 assert!(!m.contains_key(&j));
1453 }
1454
1455 for j in i + 1..101 {
1456 assert!(m.contains_key(&j));
1457 }
1458 }
1459
1460 for i in 1..101 {
1461 assert!(!m.contains_key(&i));
1462 }
1463
1464 for i in 1..101 {
1465 m.insert(i, i);
1466 }
1467
1468 for i in (1..101).rev() {
1470 assert!(m.remove(&i).is_some());
1471
1472 for j in i..101 {
1473 assert!(!m.contains_key(&j));
1474 }
1475
1476 for j in 1..i {
1477 assert!(m.contains_key(&j));
1478 }
1479 }
1480 }
1481 }
1482
1483 #[test]
1484 fn test_find_mut() {
1485 let mut m = LruKCache::new(3);
1486 m.insert(1, 12);
1487 m.insert(2, 8);
1488 m.insert(5, 14);
1489 let new = 100;
1490 match m.get_mut(&5) {
1491 None => panic!(),
1492 Some(x) => *x = new,
1493 }
1494 assert_eq!(m.get(&5), Some(&new));
1495 }
1496
1497 #[test]
1498 fn test_remove() {
1499 let mut m = LruKCache::new(3);
1500 m.insert(1, 2);
1501 assert_eq!(*m.get(&1).unwrap(), 2);
1502 m.insert(5, 3);
1503 assert_eq!(*m.get(&5).unwrap(), 3);
1504 m.insert(9, 4);
1505 assert_eq!(*m.get(&1).unwrap(), 2);
1506 assert_eq!(*m.get(&5).unwrap(), 3);
1507 assert_eq!(*m.get(&9).unwrap(), 4);
1508 assert_eq!(m.remove(&1).unwrap(), (1, 2));
1509 assert_eq!(m.remove(&5).unwrap(), (5, 3));
1510 assert_eq!(m.remove(&9).unwrap(), (9, 4));
1511 assert_eq!(m.len(), 0);
1512 }
1513
1514 #[test]
1515 fn test_is_empty() {
1516 let mut m = LruKCache::new(2);
1517 m.insert(1, 2);
1518 assert!(!m.is_empty());
1519 assert!(m.remove(&1).is_some());
1520 assert!(m.is_empty());
1521 }
1522
1523 #[test]
1524 fn test_pop() {
1525 let mut m = LruKCache::new(3);
1526 m.insert(3, 6);
1527 m.insert(2, 4);
1528 m.insert(1, 2);
1529 assert_eq!(m.len(), 3);
1530 assert_eq!(m.pop_usual(), Some((1, 2)));
1531 assert_eq!(m.len(), 2);
1532 assert_eq!(m.pop_unusual(), Some((3, 6)));
1533 assert_eq!(m.len(), 1);
1534 }
1535
1536 #[test]
1537 fn test_iterate() {
1538 let mut m = LruKCache::new(32);
1539 for i in 0..32 {
1540 m.insert(i, i * 2);
1541 }
1542 assert_eq!(m.len(), 32);
1543
1544 let mut observed: u32 = 0;
1545
1546 for (k, v) in m.iter() {
1547 assert_eq!(*v, *k * 2);
1548 observed |= 1 << *k;
1549 }
1550 assert_eq!(observed, 0xFFFF_FFFF);
1551 }
1552
1553 #[test]
1554 fn test_keys() {
1555 let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
1556 let map: LruKCache<_, _, _> = vec.into_iter().collect();
1557 let keys: Vec<_> = map.keys().cloned().collect();
1558 assert_eq!(keys.len(), 3);
1559 assert!(keys.contains(&1));
1560 assert!(keys.contains(&2));
1561 assert!(keys.contains(&3));
1562 }
1563
1564 #[test]
1565 fn test_values() {
1566 let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
1567 let map: LruKCache<_, _, _> = vec.into_iter().collect();
1568 let values: Vec<_> = map.values().cloned().collect();
1569 assert_eq!(values.len(), 3);
1570 assert!(values.contains(&'a'));
1571 assert!(values.contains(&'b'));
1572 assert!(values.contains(&'c'));
1573 }
1574
1575 #[test]
1576 fn test_values_mut() {
1577 let vec = vec![(1, 1), (2, 2), (3, 3)];
1578 let mut map: LruKCache<_, _, _> = vec.into_iter().collect();
1579 for value in map.values_mut() {
1580 *value = (*value) * 2
1581 }
1582 let values: Vec<_> = map.values().cloned().collect();
1583 assert_eq!(values.len(), 3);
1584 assert!(values.contains(&2));
1585 assert!(values.contains(&4));
1586 assert!(values.contains(&6));
1587 }
1588
1589 #[test]
1590 fn test_find() {
1591 let mut m = LruKCache::new(2);
1592 assert!(m.get(&1).is_none());
1593 m.insert(1, 2);
1594 match m.get(&1) {
1595 None => panic!(),
1596 Some(v) => assert_eq!(*v, 2),
1597 }
1598 }
1599
1600 #[test]
1601 fn test_eq() {
1602 let mut m1 = LruKCache::new(3);
1603 m1.insert(1, 2);
1604 m1.insert(2, 3);
1605 m1.insert(3, 4);
1606
1607 let mut m2 = LruKCache::new(3);
1608 m2.insert(1, 2);
1609 m2.insert(2, 3);
1610
1611 assert!(m1 != m2);
1612
1613 m2.insert(3, 4);
1614
1615 assert_eq!(m1, m2);
1616 }
1617
1618 #[test]
1619 fn test_from_iter() {
1620 let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
1621
1622 let map: LruKCache<_, _, _> = xs.iter().cloned().collect();
1623
1624 for &(k, v) in &xs {
1625 assert_eq!(map.raw_get(&k), Some(&v));
1626 }
1627 }
1628
1629 #[test]
1630 fn test_size_hint() {
1631 let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
1632
1633 let map: LruKCache<_, _, _> = xs.iter().cloned().collect();
1634
1635 let mut iter = map.iter();
1636
1637 for _ in iter.by_ref().take(3) {}
1638
1639 assert_eq!(iter.size_hint(), (3, Some(3)));
1640 }
1641
1642 #[test]
1643 fn test_iter_len() {
1644 let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
1645
1646 let map: LruKCache<_, _, _> = xs.iter().cloned().collect();
1647
1648 let mut iter = map.iter();
1649
1650 for _ in iter.by_ref().take(3) {}
1651
1652 assert_eq!(iter.count(), 3);
1653 }
1654
1655 #[test]
1656 fn test_mut_size_hint() {
1657 let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
1658
1659 let mut map: LruKCache<_, _, _> = xs.iter().cloned().collect();
1660
1661 let mut iter = map.iter_mut();
1662
1663 for _ in iter.by_ref().take(3) {}
1664
1665 assert_eq!(iter.size_hint(), (3, Some(3)));
1666 }
1667
1668 #[test]
1669 fn test_iter_mut_len() {
1670 let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
1671
1672 let mut map: LruKCache<_, _, _> = xs.iter().cloned().collect();
1673
1674 let mut iter = map.iter_mut();
1675
1676 for _ in iter.by_ref().take(3) {}
1677
1678 assert_eq!(iter.count(), 3);
1679 }
1680
1681 #[test]
1682 fn test_index() {
1683 let mut map = LruKCache::new(2);
1684
1685 map.insert(1, 2);
1686 map.insert(2, 1);
1687 map.insert(3, 4);
1688
1689 assert_eq!(map[&2], 1);
1690 }
1691
1692 #[test]
1693 #[should_panic]
1694 fn test_index_nonexistent() {
1695 let mut map = LruKCache::new(2);
1696
1697 map.insert(1, 2);
1698 map.insert(2, 1);
1699 map.insert(3, 4);
1700
1701 map[&4];
1702 }
1703
1704 #[test]
1705 fn test_extend_iter() {
1706 let mut a = LruKCache::new(2);
1707 a.insert(1, "one");
1708 let mut b = LruKCache::new(2);
1709 b.insert(2, "two");
1710 b.insert(3, "three");
1711
1712 a.extend(b.into_iter());
1713
1714 assert_eq!(a.len(), 3);
1715 assert_eq!(a[&1], "one");
1716 assert_eq!(a[&2], "two");
1717 assert_eq!(a[&3], "three");
1718 }
1719
1720 #[test]
1721 fn test_drain() {
1722 let mut a = LruKCache::new(3);
1723 a.insert(1, 1);
1724 a.insert(2, 2);
1725 a.insert(3, 3);
1726
1727 assert_eq!(a.len(), 3);
1728 {
1729 let mut drain = a.drain();
1730 assert_eq!(drain.next().unwrap(), (1, 1));
1731 assert_eq!(drain.next().unwrap(), (2, 2));
1732 }
1733 assert_eq!(a.len(), 0);
1734 }
1735
1736
1737 #[test]
1738 fn test_send() {
1739 use std::thread;
1740
1741 let mut cache = LruKCache::new(4);
1742 cache.insert(1, "a");
1743
1744 let handle = thread::spawn(move || {
1745 assert_eq!(cache.get(&1), Some(&"a"));
1746 });
1747
1748 assert!(handle.join().is_ok());
1749 }
1750
1751
1752 #[test]
1753 #[cfg(feature="ttl")]
1754 fn test_ttl_cache() {
1755 let mut lru = LruKCache::new(3);
1756 lru.insert_with_ttl("help", "ok", 1);
1757 lru.insert_with_ttl("author", "tickbh", 2);
1758 assert_eq!(lru.len(), 2);
1759 std::thread::sleep(std::time::Duration::from_secs(1));
1760 assert_eq!(lru.get("help"), None);
1761 std::thread::sleep(std::time::Duration::from_secs(1));
1762 assert_eq!(lru.get("author"), None);
1763 assert_eq!(lru.len(), 0);
1764 }
1765
1766 #[test]
1767 #[cfg(feature="ttl")]
1768 fn test_ttl_check_cache() {
1769 let mut lru = LruKCache::new(3);
1770 lru.set_check_step(1);
1771 lru.insert_with_ttl("help", "ok", 1);
1772 lru.insert("now", "algorithm");
1773 assert_eq!(lru.len(), 2);
1774 std::thread::sleep(std::time::Duration::from_secs(1));
1775 assert_eq!(lru.len(), 2);
1776 lru.insert_with_ttl("author", "tickbh", 3);
1777 assert_eq!(lru.len(), 2);
1778 assert_eq!(lru.get("help"), None);
1779 assert_eq!(lru.len(), 2);
1780 }
1781
1782 #[test]
1783 #[cfg(feature="ttl")]
1784 fn test_ttl_del() {
1785 let mut lru = LruKCache::new(3);
1786 lru.insert_with_ttl("help", "ok", 1);
1787 lru.insert_with_ttl("author", "tickbh", 2);
1788 assert_eq!(lru.len(), 2);
1789 std::thread::sleep(std::time::Duration::from_secs(1));
1790 assert_eq!(lru.get("help"), None);
1791 lru.del_ttl(&"author");
1792 std::thread::sleep(std::time::Duration::from_secs(1));
1793 assert_eq!(lru.get("author"), Some(&"tickbh"));
1794 assert_eq!(lru.len(), 1);
1795 }
1796
1797 #[test]
1798 #[cfg(feature="ttl")]
1799 fn test_ttl_set() {
1800 let mut lru = LruKCache::new(3);
1801 lru.insert_with_ttl("help", "ok", 1);
1802 lru.insert_with_ttl("author", "tickbh", 2);
1803 lru.set_ttl(&"help", 3);
1804 assert_eq!(lru.len(), 2);
1805 std::thread::sleep(std::time::Duration::from_secs(1));
1806 assert_eq!(lru.get("help"), Some(&"ok"));
1807 std::thread::sleep(std::time::Duration::from_secs(1));
1808 assert_eq!(lru.get("author"), None);
1809 std::thread::sleep(std::time::Duration::from_secs(1));
1810 assert_eq!(lru.get("help"), None);
1811 assert_eq!(lru.len(), 0);
1812 }
1813
1814
1815 #[test]
1816 #[cfg(feature="ttl")]
1817 fn test_ttl_get() {
1818 let mut lru = LruKCache::new(3);
1819 lru.insert_with_ttl("help", "ok", 1);
1820 lru.insert_with_ttl("author", "tickbh", 2);
1821 lru.insert("now", "algorithm");
1822 assert_eq!(lru.get_ttl(&"help"), Some(1));
1823 assert_eq!(lru.get_ttl(&"author"), Some(2));
1824 assert_eq!(lru.get_ttl(&"now"), Some(u64::MAX));
1825 }
1826}