use std::collections::{HashMap, VecDeque};
use std::hash::Hash;
pub struct BasicRegistry<K, V> {
map: HashMap<K, V>,
}
impl<K: Hash + Eq, V> Default for BasicRegistry<K, V> {
fn default() -> Self {
Self {
map: HashMap::new(),
}
}
}
impl<K: Hash + Eq, V> BasicRegistry<K, V> {
pub fn new() -> Self {
Self::default()
}
pub fn get(&self, key: &K) -> Option<&V> {
self.map.get(key)
}
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
self.map.insert(key, value)
}
pub fn remove(&mut self, key: &K) -> Option<V> {
self.map.remove(key)
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
self.map.iter()
}
}
pub struct LruRegistry<K, V> {
map: HashMap<K, V>,
order: VecDeque<K>,
capacity: usize,
}
impl<K: Hash + Eq + Clone, V> LruRegistry<K, V> {
pub fn new(capacity: usize) -> Self {
Self {
map: HashMap::with_capacity(capacity),
order: VecDeque::with_capacity(capacity),
capacity,
}
}
pub fn get(&mut self, key: &K) -> Option<&V> {
if self.map.contains_key(key) {
self.order.retain(|k| k != key);
self.order.push_back(key.clone());
self.map.get(key)
} else {
None
}
}
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
if self.map.contains_key(&key) {
self.order.retain(|k| k != &key);
} else if self.map.len() >= self.capacity {
if let Some(evicted) = self.order.pop_front() {
self.map.remove(&evicted);
}
}
self.order.push_back(key.clone());
self.map.insert(key, value)
}
pub fn remove(&mut self, key: &K) -> Option<V> {
self.order.retain(|k| k != key);
self.map.remove(key)
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic_registry() {
let mut reg = BasicRegistry::new();
reg.insert("key1", 42);
assert_eq!(reg.get(&"key1"), Some(&42));
assert_eq!(reg.len(), 1);
}
#[test]
fn test_lru_registry_eviction() {
let mut reg = LruRegistry::new(2);
reg.insert("a", 1);
reg.insert("b", 2);
reg.insert("c", 3); assert_eq!(reg.get(&"a"), None);
assert_eq!(reg.get(&"c"), Some(&3));
}
#[test]
fn test_lru_access_refreshes() {
let mut reg = LruRegistry::new(2);
reg.insert("a", 1);
reg.insert("b", 2);
reg.get(&"a"); reg.insert("c", 3); assert_eq!(reg.get(&"a"), Some(&1));
assert_eq!(reg.get(&"b"), None);
}
#[test]
fn test_registry_remove() {
let mut reg = BasicRegistry::new();
reg.insert("key", 42);
assert_eq!(reg.remove(&"key"), Some(42));
assert_eq!(reg.get(&"key"), None);
}
}