r_tool/cache/
fifo_cache.rs1use std::collections::{HashMap, LinkedList};
2
3pub struct LRUCache<K, V> {
4 capacity: usize,
5 cache: HashMap<K, (V, usize)>,
6 order: LinkedList<K>,
7}
8
9impl<K, V> LRUCache<K, V>
10 where
11 K: Eq + std::hash::Hash + Clone,
12{
13 pub fn new(capacity: usize) -> Self {
21 LRUCache {
22 capacity,
23 cache: HashMap::with_capacity(capacity),
24 order: LinkedList::new(),
25 }
26 }
27
28 pub fn get(&mut self, key: &K) -> Option<&V> {
36 if let Some((value, timestamp)) = self.cache.get_mut(key) {
37 *timestamp = self.order.len();
39 let popped_key = self.order.pop_front().unwrap();
41 self.order.push_back(popped_key);
42 Some(value)
43 } else {
44 None
45 }
46 }
47
48 pub fn put(&mut self, key: K, value: V) {
55 if self.cache.len() >= self.capacity {
56 if let Some(oldest_key) = self.order.pop_front() {
58 self.cache.remove(&oldest_key);
59 }
60 }
61
62 let timestamp = self.order.len();
64 self.cache.insert(key.clone(), (value, timestamp));
65 self.order.push_back(key);
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn test_lru_cache() {
76 let mut lru_cache = LRUCache::new(3);
77
78 lru_cache.put("one", 1);
80 lru_cache.put("two", 2);
81 lru_cache.put("three", 3);
82
83 assert_eq!(lru_cache.get(&"one"), Some(&1));
85
86 lru_cache.put("four", 4);
88
89 assert_eq!(lru_cache.cache.len(), 3);
91 assert_eq!(lru_cache.get(&"one"), Some(&1));
92 assert_eq!(lru_cache.get(&"two"), None); assert_eq!(lru_cache.get(&"three"), Some(&3));
94 assert_eq!(lru_cache.get(&"four"), Some(&4));
95 }
96}