thread_safe_cache/
embedded.rs1use 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 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 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 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 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}