1#[cfg(feature = "heapsize")]
49extern crate heapsize;
50
51use std::borrow::Borrow;
52use std::collections::hash_map::RandomState;
53use std::fmt;
54use std::hash::{BuildHasher, Hash};
55
56use linked_hash_map::LinkedHashMap;
57
58pub trait Meter<K, V> {
67 type Measure: Default + Copy;
69 fn measure<Q: ?Sized>(&self, key: &Q, value: &V) -> Self::Measure
71 where
72 K: Borrow<Q>;
73}
74
75pub struct Count;
77
78impl<K, V> Meter<K, V> for Count {
79 type Measure = ();
81
82 fn measure<Q: ?Sized>(&self, _: &Q, _: &V)
84 where
85 K: Borrow<Q>,
86 {
87 }
88}
89
90pub trait CountableMeter<K, V>: Meter<K, V> {
93 fn add(&self, current: Self::Measure, amount: Self::Measure) -> Self::Measure;
95 fn sub(&self, current: Self::Measure, amount: Self::Measure) -> Self::Measure;
97 fn size(&self, current: Self::Measure) -> Option<u64>;
102}
103
104impl<K, V, T: Meter<K, V>> CountableMeter<K, V> for T
106where
107 T: CountableMeterWithMeasure<K, V, <T as Meter<K, V>>::Measure>,
108{
109 fn add(&self, current: Self::Measure, amount: Self::Measure) -> Self::Measure {
110 CountableMeterWithMeasure::meter_add(self, current, amount)
111 }
112 fn sub(&self, current: Self::Measure, amount: Self::Measure) -> Self::Measure {
113 CountableMeterWithMeasure::meter_sub(self, current, amount)
114 }
115 fn size(&self, current: Self::Measure) -> Option<u64> {
116 CountableMeterWithMeasure::meter_size(self, current)
117 }
118}
119
120pub trait CountableMeterWithMeasure<K, V, M> {
121 fn meter_add(&self, current: M, amount: M) -> M;
123 fn meter_sub(&self, current: M, amount: M) -> M;
125 fn meter_size(&self, current: M) -> Option<u64>;
130}
131
132impl<K, V, T> CountableMeterWithMeasure<K, V, usize> for T
134where
135 T: Meter<K, V>,
136{
137 fn meter_add(&self, current: usize, amount: usize) -> usize {
138 current + amount
139 }
140 fn meter_sub(&self, current: usize, amount: usize) -> usize {
141 current - amount
142 }
143 fn meter_size(&self, current: usize) -> Option<u64> {
144 Some(current as u64)
145 }
146}
147
148impl<K, V> CountableMeterWithMeasure<K, V, ()> for Count {
149 fn meter_add(&self, _current: (), _amount: ()) {}
150 fn meter_sub(&self, _current: (), _amount: ()) {}
151 fn meter_size(&self, _current: ()) -> Option<u64> {
152 None
153 }
154}
155
156#[cfg(feature = "heapsize")]
157mod heap_meter {
158 use heapsize::HeapSizeOf;
159 use std::borrow::Borrow;
160
161 pub struct HeapSize;
167
168 impl<K, V: HeapSizeOf> super::Meter<K, V> for HeapSize {
169 type Measure = usize;
170
171 fn measure<Q: ?Sized>(&self, _: &Q, item: &V) -> usize
172 where
173 K: Borrow<Q>,
174 {
175 item.heap_size_of_children() + ::std::mem::size_of::<V>()
176 }
177 }
178}
179
180#[cfg(feature = "heapsize")]
181pub use heap_meter::*;
182
183#[derive(Clone)]
185pub struct LruCache<K: Eq + Hash, V, S: BuildHasher = RandomState, M: CountableMeter<K, V> = Count>
186{
187 map: LinkedHashMap<K, V, S>,
188 current_measure: M::Measure,
189 max_capacity: u64,
190 meter: M,
191}
192
193impl<K: Eq + Hash, V> LruCache<K, V> {
194 pub fn new(capacity: u64) -> Self {
203 LruCache {
204 map: LinkedHashMap::new(),
205 current_measure: (),
206 max_capacity: capacity,
207 meter: Count,
208 }
209 }
210}
211
212impl<K: Eq + Hash, V, M: CountableMeter<K, V>> LruCache<K, V, RandomState, M> {
213 pub fn with_meter(capacity: u64, meter: M) -> LruCache<K, V, RandomState, M> {
247 LruCache {
248 map: LinkedHashMap::new(),
249 current_measure: Default::default(),
250 max_capacity: capacity,
251 meter,
252 }
253 }
254}
255
256impl<K: Eq + Hash, V, S: BuildHasher> LruCache<K, V, S, Count> {
257 pub fn with_hasher(capacity: u64, hash_builder: S) -> LruCache<K, V, S, Count> {
259 LruCache {
260 map: LinkedHashMap::with_hasher(hash_builder),
261 current_measure: (),
262 max_capacity: capacity,
263 meter: Count,
264 }
265 }
266
267 pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
289 where
290 K: Borrow<Q>,
291 Q: Hash + Eq,
292 {
293 self.map.get_refresh(k)
294 }
295
296 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
328 self.internal_iter_mut()
329 }
330}
331
332impl<K: Eq + Hash, V, S: BuildHasher, M: CountableMeter<K, V>> LruCache<K, V, S, M> {
333 pub fn with_meter_and_hasher(capacity: u64, meter: M, hash_builder: S) -> Self {
336 LruCache {
337 map: LinkedHashMap::with_hasher(hash_builder),
338 current_measure: Default::default(),
339 max_capacity: capacity,
340 meter,
341 }
342 }
343
344 pub fn capacity(&self) -> u64 {
355 self.max_capacity
356 }
357
358 pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
371 where
372 K: Borrow<Q>,
373 Q: Hash + Eq,
374 {
375 self.map.contains_key(key)
376 }
377
378 pub fn get<Q: ?Sized>(&mut self, k: &Q) -> Option<&V>
379 where
380 K: Borrow<Q>,
381 Q: Hash + Eq,
382 {
383 self.map.get_refresh(k).map(|v| v as &V)
384 }
385
386 pub fn insert(&mut self, k: K, v: V) -> Option<V> {
402 let new_size = self.meter.measure(&k, &v);
403 self.current_measure = self.meter.add(self.current_measure, new_size);
404 if let Some(old) = self.map.get(&k) {
405 self.current_measure = self
406 .meter
407 .sub(self.current_measure, self.meter.measure(&k, old));
408 }
409 let old_val = self.map.insert(k, v);
410 while self.size() > self.capacity() {
411 self.remove_lru();
412 }
413 old_val
414 }
415
416 pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
433 where
434 K: Borrow<Q>,
435 Q: Hash + Eq,
436 {
437 self.map.remove(k).map(|v| {
438 self.current_measure = self
439 .meter
440 .sub(self.current_measure, self.meter.measure(k, &v));
441 v
442 })
443 }
444
445 pub fn set_capacity(&mut self, capacity: u64) {
480 while self.size() > capacity {
481 self.remove_lru();
482 }
483 self.max_capacity = capacity;
484 }
485
486 #[inline]
502 pub fn remove_lru(&mut self) -> Option<(K, V)> {
503 self.map.pop_front().map(|(k, v)| {
504 self.current_measure = self
505 .meter
506 .sub(self.current_measure, self.meter.measure(&k, &v));
507 (k, v)
508 })
509 }
510
511 pub fn len(&self) -> usize {
513 self.map.len()
514 }
515
516 pub fn size(&self) -> u64 {
519 self.meter
520 .size(self.current_measure)
521 .unwrap_or_else(|| self.map.len() as u64)
522 }
523
524 pub fn is_empty(&self) -> bool {
526 self.map.is_empty()
527 }
528
529 pub fn clear(&mut self) {
531 self.map.clear();
532 self.current_measure = Default::default();
533 }
534
535 pub fn iter(&self) -> Iter<'_, K, V> {
554 Iter(self.map.iter())
555 }
556
557 fn internal_iter_mut(&mut self) -> IterMut<'_, K, V> {
558 IterMut(self.map.iter_mut())
559 }
560}
561
562impl<K: Eq + Hash, V, S: BuildHasher, M: CountableMeter<K, V>> Extend<(K, V)>
563 for LruCache<K, V, S, M>
564{
565 fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
566 for (k, v) in iter {
567 self.insert(k, v);
568 }
569 }
570}
571
572impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, S: BuildHasher, M: CountableMeter<K, V>> fmt::Debug
573 for LruCache<K, V, S, M>
574{
575 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
576 f.debug_map().entries(self.iter().rev()).finish()
577 }
578}
579
580impl<K: Eq + Hash, V, S: BuildHasher, M: CountableMeter<K, V>> IntoIterator
581 for LruCache<K, V, S, M>
582{
583 type Item = (K, V);
584 type IntoIter = IntoIter<K, V>;
585
586 fn into_iter(self) -> IntoIter<K, V> {
587 IntoIter(self.map.into_iter())
588 }
589}
590
591impl<'a, K: Eq + Hash, V, S: BuildHasher, M: CountableMeter<K, V>> IntoIterator
592 for &'a LruCache<K, V, S, M>
593{
594 type Item = (&'a K, &'a V);
595 type IntoIter = Iter<'a, K, V>;
596 fn into_iter(self) -> Iter<'a, K, V> {
597 self.iter()
598 }
599}
600
601impl<'a, K: Eq + Hash, V, S: BuildHasher, M: CountableMeter<K, V>> IntoIterator
602 for &'a mut LruCache<K, V, S, M>
603{
604 type Item = (&'a K, &'a mut V);
605 type IntoIter = IterMut<'a, K, V>;
606 fn into_iter(self) -> IterMut<'a, K, V> {
607 self.internal_iter_mut()
608 }
609}
610
611#[derive(Clone)]
635pub struct IntoIter<K, V>(linked_hash_map::IntoIter<K, V>);
636
637impl<K, V> Iterator for IntoIter<K, V> {
638 type Item = (K, V);
639
640 fn next(&mut self) -> Option<(K, V)> {
641 self.0.next()
642 }
643
644 fn size_hint(&self) -> (usize, Option<usize>) {
645 self.0.size_hint()
646 }
647}
648
649impl<K, V> DoubleEndedIterator for IntoIter<K, V> {
650 fn next_back(&mut self) -> Option<(K, V)> {
651 self.0.next_back()
652 }
653}
654
655impl<K, V> ExactSizeIterator for IntoIter<K, V> {
656 fn len(&self) -> usize {
657 self.0.len()
658 }
659}
660
661pub struct Iter<'a, K, V>(linked_hash_map::Iter<'a, K, V>);
665
666impl<'a, K, V> Clone for Iter<'a, K, V> {
667 fn clone(&self) -> Iter<'a, K, V> {
668 Iter(self.0.clone())
669 }
670}
671
672impl<'a, K, V> Iterator for Iter<'a, K, V> {
673 type Item = (&'a K, &'a V);
674 fn next(&mut self) -> Option<(&'a K, &'a V)> {
675 self.0.next()
676 }
677 fn size_hint(&self) -> (usize, Option<usize>) {
678 self.0.size_hint()
679 }
680}
681
682impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
683 fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
684 self.0.next_back()
685 }
686}
687
688impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
689 fn len(&self) -> usize {
690 self.0.len()
691 }
692}
693
694pub struct IterMut<'a, K, V>(linked_hash_map::IterMut<'a, K, V>);
699
700impl<'a, K, V> Iterator for IterMut<'a, K, V> {
701 type Item = (&'a K, &'a mut V);
702 fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
703 self.0.next()
704 }
705 fn size_hint(&self) -> (usize, Option<usize>) {
706 self.0.size_hint()
707 }
708}
709
710impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> {
711 fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
712 self.0.next_back()
713 }
714}
715
716impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
717 fn len(&self) -> usize {
718 self.0.len()
719 }
720}
721
722#[cfg(test)]
723mod tests {
724 use super::{LruCache, Meter};
725 use std::borrow::Borrow;
726
727 #[test]
728 fn test_put_and_get() {
729 let mut cache = LruCache::new(2);
730 cache.insert(1, 10);
731 cache.insert(2, 20);
732 assert_eq!(cache.get_mut(&1), Some(&mut 10));
733 assert_eq!(cache.get_mut(&2), Some(&mut 20));
734 assert_eq!(cache.len(), 2);
735 assert_eq!(cache.size(), 2);
736 }
737
738 #[test]
739 fn test_put_update() {
740 let mut cache = LruCache::new(1);
741 cache.insert("1", 10);
742 cache.insert("1", 19);
743 assert_eq!(cache.get_mut("1"), Some(&mut 19));
744 assert_eq!(cache.len(), 1);
745 }
746
747 #[test]
748 fn test_contains_key() {
749 let mut cache = LruCache::new(1);
750 cache.insert("1", 10);
751 assert_eq!(cache.contains_key("1"), true);
752 }
753
754 #[test]
755 fn test_expire_lru() {
756 let mut cache = LruCache::new(2);
757 cache.insert("foo1", "bar1");
758 cache.insert("foo2", "bar2");
759 cache.insert("foo3", "bar3");
760 assert!(cache.get_mut("foo1").is_none());
761 cache.insert("foo2", "bar2update");
762 cache.insert("foo4", "bar4");
763 assert!(cache.get_mut("foo3").is_none());
764 }
765
766 #[test]
767 fn test_pop() {
768 let mut cache = LruCache::new(2);
769 cache.insert(1, 10);
770 cache.insert(2, 20);
771 assert_eq!(cache.len(), 2);
772 let opt1 = cache.remove(&1);
773 assert!(opt1.is_some());
774 assert_eq!(opt1.unwrap(), 10);
775 assert!(cache.get_mut(&1).is_none());
776 assert_eq!(cache.len(), 1);
777 }
778
779 #[test]
780 fn test_change_capacity() {
781 let mut cache = LruCache::new(2);
782 assert_eq!(cache.capacity(), 2);
783 cache.insert(1, 10);
784 cache.insert(2, 20);
785 cache.set_capacity(1);
786 assert!(cache.get_mut(&1).is_none());
787 assert_eq!(cache.capacity(), 1);
788 }
789
790 #[test]
791 fn test_debug() {
792 let mut cache = LruCache::new(3);
793 cache.insert(1, 10);
794 cache.insert(2, 20);
795 cache.insert(3, 30);
796 assert_eq!(format!("{:?}", cache), "{3: 30, 2: 20, 1: 10}");
797 cache.insert(2, 22);
798 assert_eq!(format!("{:?}", cache), "{2: 22, 3: 30, 1: 10}");
799 cache.insert(6, 60);
800 assert_eq!(format!("{:?}", cache), "{6: 60, 2: 22, 3: 30}");
801 cache.get_mut(&3);
802 assert_eq!(format!("{:?}", cache), "{3: 30, 6: 60, 2: 22}");
803 cache.set_capacity(2);
804 assert_eq!(format!("{:?}", cache), "{3: 30, 6: 60}");
805 }
806
807 #[test]
808 fn test_remove() {
809 let mut cache = LruCache::new(3);
810 cache.insert(1, 10);
811 cache.insert(2, 20);
812 cache.insert(3, 30);
813 cache.insert(4, 40);
814 cache.insert(5, 50);
815 cache.remove(&3);
816 cache.remove(&4);
817 assert!(cache.get_mut(&3).is_none());
818 assert!(cache.get_mut(&4).is_none());
819 cache.insert(6, 60);
820 cache.insert(7, 70);
821 cache.insert(8, 80);
822 assert!(cache.get_mut(&5).is_none());
823 assert_eq!(cache.get_mut(&6), Some(&mut 60));
824 assert_eq!(cache.get_mut(&7), Some(&mut 70));
825 assert_eq!(cache.get_mut(&8), Some(&mut 80));
826 }
827
828 #[test]
829 fn test_clear() {
830 let mut cache = LruCache::new(2);
831 cache.insert(1, 10);
832 cache.insert(2, 20);
833 cache.clear();
834 assert!(cache.get_mut(&1).is_none());
835 assert!(cache.get_mut(&2).is_none());
836 assert_eq!(format!("{:?}", cache), "{}");
837 }
838
839 #[test]
840 fn test_iter() {
841 let mut cache = LruCache::new(3);
842 cache.insert(1, 10);
843 cache.insert(2, 20);
844 cache.insert(3, 30);
845 cache.insert(4, 40);
846 cache.insert(5, 50);
847 assert_eq!(
848 cache.iter().collect::<Vec<_>>(),
849 [(&3, &30), (&4, &40), (&5, &50)]
850 );
851 assert_eq!(
852 cache.iter_mut().collect::<Vec<_>>(),
853 [(&3, &mut 30), (&4, &mut 40), (&5, &mut 50)]
854 );
855 assert_eq!(
856 cache.iter().rev().collect::<Vec<_>>(),
857 [(&5, &50), (&4, &40), (&3, &30)]
858 );
859 assert_eq!(
860 cache.iter_mut().rev().collect::<Vec<_>>(),
861 [(&5, &mut 50), (&4, &mut 40), (&3, &mut 30)]
862 );
863 }
864
865 struct VecLen;
866
867 impl<K, T> Meter<K, Vec<T>> for VecLen {
868 type Measure = usize;
869 fn measure<Q: ?Sized>(&self, _: &Q, v: &Vec<T>) -> usize
870 where
871 K: Borrow<Q>,
872 {
873 v.len()
874 }
875 }
876
877 #[test]
878 fn test_metered_cache() {
879 let mut cache = LruCache::with_meter(5, VecLen);
880 cache.insert("foo1", vec![1, 2]);
881 assert_eq!(cache.size(), 2);
882 cache.insert("foo2", vec![3, 4]);
883 cache.insert("foo3", vec![5, 6]);
884 assert_eq!(cache.size(), 4);
885 assert!(!cache.contains_key("foo1"));
886 cache.insert("foo2", vec![7, 8]);
887 cache.insert("foo4", vec![9, 10]);
888 assert_eq!(cache.size(), 4);
889 assert!(!cache.contains_key("foo3"));
890 assert_eq!(cache.get("foo2"), Some(&vec![7, 8]));
891 }
892
893 #[test]
894 fn test_metered_cache_reinsert_larger() {
895 let mut cache = LruCache::with_meter(5, VecLen);
896 cache.insert("foo1", vec![1, 2]);
897 cache.insert("foo2", vec![3, 4]);
898 assert_eq!(cache.size(), 4);
899 cache.insert("foo2", vec![5, 6, 7, 8]);
900 assert_eq!(cache.size(), 4);
901 assert!(!cache.contains_key("foo1"));
902 }
903
904 #[test]
905 fn test_metered_cache_oversize() {
906 let mut cache = LruCache::with_meter(2, VecLen);
907 cache.insert("foo1", vec![1, 2]);
908 cache.insert("foo2", vec![3, 4, 5, 6]);
909 assert_eq!(cache.size(), 0);
910 assert!(!cache.contains_key("foo1"));
911 assert!(!cache.contains_key("foo2"));
912 }
913
914 #[cfg(feature = "heapsize")]
915 #[test]
916 fn test_heapsize_cache() {
917 use super::HeapSize;
918
919 let mut cache = LruCache::<&str, (u8, u8, u8), _, _>::with_meter(8, HeapSize);
920 cache.insert("foo1", (1, 2, 3));
921 cache.insert("foo2", (4, 5, 6));
922 cache.insert("foo3", (7, 8, 9));
923 assert!(!cache.contains_key("foo1"));
924 cache.insert("foo2", (10, 11, 12));
925 cache.insert("foo4", (13, 14, 15));
926 assert!(!cache.contains_key("foo3"));
927 }
928}