1use luct_core::store::{
2 AppendableStore, AsyncAppendableStore, AsyncOrderedStoreRead, AsyncSearchableStoreRead,
3 AsyncStoreRead, AsyncStoreWrite, OrderedStoreRead, SearchableStoreRead, StoreBase, StoreRead,
4 StoreWrite,
5};
6use std::{
7 cell::RefCell,
8 ops::{Deref, DerefMut},
9};
10
11pub struct LastValCacheStore<S>
15where
16 S: StoreBase,
17{
18 last: RefCell<Option<(S::Key, S::Value)>>,
19 inner: S,
20}
21
22impl<S> Deref for LastValCacheStore<S>
23where
24 S: StoreBase,
25{
26 type Target = S;
27
28 fn deref(&self) -> &Self::Target {
29 &self.inner
30 }
31}
32
33impl<S> DerefMut for LastValCacheStore<S>
34where
35 S: StoreBase,
36{
37 fn deref_mut(&mut self) -> &mut Self::Target {
38 &mut self.inner
39 }
40}
41
42impl<S> LastValCacheStore<S>
43where
44 S: StoreBase,
45{
46 pub fn new(store: S) -> Self {
47 Self {
48 last: RefCell::new(None),
49 inner: store,
50 }
51 }
52}
53
54impl<S> StoreBase for LastValCacheStore<S>
55where
56 S: StoreBase,
57{
58 type Key = S::Key;
59 type Value = S::Value;
60}
61
62impl<S> StoreRead for LastValCacheStore<S>
63where
64 S: StoreRead,
65{
66 fn get(&self, key: &Self::Key) -> Option<Self::Value> {
67 self.inner.get(key)
68 }
69
70 fn len(&self) -> usize {
71 self.inner.len()
72 }
73}
74
75impl<S> StoreWrite for LastValCacheStore<S>
76where
77 S: StoreWrite,
78{
79 fn insert(&self, key: Self::Key, value: Self::Value) {
80 *self.last.borrow_mut() = None;
81 self.inner.insert(key, value);
82 }
83
84 fn delete(&self, key: &Self::Key) -> bool {
85 *self.last.borrow_mut() = None;
86 self.inner.delete(key)
87 }
88}
89
90impl<S> OrderedStoreRead for LastValCacheStore<S>
91where
92 S: OrderedStoreRead<Key: Clone, Value: Clone>,
93{
94 fn last(&self) -> Option<(Self::Key, Self::Value)> {
95 let mut last_borrow = self.last.borrow_mut();
96 match last_borrow.as_ref() {
97 Some(last) => Some(last.clone()),
98 None => {
99 let last = self.inner.last();
100 *last_borrow = last.clone();
101 last
102 }
103 }
104 }
105}
106
107impl<S> AppendableStore for LastValCacheStore<S>
108where
109 S: AppendableStore<Key: Clone, Value: Clone>,
110{
111 fn append(&self, value: Self::Value) -> Self::Key {
112 *self.last.borrow_mut() = None;
113 self.inner.append(value)
114 }
115}
116
117impl<S> SearchableStoreRead for LastValCacheStore<S>
118where
119 S: SearchableStoreRead<Key: Clone, Value: Clone>,
120{
121 fn filter(
122 &self,
123 pred: impl FnMut(&Self::Key, &Self::Value) -> bool,
124 ) -> Vec<(Self::Key, Self::Value)> {
125 self.inner.filter(pred)
126 }
127
128 fn find(
129 &self,
130 pred: impl FnMut(&Self::Key, &Self::Value) -> bool,
131 ) -> Option<(Self::Key, Self::Value)> {
132 self.inner.find(pred)
133 }
134}
135
136impl<S> AsyncStoreRead for LastValCacheStore<S>
137where
138 S: AsyncStoreRead<Key: Clone>,
139{
140 async fn get(&self, key: Self::Key) -> Option<Self::Value> {
141 self.inner.get(key.clone()).await
142 }
143
144 async fn len(&self) -> usize {
145 self.inner.len().await
146 }
147}
148
149impl<S> AsyncStoreWrite for LastValCacheStore<S>
150where
151 S: AsyncStoreWrite<Key: Clone>,
152{
153 async fn insert(&self, key: Self::Key, value: Self::Value) {
154 *self.last.borrow_mut() = None;
155 self.inner.insert(key, value).await
156 }
157
158 async fn delete(&self, key: Self::Key) -> bool {
159 *self.last.borrow_mut() = None;
160 self.inner.delete(key).await
161 }
162}
163
164impl<S> AsyncOrderedStoreRead for LastValCacheStore<S>
165where
166 S: AsyncOrderedStoreRead<Key: Clone, Value: Clone>,
167{
168 async fn last(&self) -> Option<(Self::Key, Self::Value)> {
169 let last = self.last.borrow().clone();
170
171 if let Some(last) = last {
172 Some(last)
173 } else {
174 let new_last = self.inner.last().await;
175 *self.last.borrow_mut() = new_last.clone();
176 new_last
177 }
178 }
179}
180
181impl<S> AsyncAppendableStore for LastValCacheStore<S>
182where
183 S: AsyncAppendableStore<Key: Clone, Value: Clone>,
184{
185 async fn append(&self, value: Self::Value) -> Self::Key {
186 *self.last.borrow_mut() = None;
187 self.inner.append(value).await
188 }
189}
190
191impl<S> AsyncSearchableStoreRead for LastValCacheStore<S>
192where
193 S: AsyncSearchableStoreRead<Key: Clone, Value: Clone>,
194{
195 async fn filter(
196 &self,
197 pred: impl FnMut(&Self::Key, &Self::Value) -> bool,
198 ) -> Vec<(Self::Key, Self::Value)> {
199 self.inner.filter(pred).await
200 }
201
202 async fn find(
203 &self,
204 pred: impl FnMut(&Self::Key, &Self::Value) -> bool,
205 ) -> Option<(Self::Key, Self::Value)> {
206 self.inner.find(pred).await
207 }
208}
209
210#[cfg(test)]
211mod tests {
212 use super::*;
213 use luct_core::store::{MemoryStore, async_adapter::AsyncAdapter};
214 use luct_test::{
215 async_store::{async_ordered_store_test, async_searchable_store_test, async_store_test},
216 store::{ordered_store_test, searchable_store_test, store_test},
217 };
218
219 #[test]
220 fn last_val_store() {
221 let store = LastValCacheStore::new(MemoryStore::<u64, String>::default());
222 store_test(store);
223 }
224
225 #[test]
226 fn last_val_ordered_store() {
227 let store = LastValCacheStore::new(MemoryStore::<u64, String>::default());
228 ordered_store_test(store);
229 }
230
231 #[test]
232 fn last_val_searchable_store() {
233 let store = LastValCacheStore::new(MemoryStore::<u64, String>::default());
234 searchable_store_test(store);
235 }
236
237 #[tokio::test]
238 async fn async_last_val_store() {
239 let store =
240 AsyncAdapter::new(LastValCacheStore::new(MemoryStore::<u64, String>::default()));
241 async_store_test(store).await;
242 }
243
244 #[tokio::test]
245 async fn async_last_val_ordered_store() {
246 let store =
247 AsyncAdapter::new(LastValCacheStore::new(MemoryStore::<u64, String>::default()));
248 async_ordered_store_test(store).await;
249 }
250
251 #[tokio::test]
252 async fn async_last_val_searchable_store() {
253 let store =
254 AsyncAdapter::new(LastValCacheStore::new(MemoryStore::<u64, String>::default()));
255 async_searchable_store_test(store).await;
256 }
257}