burning_cache/
lib.rs

1use std::{collections::HashMap, sync::{Arc, Mutex}};
2use tokio::time::{sleep, Duration};
3use std::time::Instant;
4use lazy_static::lazy_static;
5use sha2::{Sha256, Digest};
6
7#[derive(Clone, Debug)]
8pub struct CacheValue {
9    pub value: String,
10    pub expiration: Option<Instant>,
11}
12fn get_key(key : String) -> Vec<u8>{
13    let mut hasher = Sha256::new();
14    hasher.update(key.as_bytes());
15    let result = hasher.finalize();
16    return result.as_slice().to_vec()
17}
18impl CacheValue {
19    pub fn new(value: String, ttl: Option<Duration>) -> Self {
20        CacheValue {
21            value,
22            expiration: ttl.map(|ttl| Instant::now() + ttl),
23        }
24    }
25
26    pub fn is_expired(&self) -> bool {
27        if let Some(expiration) = self.expiration {
28            return Instant::now() > expiration;
29        }
30        false
31    }
32}
33
34pub struct CacheManager {
35    cache: Arc<Mutex<HashMap<Vec<u8>, CacheValue>>>,
36    debris: u64,
37}
38
39impl CacheManager {
40    pub fn new() -> Self {
41        CacheManager {
42            cache: Arc::new(Mutex::new(HashMap::new())),
43            debris: 1,
44        }
45    }
46    pub async fn set(&self, key: String, value: String, ttl: Option<Duration>) {
47        let cache_value = CacheValue::new(value, ttl);
48        let mut cache = self.cache.lock().unwrap();
49        cache.insert(get_key(key), cache_value);
50    }
51    pub async fn get(&self, key: String) -> Option<String> {
52        let cache = self.cache.lock().unwrap();
53        if let Some(cache_value) = cache.get(&get_key(key)) {
54            if cache_value.is_expired() {
55                None
56            } else {
57                Some(cache_value.value.clone())
58            }
59        } else {
60            None
61        }
62    }
63    pub async fn exists(&self, key: String) -> bool {
64        let cache = self.cache.lock().unwrap();
65        cache.contains_key(&get_key(key))
66    }
67    pub async fn delete(&self, key: String) {
68        let mut cache = self.cache.lock().unwrap();
69        cache.remove(&get_key(key));
70    }
71    pub async fn clear(&self) {
72        let mut cache = self.cache.lock().unwrap();
73        cache.clear();
74    }
75    pub fn start_clean_up(&self) {
76        let cache = self.cache.clone();
77        let debris = self.debris;
78        tokio::spawn(async move {
79            loop {
80                sleep(Duration::from_secs(debris)).await;
81                let mut cache = cache.lock().unwrap();
82                let keys_to_remove: Vec<Vec<u8>> = cache.iter()
83                    .filter(|(_, v)| v.is_expired())
84                    .map(|(k, _)| k.clone())
85                    .collect();
86                for key in keys_to_remove {
87                    cache.remove(&key);
88                }
89            }
90        });
91    }
92}
93
94lazy_static! {
95    pub static ref CACHE_MANAGER: CacheManager = CacheManager::new();
96}