use linked_hash_set::LinkedHashSet; use std::{borrow::Borrow, hash::Hash, num::NonZeroUsize}; /// A minimal LRU cache based on a `LinkedHashSet` with limited capacity. /// /// If the length exceeds the set capacity, the oldest element will be removed /// In the limit, for each element inserted the oldest existing element will be removed. #[derive(Debug, Clone)] pub struct LruCache { limit: NonZeroUsize, inner: LinkedHashSet, } impl LruCache { /// Creates a new `LruCache` using the given limit pub fn new(limit: NonZeroUsize) -> Self { Self { inner: LinkedHashSet::new(), limit } } /// Insert an element into the set. /// /// If the element is new (did not exist before [`LruCache::insert()`]) was called, then the /// given length will be enforced and the oldest element will be removed if the limit was /// exceeded. /// /// If the set did not have this value present, true is returned. /// If the set did have this value present, false is returned. pub fn insert(&mut self, entry: T) -> bool { if self.inner.insert(entry) { if self.limit.get() == self.inner.len() { // remove the oldest element in the set self.inner.pop_front(); } return true } false } /// Returns `true` if the set contains a value. pub fn contains(&self, value: &Q) -> bool where T: Borrow, Q: Hash + Eq, { self.inner.contains(value) } } impl Extend for LruCache where T: Eq + Hash, { fn extend>(&mut self, iter: I) { for item in iter.into_iter() { self.insert(item); } } }