Skip to main content

euv_core/reactive/cache/
struct.rs

1use super::*;
2
3/// A fixed-capacity LRU cache.
4///
5/// The cache holds at most `capacity` entries. When a
6/// `put` would exceed the capacity, the
7/// least-recently-used entry is evicted. `get` updates
8/// the recency so the just-read entry becomes the most-
9/// recently-used.
10///
11/// All operations are O(1) amortized (`put`, `get`,
12/// `remove`, `contains`) except `iter`, which is O(n).
13///
14/// # Capacity edge cases
15///
16/// - `capacity = 0` - the cache accepts no entries. Both
17///   `put` and `get` behave as no-ops (well, `get` still
18///   evicts because there's nothing to evict; `put`
19///   silently drops the entry).
20/// - `capacity = 1` - the cache holds exactly one entry.
21///   Every `put` evicts the previous entry.
22///
23/// # Lombok `New` derivation
24///
25/// `#[derive(New)]` generates `LruCache::new(capacity)` —
26/// the `map` and `order` fields are skipped with
27/// `#[new(skip)]` so Lombok falls back to
28/// `<HashMap as Default>::default()` and
29/// `<VecDeque as Default>::default()` (which both call
30/// `new()` internally), preserving the canonical
31/// single-argument call site.
32#[derive(Clone, Data, Debug, New)]
33pub struct LruCache<K, V>
34where
35    K: Clone + Eq + Hash,
36{
37    /// The maximum number of entries before eviction
38    /// kicks in.
39    #[get(pub(crate))]
40    pub(crate) capacity: usize,
41    /// The current entries, keyed by K. Default-initialised
42    /// via `#[new(skip)]` (`HashMap::new()`).
43    #[new(skip)]
44    pub(crate) map: HashMap<K, V>,
45    /// The MRU-first order. Front = most recently used,
46    /// back = least recently used. Default-initialised
47    /// via `#[new(skip)]` (`VecDeque::new()`).
48    #[new(skip)]
49    pub(crate) order: VecDeque<K>,
50}