1use std::{
2 hash::Hash,
3 sync::{Arc, Mutex, MutexGuard, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard},
4};
5
6use dashmap::DashMap;
7
8type SharedLockResult<'a, T, R> = Result<R, PoisonError<MutexGuard<'a, T>>>;
9type SharedRwReadResult<'a, T, R> = Result<R, PoisonError<RwLockReadGuard<'a, T>>>;
10type SharedRwWriteResult<'a, T, R> = Result<R, PoisonError<RwLockWriteGuard<'a, T>>>;
11
12#[derive(Debug)]
14pub struct SharedLock<T>(Arc<Mutex<T>>);
15
16impl<T> Clone for SharedLock<T> {
17 fn clone(&self) -> Self {
18 SharedLock(Arc::clone(&self.0))
19 }
20}
21
22impl<T> SharedLock<T> {
23 pub fn new(v: T) -> Self {
25 SharedLock(Arc::new(Mutex::new(v)))
26 }
27
28 pub fn with<F, R>(&self, f: F) -> SharedLockResult<'_, T, R>
33 where
34 F: FnOnce(&mut T) -> R,
35 {
36 let mut lock = self.0.lock()?;
37 Ok(f(&mut *lock))
38 }
39
40 pub fn get(&self) -> SharedLockResult<'_, T, T>
42 where
43 T: Clone,
44 {
45 self.with(|v| v.clone())
46 }
47
48 pub fn set(&self, value: T) -> SharedLockResult<'_, T, ()> {
50 self.with(|v| *v = value)?;
51 Ok(())
52 }
53}
54
55#[derive(Debug)]
57pub struct SharedRw<T>(Arc<RwLock<T>>);
58
59impl<T> Clone for SharedRw<T> {
60 fn clone(&self) -> Self {
61 SharedRw(Arc::clone(&self.0))
62 }
63}
64
65impl<T> SharedRw<T> {
66 pub fn new(v: T) -> Self {
68 SharedRw(Arc::new(RwLock::new(v)))
69 }
70
71 pub fn read<F, R>(&self, f: F) -> SharedRwReadResult<'_, T, R>
76 where
77 F: FnOnce(&T) -> R,
78 {
79 let guard = self.0.read()?;
80 Ok(f(&*guard))
81 }
82
83 pub fn write<F, R>(&self, f: F) -> SharedRwWriteResult<'_, T, R>
88 where
89 F: FnOnce(&mut T) -> R,
90 {
91 let mut guard = self.0.write()?;
92 Ok(f(&mut *guard))
93 }
94
95 pub fn get(&self) -> SharedRwReadResult<'_, T, T>
97 where
98 T: Clone,
99 {
100 self.read(|v| v.clone())
101 }
102
103 pub fn set(&self, value: T) -> SharedRwWriteResult<'_, T, ()> {
105 self.write(|v| *v = value)?;
106 Ok(())
107 }
108}
109
110pub struct SharedMap<K: Eq + Clone + Hash, V>(Arc<DashMap<K, V>>);
112
113impl<K: Eq + Clone + Hash, V> Clone for SharedMap<K, V> {
114 fn clone(&self) -> Self {
115 SharedMap(Arc::clone(&self.0))
116 }
117}
118
119impl<K: Eq + Hash + Clone, V> SharedMap<K, V> {
120 pub fn new() -> Self {
122 SharedMap(Arc::new(DashMap::new()))
123 }
124
125 pub fn with<F, R>(&self, key: &K, f: F) -> Option<R>
130 where
131 F: FnOnce(&V) -> R,
132 {
133 let guard = self.0.get(key)?;
134 let result = f(guard.value());
135 drop(guard);
136 Some(result)
137 }
138
139 pub fn with_mut<F, R>(&self, key: &K, f: F) -> Option<R>
144 where
145 F: FnOnce(&mut V) -> R,
146 {
147 let mut guard = self.0.get_mut(key)?;
148 let result = f(guard.value_mut());
149 Some(result)
150 }
151
152 pub fn for_each<F, Ret>(&self, mut f: F)
157 where
158 F: FnMut(K, &V) -> Ret,
159 {
160 for entry in self.0.iter() {
161 f(entry.key().clone(), entry.value());
162 }
163 }
164
165 pub fn for_each_mut<F, Ret>(&self, mut f: F)
170 where
171 F: FnMut(K, &mut V) -> Ret,
172 {
173 for mut entry in self.0.iter_mut() {
174 f(entry.key().clone(), entry.value_mut());
175 }
176 }
177
178 pub fn try_for_each_mut<F, E>(&self, mut f: F) -> Result<(), E>
183 where
184 F: FnMut(K, &mut V) -> Result<(), E>,
185 {
186 for mut entry in self.0.iter_mut() {
187 f(entry.key().clone(), entry.value_mut())?;
188 }
189 Ok(())
190 }
191
192 pub fn try_for_each<F, E>(&self, f: F) -> Result<(), E>
197 where
198 F: Fn(K, &V) -> Result<(), E>,
199 {
200 for entry in self.0.iter() {
201 f(entry.key().clone(), entry.value())?;
202 }
203 Ok(())
204 }
205
206 pub fn insert(&self, key: K, value: V) -> Option<V> {
208 self.0.insert(key, value)
209 }
210
211 pub fn remove(&self, key: &K) -> Option<(K, V)> {
213 self.0.remove(key)
214 }
215
216 pub fn contains_key(&self, key: &K) -> bool {
218 self.0.contains_key(key)
219 }
220
221 pub fn retain<F>(&self, f: F)
226 where
227 F: FnMut(&K, &mut V) -> bool,
228 {
229 self.0.retain(f);
230 }
231
232 pub fn keys(&self) -> Vec<K>
234 where
235 K: Clone,
236 {
237 self.0.iter().map(|e| e.key().clone()).collect()
238 }
239
240 pub fn len(&self) -> usize {
242 self.0.len()
243 }
244
245 pub fn is_empty(&self) -> bool {
247 self.0.is_empty()
248 }
249}
250
251impl<K: Eq + Hash + Clone, V> Default for SharedMap<K, V> {
252 fn default() -> Self {
253 Self::new()
254 }
255}
256
257#[cfg(test)]
258mod tests {
259 use super::*;
260
261 #[test]
262 fn shared_basic_usage() {
263 let v = SharedLock::new(10);
264
265 let _ = v.with(|x| *x += 5);
266 assert_eq!(v.get().unwrap(), 15);
267
268 let _ = v.set(42);
269 assert_eq!(v.get().unwrap(), 42);
270 }
271
272 #[test]
273 fn shared_rw_usage() {
274 let v = SharedRw::new(100);
275
276 let a = v.read(|x| *x).unwrap();
277 let b = v.read(|x| *x).unwrap();
278 assert_eq!(a, b);
279
280 let _ = v.write(|x| *x += 1);
281 assert_eq!(v.get().unwrap(), 101);
282 }
283
284 #[test]
285 fn shared_map_usage() {
286 let map = SharedMap::new();
287
288 map.insert("a", 1);
289 map.insert("b", 2);
290
291 let val = map.with(&"a", |v| *v).unwrap();
292 assert_eq!(val, 1);
293
294 map.with_mut(&"a", |v| *v += 10);
295 assert_eq!(map.with(&"a", |v| *v).unwrap(), 11);
296
297 let mut sum = 0;
298 map.for_each(|_, v| sum += v);
299 assert_eq!(sum, 13);
300
301 map.remove(&"a");
302 assert!(!map.contains_key(&"a"));
303 }
304}