cache_mod/cache.rs
1//! The [`Cache`] trait — the common contract every cache type in this crate
2//! implements.
3
4use core::hash::Hash;
5
6/// The common read / write / evict contract every cache type in this crate
7/// implements.
8///
9/// All methods take `&self` (not `&mut self`) so a cache instance can be
10/// shared across threads and across `.await` points without external locking.
11/// Implementations use interior mutability.
12///
13/// # Access semantics
14///
15/// - [`get`](Self::get) is an **access**: it may update the eviction order
16/// (e.g. promoting the entry to most-recently-used).
17/// - [`contains_key`](Self::contains_key) is a **query** only: it must not
18/// update the eviction order.
19/// - [`insert`](Self::insert) is an access on the inserted key.
20/// - [`remove`](Self::remove) is destructive and does not update order.
21///
22/// # Example
23///
24/// ```
25/// use cache_mod::{Cache, LruCache};
26///
27/// let cache: LruCache<&'static str, u32> = LruCache::new(4).expect("capacity > 0");
28///
29/// assert_eq!(cache.insert("a", 1), None);
30/// assert_eq!(cache.get(&"a"), Some(1));
31/// assert!(cache.contains_key(&"a"));
32/// assert_eq!(cache.len(), 1);
33///
34/// assert_eq!(cache.remove(&"a"), Some(1));
35/// assert!(cache.is_empty());
36/// ```
37pub trait Cache<K, V>
38where
39 K: Eq + Hash,
40 V: Clone,
41{
42 /// Returns the value associated with `key`, if any, and counts as an
43 /// access for the purposes of the eviction policy.
44 #[must_use = "the value lookup is the whole reason to call `get`; dropping it is almost certainly a bug"]
45 fn get(&self, key: &K) -> Option<V>;
46
47 /// Inserts `value` under `key`. Returns the previously-stored value if
48 /// `key` was already present.
49 ///
50 /// May evict one or more existing entries to make room, according to
51 /// the cache's eviction policy. For `TinyLfuCache` the value may also
52 /// be silently rejected by the admission filter — in that case the
53 /// return value is `None` and the cache is unchanged.
54 ///
55 /// The return value carries useful information (new-vs-replace, or
56 /// admit-vs-reject for `TinyLfuCache`). If you genuinely don't need
57 /// it, bind to `_` explicitly.
58 fn insert(&self, key: K, value: V) -> Option<V>;
59
60 /// Removes the entry for `key` and returns the value if present.
61 fn remove(&self, key: &K) -> Option<V>;
62
63 /// Returns `true` if the cache currently holds an entry for `key`.
64 ///
65 /// Unlike [`get`](Self::get), this method does **not** count as an
66 /// access — eviction order is left unchanged. For `TtlCache` an
67 /// expired-but-not-yet-cleaned entry is removed during the check and
68 /// the method returns `false`.
69 #[must_use = "ignoring `contains_key` defeats its purpose; use `_` to drop it explicitly"]
70 fn contains_key(&self, key: &K) -> bool;
71
72 /// Number of entries currently stored.
73 ///
74 /// For sharded caches (capacity ≥ 32), this is computed by summing
75 /// each shard's length while briefly locking each in turn — it is
76 /// **not** an atomic snapshot of all shards simultaneously. In
77 /// practice this matters only for code that races a `len()` against
78 /// concurrent writers and expects a single instantaneous value.
79 #[must_use = "ignoring `len` defeats its purpose; use `_` to drop it explicitly"]
80 fn len(&self) -> usize;
81
82 /// Returns `true` when the cache holds no entries.
83 #[must_use = "ignoring `is_empty` defeats its purpose; use `_` to drop it explicitly"]
84 fn is_empty(&self) -> bool {
85 self.len() == 0
86 }
87
88 /// Removes every entry. Capacity is preserved.
89 ///
90 /// For caches with auxiliary state — `LfuCache`'s priority index,
91 /// `TinyLfuCache`'s Count-Min Sketch, the monotonic clocks used by
92 /// `LfuCache` and `TinyLfuCache` — that state is reset alongside the
93 /// entries themselves. Configured capacity / `max_weight` is the only
94 /// piece of state that survives.
95 fn clear(&self);
96
97 /// Configured capacity bound.
98 ///
99 /// The unit depends on the implementation:
100 /// - `LruCache`, `LfuCache`, `TtlCache`, `TinyLfuCache` — maximum number of entries.
101 /// - `SizedCache` — maximum total byte-weight across entries.
102 #[must_use = "ignoring `capacity` defeats its purpose; use `_` to drop it explicitly"]
103 fn capacity(&self) -> usize;
104}