oxistore_cache/
builder.rs1use crate::bounded::BoundedCache;
9use crate::sharded::ShardedCache;
10use crate::{ArcCache, LfuCache, LruCache, WTinyLfuCache};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum CachePolicy {
15 Lru,
17 Arc,
19 Lfu,
21 WTinyLfu,
23}
24
25#[derive(Debug, Clone)]
41pub struct CacheBuilder {
42 capacity: usize,
44 policy: CachePolicy,
46 max_bytes: Option<usize>,
48 n_shards: Option<usize>,
50}
51
52impl CacheBuilder {
53 #[must_use]
55 pub fn new(capacity: usize) -> Self {
56 CacheBuilder {
57 capacity,
58 policy: CachePolicy::Lru,
59 max_bytes: None,
60 n_shards: None,
61 }
62 }
63
64 #[must_use]
66 pub fn policy(mut self, p: CachePolicy) -> Self {
67 self.policy = p;
68 self
69 }
70
71 #[must_use]
73 pub fn max_bytes(mut self, b: usize) -> Self {
74 self.max_bytes = Some(b);
75 self
76 }
77
78 #[must_use]
82 pub fn n_shards(mut self, n: usize) -> Self {
83 self.n_shards = Some(n);
84 self
85 }
86
87 #[must_use]
89 pub fn build_lru(self) -> LruCache<Vec<u8>, Vec<u8>> {
90 LruCache::new(self.capacity)
91 }
92
93 #[must_use]
95 pub fn build_arc(self) -> ArcCache<Vec<u8>, Vec<u8>> {
96 ArcCache::new(self.capacity)
97 }
98
99 #[must_use]
101 pub fn build_lfu(self) -> LfuCache<Vec<u8>, Vec<u8>> {
102 LfuCache::new(self.capacity)
103 }
104
105 #[must_use]
107 pub fn build_wtinylfu(self) -> WTinyLfuCache<Vec<u8>, Vec<u8>> {
108 WTinyLfuCache::new(self.capacity)
109 }
110
111 #[must_use]
116 pub fn build_bounded_lru(self) -> BoundedCache<LruCache<Vec<u8>, Vec<u8>>> {
117 let max_bytes = self.max_bytes.unwrap_or(self.capacity * 64);
118 BoundedCache::new(LruCache::new(self.capacity), max_bytes)
119 }
120
121 #[must_use]
130 pub fn build_sharded(self) -> ShardedCache {
131 let n = self.n_shards.unwrap_or(8);
132 let shard_cap = (self.capacity / n).max(1);
133 ShardedCache::new(n, shard_cap)
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140 use crate::Cache;
141
142 #[test]
143 fn builder_lru() {
144 let mut cache = CacheBuilder::new(4).policy(CachePolicy::Lru).build_lru();
145 cache.put(b"k".to_vec(), b"v".to_vec());
146 assert_eq!(cache.get(&b"k".to_vec()), Some(&b"v".to_vec()));
147 assert_eq!(cache.cap(), 4);
148 }
149
150 #[test]
151 fn builder_arc() {
152 let mut cache = CacheBuilder::new(4).policy(CachePolicy::Arc).build_arc();
153 cache.put(b"k".to_vec(), b"v".to_vec());
154 assert_eq!(cache.get(&b"k".to_vec()), Some(&b"v".to_vec()));
155 assert_eq!(cache.cap(), 4);
156 }
157
158 #[test]
159 fn builder_lfu() {
160 let mut cache = CacheBuilder::new(4).policy(CachePolicy::Lfu).build_lfu();
161 cache.put(b"k".to_vec(), b"v".to_vec());
162 assert_eq!(cache.get(&b"k".to_vec()), Some(&b"v".to_vec()));
163 assert_eq!(cache.cap(), 4);
164 }
165
166 #[test]
167 fn builder_wtinylfu() {
168 let mut cache = CacheBuilder::new(10)
169 .policy(CachePolicy::WTinyLfu)
170 .build_wtinylfu();
171 cache.put(b"k".to_vec(), b"v".to_vec());
172 assert_eq!(cache.cap(), 10);
173 }
174
175 #[test]
176 fn builder_bounded_default_budget() {
177 let cache = CacheBuilder::new(8).build_bounded_lru();
178 assert_eq!(cache.max_bytes(), 8 * 64);
179 }
180
181 #[test]
182 fn builder_bounded_explicit_budget() {
183 let mut cache = CacheBuilder::new(100).max_bytes(50).build_bounded_lru();
184 assert_eq!(cache.max_bytes(), 50);
185 cache.put(b"key1".to_vec(), b"val1".to_vec()); assert!(cache.current_bytes() <= 50);
188 }
189
190 #[test]
191 fn builder_sharded_default() {
192 let cache = CacheBuilder::new(64).build_sharded();
193 assert_eq!(cache.n_shards(), 8);
194 }
195
196 #[test]
197 fn builder_sharded_custom_shards() {
198 let cache = CacheBuilder::new(32).n_shards(4).build_sharded();
199 assert_eq!(cache.n_shards(), 4);
200 assert_eq!(cache.shard_cap(), 8); }
202
203 #[test]
204 fn builder_each_policy_usable() {
205 let mut lru = CacheBuilder::new(4).build_lru();
207 lru.put(b"a".to_vec(), b"1".to_vec());
208
209 let mut arc = CacheBuilder::new(4).build_arc();
210 arc.put(b"a".to_vec(), b"1".to_vec());
211
212 let mut lfu = CacheBuilder::new(4).build_lfu();
213 lfu.put(b"a".to_vec(), b"1".to_vec());
214
215 let mut wtlfu = CacheBuilder::new(10).build_wtinylfu();
216 wtlfu.put(b"a".to_vec(), b"1".to_vec());
217
218 let mut bounded = CacheBuilder::new(4).max_bytes(200).build_bounded_lru();
219 bounded.put(b"a".to_vec(), b"1".to_vec());
220
221 let sharded = CacheBuilder::new(16).n_shards(4).build_sharded();
222 sharded.put(b"a".to_vec(), b"1".to_vec());
223 assert_eq!(sharded.get(b"a"), Some(b"1".to_vec()));
224 }
225}