1use alloc::collections::BTreeMap;
15use alloc::vec::Vec;
16
17#[derive(Clone, Debug, PartialEq, Eq)]
18struct Slot<V> {
19 v: V,
20 tick: u64,
21 weight: u64,
22}
23
24#[derive(Clone, Debug, PartialEq, Eq)]
26pub struct Lru<K: Ord + Clone, V> {
27 map: BTreeMap<K, Slot<V>>,
28 order: BTreeMap<u64, K>,
30 tick: u64,
31 weight: u64,
32 pub max_len: usize,
34 pub max_weight: u64,
36}
37
38impl<K: Ord + Clone, V> Lru<K, V> {
39 pub fn new(max_len: usize, max_weight: u64) -> Lru<K, V> {
40 Lru { map: BTreeMap::new(), order: BTreeMap::new(), tick: 0, weight: 0, max_len, max_weight }
41 }
42 pub fn len(&self) -> usize {
43 self.map.len()
44 }
45 pub fn is_empty(&self) -> bool {
46 self.map.is_empty()
47 }
48 pub fn weight(&self) -> u64 {
50 self.weight
51 }
52 pub fn contains(&self, k: &K) -> bool {
53 self.map.contains_key(k)
54 }
55 pub fn peek(&self, k: &K) -> Option<&V> {
57 self.map.get(k).map(|s| &s.v)
58 }
59 fn touch(&mut self, k: &K) {
60 self.tick += 1;
61 let t = self.tick;
62 if let Some(s) = self.map.get_mut(k) {
63 self.order.remove(&s.tick);
64 s.tick = t;
65 self.order.insert(t, k.clone());
66 }
67 }
68 pub fn get(&mut self, k: &K) -> Option<&V> {
70 if !self.map.contains_key(k) {
71 return None;
72 }
73 self.touch(k);
74 self.map.get(k).map(|s| &s.v)
75 }
76 pub fn get_mut(&mut self, k: &K) -> Option<&mut V> {
78 if !self.map.contains_key(k) {
79 return None;
80 }
81 self.touch(k);
82 self.map.get_mut(k).map(|s| &mut s.v)
83 }
84 pub fn insert(&mut self, k: K, v: V, weight: u64) -> Vec<(K, V)> {
87 let _ = self.remove(&k);
88 self.tick += 1;
89 let t = self.tick;
90 self.order.insert(t, k.clone());
91 self.map.insert(k, Slot { v, tick: t, weight });
92 self.weight = self.weight.saturating_add(weight);
93 let mut out = Vec::new();
94 while (self.max_len > 0 && self.map.len() > self.max_len) || (self.max_weight > 0 && self.weight > self.max_weight) {
95 match self.pop_lru() {
96 Some(e) => out.push(e),
97 None => break,
98 }
99 }
100 out
101 }
102 pub fn remove(&mut self, k: &K) -> Option<V> {
103 let s = self.map.remove(k)?;
104 self.order.remove(&s.tick);
105 self.weight = self.weight.saturating_sub(s.weight);
106 Some(s.v)
107 }
108 pub fn pop_lru(&mut self) -> Option<(K, V)> {
110 let (&t, _) = self.order.iter().next()?;
111 let k = self.order.remove(&t)?;
112 let s = self.map.remove(&k)?;
113 self.weight = self.weight.saturating_sub(s.weight);
114 Some((k, s.v))
115 }
116 pub fn clear(&mut self) {
117 self.map.clear();
118 self.order.clear();
119 self.weight = 0;
120 }
121 pub fn keys(&self) -> impl Iterator<Item = &K> {
123 self.order.values()
124 }
125 pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
127 self.map.iter().map(|(k, s)| (k, &s.v))
128 }
129}