1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use Hash;
use DeepSizeOf;
use crateDeepSizeOf;
pub const NUM_POLICY_BUCKETS: usize = 3;
/// Cache eviction policy determining retention priority.
///
/// Lower discriminant values = higher priority = evicted last.
/// Marker trait for cache keys. Associates a key type with its value type.
///
/// # Example
///
/// ```
/// use priority_lfu::{DeepSizeOf, CacheKey, CachePolicy};
///
/// #[derive(Hash, Eq, PartialEq, Clone)]
/// struct UserId(u64);
///
/// #[derive(Clone, Debug, PartialEq, DeepSizeOf)]
/// struct UserData {
/// name: String,
/// }
///
/// impl CacheKey for UserId {
/// type Value = UserData;
///
/// fn policy(&self) -> CachePolicy {
/// CachePolicy::Standard
/// }
/// }
/// ```
/// Trait for borrowed keys that can look up entries of type `K`.
///
/// This trait enables zero-allocation cache lookups using borrowed key types.
/// For example, you can use `(&str, &str)` to look up entries stored with
/// `(String, String)` keys, avoiding the allocation of owned strings.
///
/// # Hash Consistency Requirement
///
/// **CRITICAL**: The `Hash` implementation MUST produce the same hash as `K`
/// for equivalent keys. If the hashes differ, lookups will fail.
///
/// # Example
///
/// ```
/// use std::hash::{Hash, Hasher};
/// use priority_lfu::{CacheKey, CacheKeyLookup, CachePolicy, DeepSizeOf};
///
/// // Owned key type
/// #[derive(Hash, Eq, PartialEq, Clone)]
/// struct DbCacheKey(String, String);
///
/// impl CacheKey for DbCacheKey {
/// type Value = String;
/// }
///
/// // Borrowed lookup type
/// struct DbCacheKeyRef<'a>(&'a str, &'a str);
///
/// impl Hash for DbCacheKeyRef<'_> {
/// fn hash<H: Hasher>(&self, state: &mut H) {
/// // MUST match DbCacheKey's hash implementation
/// self.0.hash(state);
/// self.1.hash(state);
/// }
/// }
///
/// impl CacheKeyLookup<DbCacheKey> for DbCacheKeyRef<'_> {
/// fn eq_key(&self, key: &DbCacheKey) -> bool {
/// self.0 == key.0 && self.1 == key.1
/// }
///
/// fn to_owned_key(self) -> DbCacheKey {
/// DbCacheKey(self.0.to_owned(), self.1.to_owned())
/// }
/// }
/// ```
/// Blanket implementation: every `CacheKey` can look up itself.
///
/// This allows existing code using `cache.get(&key)` to continue working unchanged.