terminals-core 0.1.0

Core runtime primitives for Terminals OS: phase dynamics, AXON wire protocol, substrate engine, and sematonic types
Documentation
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); // should evict "a"
        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"); // refresh "a"
        reg.insert("c", 3); // should evict "b" (LRU), not "a"
        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);
    }
}