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}