Skip to main content

luct_store/
last.rs

1use luct_core::store::{
2    AppendableStore, AsyncStoreRead, AsyncStoreWrite, OrderedStoreRead, SearchableStoreRead,
3    StoreBase, StoreRead, StoreWrite,
4};
5use std::{
6    cell::RefCell,
7    ops::{Deref, DerefMut},
8};
9
10/// A [`OrderedStore`](luct_core::store::OrderedStore) that caches the `last` value in memory
11///
12/// If you need to call [`OrderedStoreRead::last`], this will speed up access
13pub struct LastValCacheStore<S>
14where
15    S: StoreBase,
16{
17    last: RefCell<Option<(S::Key, S::Value)>>,
18    inner: S,
19}
20
21impl<S> Deref for LastValCacheStore<S>
22where
23    S: StoreBase,
24{
25    type Target = S;
26
27    fn deref(&self) -> &Self::Target {
28        &self.inner
29    }
30}
31
32impl<S> DerefMut for LastValCacheStore<S>
33where
34    S: StoreBase,
35{
36    fn deref_mut(&mut self) -> &mut Self::Target {
37        &mut self.inner
38    }
39}
40
41impl<S> LastValCacheStore<S>
42where
43    S: StoreBase,
44{
45    pub fn new(store: S) -> Self {
46        Self {
47            last: RefCell::new(None),
48            inner: store,
49        }
50    }
51}
52
53impl<S> StoreBase for LastValCacheStore<S>
54where
55    S: StoreBase,
56{
57    type Key = S::Key;
58    type Value = S::Value;
59}
60
61impl<S> StoreRead for LastValCacheStore<S>
62where
63    S: StoreRead,
64{
65    fn get(&self, key: &Self::Key) -> Option<Self::Value> {
66        self.inner.get(key)
67    }
68
69    fn len(&self) -> usize {
70        self.inner.len()
71    }
72}
73
74impl<S> StoreWrite for LastValCacheStore<S>
75where
76    S: StoreWrite,
77{
78    fn insert(&self, key: Self::Key, value: Self::Value) {
79        *self.last.borrow_mut() = None;
80        self.inner.insert(key, value);
81    }
82
83    fn delete(&self, key: &Self::Key) -> bool {
84        *self.last.borrow_mut() = None;
85        self.inner.delete(key)
86    }
87}
88
89impl<S> OrderedStoreRead for LastValCacheStore<S>
90where
91    S: OrderedStoreRead<Key: Clone, Value: Clone>,
92{
93    fn last(&self) -> Option<(Self::Key, Self::Value)> {
94        let mut last_borrow = self.last.borrow_mut();
95        match last_borrow.as_ref() {
96            Some(last) => Some(last.clone()),
97            None => {
98                let last = self.inner.last();
99                *last_borrow = last.clone();
100                last
101            }
102        }
103    }
104}
105
106impl<S> AppendableStore for LastValCacheStore<S>
107where
108    S: AppendableStore<Key: Clone, Value: Clone>,
109{
110    fn append(&self, value: Self::Value) -> Self::Key {
111        *self.last.borrow_mut() = None;
112        self.inner.append(value)
113    }
114}
115
116impl<S> SearchableStoreRead for LastValCacheStore<S>
117where
118    S: SearchableStoreRead<Key: Clone, Value: Clone>,
119{
120    fn filter(
121        &self,
122        pred: impl FnMut(&Self::Key, &Self::Value) -> bool,
123    ) -> Vec<(Self::Key, Self::Value)> {
124        self.inner.filter(pred)
125    }
126
127    fn find(
128        &self,
129        pred: impl FnMut(&Self::Key, &Self::Value) -> bool,
130    ) -> Option<(Self::Key, Self::Value)> {
131        self.inner.find(pred)
132    }
133}
134
135impl<S> AsyncStoreRead for LastValCacheStore<S>
136where
137    S: AsyncStoreRead<Key: Clone>,
138{
139    async fn get(&self, key: Self::Key) -> Option<Self::Value> {
140        self.inner.get(key.clone()).await
141    }
142
143    async fn len(&self) -> usize {
144        self.inner.len().await
145    }
146}
147
148impl<S> AsyncStoreWrite for LastValCacheStore<S>
149where
150    S: AsyncStoreWrite<Key: Clone>,
151{
152    async fn insert(&self, key: Self::Key, value: Self::Value) {
153        *self.last.borrow_mut() = None;
154        self.inner.insert(key, value).await
155    }
156}
157
158#[cfg(test)]
159mod tests {
160    use super::*;
161    use luct_core::store::MemoryStore;
162    use luct_test::store::{ordered_store_test, searchable_store_test, store_test};
163
164    #[test]
165    fn last_val_store() {
166        let store = LastValCacheStore::new(MemoryStore::<u64, String>::default());
167        store_test(store);
168    }
169
170    #[test]
171    fn last_val_ordered_store() {
172        let store = LastValCacheStore::new(MemoryStore::<u64, String>::default());
173        ordered_store_test(store);
174    }
175
176    #[test]
177    fn last_val_searchable_store() {
178        let store = LastValCacheStore::new(MemoryStore::<u64, String>::default());
179        searchable_store_test(store);
180    }
181}