#[cfg(feature = "alloc")]
extern crate alloc;
use alloc::collections::BTreeMap;
use alloc::vec::Vec;
#[derive(Debug, Default, PartialEq)]
pub struct DirCache<K, V> {
cache: BTreeMap<K, V>,
order: Vec<K>,
max_size: usize,
}
impl<K: Ord + Clone, V> DirCache<K, V> {
pub fn new(max_size: usize) -> Self {
DirCache {
cache: BTreeMap::new(),
order: Vec::new(),
max_size,
}
}
pub fn len(&self) -> usize {
self.cache.len()
}
pub fn is_empty(&self) -> bool {
self.cache.is_empty()
}
pub fn set(&mut self, key: K, dir: V) {
if let Some(pos) = self.order.iter().position(|k| *k == key) {
self.order.remove(pos);
}
self.order.insert(0, key.clone());
while self.order.len() > self.max_size {
let last = self.order.pop().unwrap();
self.delete(&last);
}
self.cache.insert(key, dir);
}
pub fn get(&mut self, key: &K) -> Option<&V> {
if let Some(pos) = self.order.iter().position(|k| *k == *key) {
self.order.remove(pos);
self.order.insert(0, key.clone());
}
self.cache.get(key)
}
pub fn delete(&mut self, key: &K) -> bool {
self.cache.remove(key).is_some()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_functionality() {
let mut cache = DirCache::<u32, u32>::new(3);
cache.set(1, 2);
assert_eq!(cache.get(&1), Some(&2));
assert!(cache.delete(&1));
assert!(!cache.delete(&1));
}
#[test]
fn test_max_size() {
let mut cache = DirCache::<u32, u32>::new(5);
assert!(cache.is_empty());
cache.set(1, 2);
cache.set(2, 3);
cache.set(3, 4);
cache.set(4, 5);
cache.set(5, 6);
cache.set(6, 7);
cache.set(7, 8);
assert_eq!(
cache,
DirCache::<u32, u32> {
cache: BTreeMap::from([(3, 4), (4, 5), (5, 6), (6, 7), (7, 8)]),
order: vec![7, 6, 5, 4, 3],
max_size: 5
}
);
cache.set(5, 9);
assert_eq!(
cache,
DirCache::<u32, u32> {
cache: BTreeMap::from([(3, 4), (4, 5), (5, 9), (6, 7), (7, 8)]),
order: vec![5, 7, 6, 4, 3],
max_size: 5
}
);
assert_eq!(cache.len(), 5);
assert!(!cache.is_empty());
assert_eq!(cache.get(&2), None);
assert_eq!(cache.get(&3), Some(&4));
assert_eq!(
cache,
DirCache::<u32, u32> {
cache: BTreeMap::from([(3, 4), (4, 5), (5, 9), (6, 7), (7, 8)]),
order: vec![3, 5, 7, 6, 4],
max_size: 5
}
);
}
}