1use crate::error::CacheError;
6use std::collections::HashMap;
7use std::sync::{Arc, RwLock};
8use std::time::{Duration, Instant};
9
10pub trait Cache: Send + Sync {
11 fn get(&self, key: &str) -> Result<Option<Vec<u8>>, CacheError>;
12 fn set(&self, key: &str, value: Vec<u8>, ttl: Option<Duration>) -> Result<(), CacheError>;
13 fn delete(&self, key: &str) -> Result<(), CacheError>;
14 fn clear(&self) -> Result<(), CacheError>;
15 fn exists(&self, key: &str) -> Result<bool, CacheError>;
16 fn expire(&self, key: &str, ttl: Duration) -> Result<(), CacheError>;
17 fn ttl(&self, key: &str) -> Result<Option<Duration>, CacheError>;
18}
19
20#[derive(Clone)]
21pub struct MemoryCache {
22 data: Arc<RwLock<HashMap<String, CacheEntry>>>,
23 default_ttl: Option<Duration>,
24}
25
26struct CacheEntry {
27 value: Vec<u8>,
28 expires_at: Option<Instant>,
29}
30
31impl MemoryCache {
32 pub fn new() -> Self {
33 Self {
34 data: Arc::new(RwLock::new(HashMap::new())),
35 default_ttl: None,
36 }
37 }
38
39 pub fn with_ttl(ttl: Duration) -> Self {
40 Self {
41 data: Arc::new(RwLock::new(HashMap::new())),
42 default_ttl: Some(ttl),
43 }
44 }
45}
46
47impl Default for MemoryCache {
48 fn default() -> Self {
49 Self::new()
50 }
51}
52
53impl Cache for MemoryCache {
54 fn get(&self, key: &str) -> Result<Option<Vec<u8>>, CacheError> {
55 let data = self.data.read()?;
56 if let Some(entry) = data.get(key) {
57 if let Some(expires_at) = entry.expires_at {
58 if expires_at <= Instant::now() {
59 return Ok(None);
60 }
61 }
62 Ok(Some(entry.value.clone()))
63 } else {
64 Ok(None)
65 }
66 }
67
68 fn set(&self, key: &str, value: Vec<u8>, ttl: Option<Duration>) -> Result<(), CacheError> {
69 let expires_at = ttl.or(self.default_ttl).map(|d| Instant::now() + d);
70 let mut data = self.data.write()?;
71 data.insert(key.to_string(), CacheEntry { value, expires_at });
72 Ok(())
73 }
74
75 fn delete(&self, key: &str) -> Result<(), CacheError> {
76 let mut data = self.data.write()?;
77 data.remove(key);
78 Ok(())
79 }
80
81 fn clear(&self) -> Result<(), CacheError> {
82 let mut data = self.data.write()?;
83 data.clear();
84 Ok(())
85 }
86
87 fn exists(&self, key: &str) -> Result<bool, CacheError> {
88 let data = self.data.read()?;
89 if let Some(entry) = data.get(key) {
90 if let Some(expires_at) = entry.expires_at {
91 if expires_at <= Instant::now() {
92 return Ok(false);
93 }
94 }
95 Ok(true)
96 } else {
97 Ok(false)
98 }
99 }
100
101 fn expire(&self, key: &str, ttl: Duration) -> Result<(), CacheError> {
102 let mut data = self.data.write()?;
103 if let Some(entry) = data.get_mut(key) {
104 entry.expires_at = Some(Instant::now() + ttl);
105 Ok(())
106 } else {
107 Err(CacheError::NotFound(key.to_string()))
108 }
109 }
110
111 fn ttl(&self, key: &str) -> Result<Option<Duration>, CacheError> {
112 let data = self.data.read()?;
113 if let Some(entry) = data.get(key) {
114 if let Some(expires_at) = entry.expires_at {
115 if expires_at <= Instant::now() {
116 return Ok(None);
117 }
118 let remaining = expires_at.duration_since(Instant::now());
119 Ok(Some(remaining))
120 } else {
121 Ok(None)
122 }
123 } else {
124 Err(CacheError::NotFound(key.to_string()))
125 }
126 }
127}
128
129pub struct MultiLevelCache {
130 caches: Vec<Box<dyn Cache>>,
131}
132
133impl MultiLevelCache {
134 pub fn new() -> Self {
135 Self { caches: Vec::new() }
136 }
137
138 pub fn add_cache(mut self, cache: Box<dyn Cache>) -> Self {
139 self.caches.push(cache);
140 self
141 }
142}
143
144impl Default for MultiLevelCache {
145 fn default() -> Self {
146 Self::new()
147 }
148}
149
150impl Cache for MultiLevelCache {
151 fn get(&self, key: &str) -> Result<Option<Vec<u8>>, CacheError> {
152 for (i, cache) in self.caches.iter().enumerate() {
153 if let Ok(Some(value)) = cache.get(key) {
154 let ttl = cache.ttl(key).ok().flatten();
156 for j in 0..i {
157 let _ = self.caches[j].set(key, value.clone(), ttl);
158 }
159 return Ok(Some(value));
160 }
161 }
162 Ok(None)
163 }
164
165 fn set(&self, key: &str, value: Vec<u8>, ttl: Option<Duration>) -> Result<(), CacheError> {
166 for cache in &self.caches {
167 cache.set(key, value.clone(), ttl)?;
168 }
169 Ok(())
170 }
171
172 fn delete(&self, key: &str) -> Result<(), CacheError> {
173 for cache in &self.caches {
174 cache.delete(key)?;
175 }
176 Ok(())
177 }
178
179 fn clear(&self) -> Result<(), CacheError> {
180 for cache in &self.caches {
181 cache.clear()?;
182 }
183 Ok(())
184 }
185
186 fn exists(&self, key: &str) -> Result<bool, CacheError> {
187 for cache in &self.caches {
188 if cache.exists(key)? {
189 return Ok(true);
190 }
191 }
192 Ok(false)
193 }
194
195 fn expire(&self, key: &str, ttl: Duration) -> Result<(), CacheError> {
196 for cache in &self.caches {
197 cache.expire(key, ttl)?;
198 }
199 Ok(())
200 }
201
202 fn ttl(&self, key: &str) -> Result<Option<Duration>, CacheError> {
203 if let Some(cache) = self.caches.first() {
204 cache.ttl(key)
205 } else {
206 Err(CacheError::NotFound("No caches configured".to_string()))
207 }
208 }
209}
210
211#[derive(Debug, Clone, Default)]
212pub struct CacheStats {
213 pub hits: u64,
214 pub misses: u64,
215 pub sets: u64,
216 pub deletes: u64,
217}
218
219#[cfg(test)]
220mod tests {
221 use super::*;
222
223 #[test]
224 fn test_memory_cache_set_get() {
225 let cache = MemoryCache::new();
226 cache.set("key1", b"value1".to_vec(), None).unwrap();
227 let val = cache.get("key1").unwrap();
228 assert_eq!(val, Some(b"value1".to_vec()));
229 }
230
231 #[test]
232 fn test_memory_cache_delete() {
233 let cache = MemoryCache::new();
234 cache.set("key1", b"value1".to_vec(), None).unwrap();
235 cache.delete("key1").unwrap();
236 let val = cache.get("key1").unwrap();
237 assert_eq!(val, None);
238 }
239
240 #[test]
241 fn test_memory_cache_exists() {
242 let cache = MemoryCache::new();
243 cache.set("key1", b"value1".to_vec(), None).unwrap();
244 let exists = cache.exists("key1").unwrap();
245 assert!(exists);
246 let exists2 = cache.exists("nonexistent").unwrap();
247 assert!(!exists2);
248 }
249
250 #[test]
251 fn test_memory_cache_clear() {
252 let cache = MemoryCache::new();
253 cache.set("key1", b"value1".to_vec(), None).unwrap();
254 cache.set("key2", b"value2".to_vec(), None).unwrap();
255 cache.clear().unwrap();
256 let val = cache.get("key1").unwrap();
257 assert_eq!(val, None);
258 }
259
260 #[test]
261 fn test_memory_cache_with_ttl() {
262 let cache = MemoryCache::with_ttl(Duration::from_secs(1));
263 cache.set("key1", b"value1".to_vec(), None).unwrap();
264 let val = cache.get("key1").unwrap();
265 assert!(val.is_some());
266 }
267
268 #[test]
269 fn test_cache_stats() {
270 let stats = CacheStats::default();
271 assert_eq!(stats.hits, 0);
272 assert_eq!(stats.misses, 0);
273 }
274
275 #[test]
276 fn test_multi_level_cache() {
277 let cache1 = MemoryCache::new();
278 let cache2 = MemoryCache::new();
279 let multi = MultiLevelCache::new()
280 .add_cache(Box::new(cache1))
281 .add_cache(Box::new(cache2));
282
283 multi.set("key1", b"value1".to_vec(), None).unwrap();
284 let val = multi.get("key1").unwrap();
285 assert_eq!(val, Some(b"value1".to_vec()));
286
287 multi.delete("key1").unwrap();
288 let val = multi.get("key1").unwrap();
289 assert_eq!(val, None);
290 }
291}