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/// `peek` and `contains` are O(1). `put`, `get`, and
12/// `remove` are O(n) in the number of cached entries
13/// because promoting or dropping a key scans the
14/// recency deque (`VecDeque::retain`); `iter` is O(n).
15///
16/// # Capacity edge cases
17///
18/// - `capacity = 0` - the cache accepts no entries. Both
19///   `put` and `get` behave as no-ops (well, `get` still
20///   evicts because there's nothing to evict; `put`
21///   silently drops the entry).
22/// - `capacity = 1` - the cache holds exactly one entry.
23///   Every `put` evicts the previous entry.
24///
25/// # Lombok `New` derivation
26///
27/// `#[derive(New)]` generates `LruCache::new(capacity)` —
28/// the `map` and `order` fields are skipped with
29/// `#[new(skip)]` so Lombok falls back to
30/// `<HashMap as Default>::default()` and
31/// `<VecDeque as Default>::default()` (which both call
32/// `new()` internally), preserving the canonical
33/// single-argument call site.
34#[derive(Clone, Data, Debug, New)]
35pub struct LruCache<K, V>
36where
37    K: Clone + Eq + Hash,
38{
39    /// The maximum number of entries before eviction
40    /// kicks in.
41    #[get(pub(crate))]
42    pub(crate) capacity: usize,
43    /// The current entries, keyed by K. Default-initialised
44    /// via `#[new(skip)]` (`HashMap::new()`).
45    #[new(skip)]
46    pub(crate) map: HashMap<K, V>,
47    /// The MRU-first order. Front = most recently used,
48    /// back = least recently used. Default-initialised
49    /// via `#[new(skip)]` (`VecDeque::new()`).
50    #[new(skip)]
51    pub(crate) order: VecDeque<K>,
52}