terminals_core/primitives/
registry.rs1use std::collections::{HashMap, VecDeque};
2use std::hash::Hash;
3
4pub struct BasicRegistry<K, V> {
5 map: HashMap<K, V>,
6}
7
8impl<K: Hash + Eq, V> Default for BasicRegistry<K, V> {
9 fn default() -> Self {
10 Self {
11 map: HashMap::new(),
12 }
13 }
14}
15
16impl<K: Hash + Eq, V> BasicRegistry<K, V> {
17 pub fn new() -> Self {
18 Self::default()
19 }
20 pub fn get(&self, key: &K) -> Option<&V> {
21 self.map.get(key)
22 }
23 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
24 self.map.insert(key, value)
25 }
26 pub fn remove(&mut self, key: &K) -> Option<V> {
27 self.map.remove(key)
28 }
29 pub fn len(&self) -> usize {
30 self.map.len()
31 }
32 pub fn is_empty(&self) -> bool {
33 self.map.is_empty()
34 }
35 pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
36 self.map.iter()
37 }
38}
39
40pub struct LruRegistry<K, V> {
41 map: HashMap<K, V>,
42 order: VecDeque<K>,
43 capacity: usize,
44}
45
46impl<K: Hash + Eq + Clone, V> LruRegistry<K, V> {
47 pub fn new(capacity: usize) -> Self {
48 Self {
49 map: HashMap::with_capacity(capacity),
50 order: VecDeque::with_capacity(capacity),
51 capacity,
52 }
53 }
54
55 pub fn get(&mut self, key: &K) -> Option<&V> {
56 if self.map.contains_key(key) {
57 self.order.retain(|k| k != key);
58 self.order.push_back(key.clone());
59 self.map.get(key)
60 } else {
61 None
62 }
63 }
64
65 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
66 if self.map.contains_key(&key) {
67 self.order.retain(|k| k != &key);
68 } else if self.map.len() >= self.capacity {
69 if let Some(evicted) = self.order.pop_front() {
70 self.map.remove(&evicted);
71 }
72 }
73 self.order.push_back(key.clone());
74 self.map.insert(key, value)
75 }
76
77 pub fn remove(&mut self, key: &K) -> Option<V> {
78 self.order.retain(|k| k != key);
79 self.map.remove(key)
80 }
81
82 pub fn len(&self) -> usize {
83 self.map.len()
84 }
85 pub fn is_empty(&self) -> bool {
86 self.map.is_empty()
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn test_basic_registry() {
96 let mut reg = BasicRegistry::new();
97 reg.insert("key1", 42);
98 assert_eq!(reg.get(&"key1"), Some(&42));
99 assert_eq!(reg.len(), 1);
100 }
101
102 #[test]
103 fn test_lru_registry_eviction() {
104 let mut reg = LruRegistry::new(2);
105 reg.insert("a", 1);
106 reg.insert("b", 2);
107 reg.insert("c", 3); assert_eq!(reg.get(&"a"), None);
109 assert_eq!(reg.get(&"c"), Some(&3));
110 }
111
112 #[test]
113 fn test_lru_access_refreshes() {
114 let mut reg = LruRegistry::new(2);
115 reg.insert("a", 1);
116 reg.insert("b", 2);
117 reg.get(&"a"); reg.insert("c", 3); assert_eq!(reg.get(&"a"), Some(&1));
120 assert_eq!(reg.get(&"b"), None);
121 }
122
123 #[test]
124 fn test_registry_remove() {
125 let mut reg = BasicRegistry::new();
126 reg.insert("key", 42);
127 assert_eq!(reg.remove(&"key"), Some(42));
128 assert_eq!(reg.get(&"key"), None);
129 }
130}