thread_safe_cache/
embedded.rs

1use std::collections::{BTreeMap, HashMap};
2use std::fs::File;
3use std::hash::Hash;
4use std::io::Write;
5use std::io::Read;
6use std::sync::{Arc, Mutex};
7use crate::{ThreadSafeCachePersistTrait, ThreadSafeCacheTrait};
8
9
10pub struct ThreadSafeCacheImpl<K: Eq + Hash, V > {
11    pub cache: HashMap<K, (V, u128)>,
12    pub expiration_set: BTreeMap<u128,Vec<K>>,
13    pub max_size: i32,
14    pub current_size: i32,
15}
16
17pub struct ThreadSafeCache<K: Eq + Hash + serde::de::DeserializeOwned, V: serde::de::DeserializeOwned> {
18    pub implementation: Arc<Mutex<ThreadSafeCacheImpl<K, V>>>,
19}
20
21impl <K: std::marker::Send  + 'static + Clone +  Eq + Hash + serde::Serialize + serde::de::DeserializeOwned,
22    V: std::marker::Send  + Clone + serde::Serialize + serde::de::DeserializeOwned +'static> ThreadSafeCachePersistTrait<K, V> for ThreadSafeCache<K, V> {
23
24     fn save(&mut self, file_name: &str) {
25        let cloned = {
26            let md = self.implementation.lock().unwrap();
27            md.cache.clone()
28        };
29        let encoded: Vec<u8> = bincode::serialize(&cloned).unwrap();
30        let mut file = File::create(file_name).unwrap();
31        file.write_all(&encoded).unwrap();
32
33    }
34
35     fn load(&mut self, file_name: &str) {
36        let buf: HashMap<K, (V, u128)>;
37        let mut file = File::open(file_name).unwrap();
38        let mut encoded: Vec<u8> = Vec::new();
39        file.read_to_end(&mut encoded).unwrap();
40        buf = bincode::deserialize(&encoded[..]).unwrap();
41        let mut md = self.implementation.lock().unwrap();
42        md.cache = buf;
43        md.current_size = md.cache.len() as i32;
44    }
45
46}
47
48impl <K: std::marker::Send  + 'static + Clone +  Eq + Hash + serde::Serialize + serde::de::DeserializeOwned,
49    V: std::marker::Send  + Clone + serde::Serialize + serde::de::DeserializeOwned +'static>ThreadSafeCacheTrait<K, V> for ThreadSafeCache<K, V> {
50    fn put(&mut self, key: K, val: V)
51        where K: Eq + Hash,
52    {
53        let mut md = self.implementation.lock().unwrap();
54
55        if md.current_size == md.max_size {
56            let last_opt = md.expiration_set.pop_first();
57            if let Some((_, last)) = last_opt {
58                for key in last {
59                    md.cache.remove(&key);
60                    md.current_size = md.current_size - 1;
61                }
62            }
63        }
64        if !md.cache.contains_key(&key) {
65            md.current_size = md.current_size + 1;
66        }
67
68        let now = std::time::SystemTime::now();
69        let year:u128 = 1000 * 60 * 60 * 24 * 365;
70        let milliseconds_from_now  = now.duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() + year;
71        md.cache.insert(key.clone(), (val, milliseconds_from_now));
72        md.expiration_set.entry(milliseconds_from_now)
73            .and_modify(|curr| curr.push(key.clone())).or_insert({
74            let mut ret = Vec::new();
75            ret.push(key);
76            ret
77        });
78
79    }
80    fn put_exp(&mut self, key: K, val: V, expiration: i32)
81        where K: Eq + Hash + Clone,
82    {
83        let mut md = self.implementation.lock().unwrap();
84        if md.current_size == md.max_size {
85            let last_opt = md.expiration_set.pop_first();
86            if let Some((_, last)) = last_opt {
87                for key in last {
88                    md.cache.remove(&key);
89                    md.current_size = md.current_size - 1;
90                }
91            }
92        }
93
94        if !md.cache.contains_key(&key) {
95            md.current_size = md.current_size + 1;
96        }
97        let now = std::time::SystemTime::now();
98        let milliseconds_from_now  = now.duration_since(std::time::UNIX_EPOCH).unwrap().as_millis()  + expiration as u128;
99        md.cache.insert(key.clone(), (val, milliseconds_from_now));
100        md.expiration_set.entry(milliseconds_from_now)
101            .and_modify(|curr| curr.push(key.clone())).or_insert({
102            let mut ret = Vec::new();
103            ret.push(key);
104            ret
105        });
106    }
107    fn get(&mut self, key: K) -> Option<V>
108        where K: Eq + Hash, V: Clone
109    {
110        let md = self.implementation.lock().unwrap();
111        let ret = md.cache.get(&key).map(|s| s.clone());
112        if ret.is_some() {
113            let (val, expiration) = ret.unwrap();
114            if expiration > 0 {
115                let now = std::time::SystemTime::now();
116                let milliseconds_now  = now.duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() as u128;
117                // println!("{} {}", milliseconds_now, expiration);
118                if milliseconds_now > expiration {
119                    return None;
120                }
121            }
122            return Some(val);
123        } else {
124            return None;
125        }
126    }
127    fn exists(&mut self, key: K) -> bool
128        where K: Eq + Hash, V: Clone
129    {
130        let md = self.implementation.lock().unwrap();
131        let ret = md.cache.contains_key(&key);
132        ret
133    }
134    fn rm(&mut self, key: K)
135        where K: Eq + Hash,
136    {
137        let mut md = self.implementation.lock().unwrap();
138        let r = md.cache.remove(&key);
139        if r.is_some() {
140            md.current_size = md.current_size - 1;
141        }
142    }
143
144
145
146}
147
148impl <K: std::marker::Send  + 'static + Clone +  Eq + Hash + serde::Serialize + serde::de::DeserializeOwned,
149    V: std::marker::Send  + Clone + serde::Serialize + serde::de::DeserializeOwned +'static>ThreadSafeCache<K, V> {
150    pub fn clean(&mut self) -> bool
151    {
152        // println!("cleaning");
153        let mut md = self.implementation.lock().unwrap();
154
155        let now = std::time::SystemTime::now();
156        let milliseconds_now  = now.duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() as u128;
157        let new_expiration_set = md.expiration_set.split_off(&milliseconds_now);
158        let keys: Vec<K> = md.expiration_set.iter().map(|(_, keys)| {
159            keys.clone()
160        }).flatten().collect();
161        // println!("Keys len : {}", keys.len());
162        for key in keys {
163            let r = md.cache.remove(&key);
164            if r.is_some() {
165                md.current_size = md.current_size - 1;
166            }
167        }
168
169        md.expiration_set = new_expiration_set;
170        // println!("expiration_set len : {}", md.expiration_set.len());
171
172        let count = Arc::strong_count(&self.implementation);
173        if count == 0 {
174            false
175        } else {
176            true
177        }
178    }
179
180
181}
182
183impl<K: Eq + Hash + serde::de::DeserializeOwned + serde::Serialize, V: serde::de::DeserializeOwned + serde::Serialize> Clone for ThreadSafeCache<K, V> {
184    fn clone(&self) -> ThreadSafeCache<K, V> {
185        ThreadSafeCache {
186            implementation: Arc::clone(&self.implementation),
187        }
188    }
189}