Skip to main content

luct_core/store/
memory.rs

1use crate::store::{
2    AppendableStore, AsyncStoreRead, AsyncStoreWrite, OrderedStoreRead, SearchableStoreRead,
3    StoreRead, StoreWrite,
4};
5use std::{
6    collections::BTreeMap,
7    sync::{Arc, RwLock},
8};
9
10/// A non-persistent implementation of [`Store`](crate::store::Store)
11///
12/// This can be useful for testing, or in settings, in which the data should not be stored,
13/// for example when running as a command line tool in CI
14#[derive(Debug, Clone)]
15pub struct MemoryStore<K, V>(Arc<RwLock<BTreeMap<K, V>>>);
16
17impl<K, V> Default for MemoryStore<K, V> {
18    fn default() -> Self {
19        Self(Arc::new(RwLock::new(BTreeMap::new())))
20    }
21}
22
23impl<K: Ord, V: Clone> StoreRead<K, V> for MemoryStore<K, V> {
24    fn get(&self, key: &K) -> Option<V> {
25        self.0.read().unwrap().get(key).cloned()
26    }
27
28    fn len(&self) -> usize {
29        self.0.read().unwrap().len()
30    }
31}
32
33impl<K: Ord, V> StoreWrite<K, V> for MemoryStore<K, V> {
34    fn insert(&self, key: K, value: V) {
35        self.0.write().unwrap().insert(key, value);
36    }
37
38    fn delete(&self, key: &K) -> bool {
39        self.0.write().unwrap().remove(key).is_some()
40    }
41}
42
43impl<K: Ord + Clone, V: Clone> OrderedStoreRead<K, V> for MemoryStore<K, V> {
44    fn last(&self) -> Option<(K, V)> {
45        self.0
46            .read()
47            .unwrap()
48            .iter()
49            .next_back()
50            .map(|(k, v)| (k.clone(), v.clone()))
51    }
52}
53
54impl<V: Clone> AppendableStore<u64, V> for MemoryStore<u64, V> {
55    fn append(&self, value: V) -> u64 {
56        let mut store = self.0.write().unwrap();
57
58        let len = store.len() as u64;
59        let old = store.insert(len, value);
60
61        assert!(
62            old.is_none(),
63            "IndexedStore already contained a value at {len}"
64        );
65
66        len
67    }
68}
69
70impl<K: Ord, V: Clone> AsyncStoreRead<K, V> for MemoryStore<K, V> {
71    async fn get(&self, key: K) -> Option<V> {
72        self.0.read().unwrap().get(&key).cloned()
73    }
74
75    async fn len(&self) -> usize {
76        self.0.read().unwrap().len()
77    }
78}
79
80impl<K: Ord, V: Clone> AsyncStoreWrite<K, V> for MemoryStore<K, V> {
81    async fn insert(&self, key: K, value: V) {
82        self.0.write().unwrap().insert(key, value);
83    }
84}
85
86impl<K: Ord + Clone, V: Clone> SearchableStoreRead<K, V> for MemoryStore<K, V> {
87    fn filter(&self, mut pred: impl FnMut(&K, &V) -> bool) -> Vec<(K, V)> {
88        self.0
89            .read()
90            .unwrap()
91            .iter()
92            .filter(|(key, val)| pred(key, val))
93            .map(|(key, val)| (key.clone(), val.clone()))
94            .collect()
95    }
96}