1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
mod cache;
use cache::*;
use std::collections::HashMap;
use std::hash::Hash;
pub use cache::Iter;
#[cfg(test)]
mod tests;
#[derive(Debug, Default)]
pub struct LRUMap<K, T, const N: usize> {
cache: Cache<(K, T), N>,
indices: HashMap<K, u16>,
}
impl<K, T, const N: usize> LRUMap<K, T, N>
where
K: Hash + Eq + Clone
{
pub fn put(&mut self, key: K, value: T) -> Option<T> {
match self.indices.get(&key) {
None => {
self.cache.insert((key.clone(), value));
self.indices.insert(key, self.cache.head);
None
},
Some(idx) => {
Some(self.cache.replace(*idx, (key, value)).1)
}
}
}
pub fn get(&mut self, key: &K) -> Option<&T> {
match self.indices.get(key) {
None => None,
Some(idx) => Some(&self.cache.get(*idx).1)
}
}
pub fn get_mut(&mut self, key: &K) -> Option<&mut T> {
match self.indices.get(key) {
None => None,
Some(idx) => Some(&mut self.cache.get_mut(*idx).1)
}
}
pub fn remove_one(&mut self, key: &K) {
if let Some(idx) = self.indices.remove(key) {
self.cache.remove(idx);
}
}
pub fn remove<F>(&mut self, mut pred: F)
where
F: FnMut(&K) -> bool
{
let old_indices = std::mem::replace(&mut self.indices, HashMap::new());
for (key, idx) in old_indices.into_iter() {
if pred(&key) {
self.cache.remove(idx);
} else {
self.indices.insert(key, idx);
}
}
}
#[inline]
pub fn clear(&mut self) {
self.indices.clear();
self.cache.clear();
}
#[inline]
pub fn len(&self) -> usize {
self.cache.len()
}
pub fn touch<F>(&mut self, mut pred: F)
where
F: FnMut(&K) -> bool
{
for (key, idx) in self.indices.iter() {
if pred(key) {
self.cache.touch_index(*idx);
}
}
}
pub fn iter(&self) -> Iter<(K, T), N> {
self.cache.iter()
}
pub fn keys(&self) -> impl Iterator<Item=&K> {
self.indices.keys()
}
}