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}