1use super::{
10 BTreeMap, KeyValueBatch, KeyValueBatchOperation, KeyValueStore, Mutex, StorageBackendError,
11 StorageBackendResult,
12};
13
14#[derive(Debug, Default)]
17pub struct MemoryKeyValueStore {
18 inner: Mutex<MemoryKeyValueState>,
19}
20
21#[derive(Debug, Default, Clone)]
22struct MemoryKeyValueState {
23 map: BTreeMap<Vec<u8>, Vec<u8>>,
24 transactions: Vec<BTreeMap<Vec<u8>, Vec<u8>>>,
25 savepoints: Vec<MemorySavepoint>,
26 transaction_read_only: bool,
27 transaction_written: bool,
28 change_version: u64,
29}
30
31#[derive(Debug, Clone)]
32struct MemorySavepoint {
33 name: String,
34 snapshot: BTreeMap<Vec<u8>, Vec<u8>>,
35}
36
37impl MemoryKeyValueStore {
38 pub fn new() -> Self {
39 Self::default()
40 }
41}
42
43impl KeyValueStore for MemoryKeyValueStore {
44 fn visit_value(
45 &self,
46 key: &[u8],
47 control: &crate::read_control::StorageReadControl,
48 visit: &mut crate::read_control::ValueReadVisitor<'_>,
49 ) -> StorageBackendResult<()> {
50 control.check()?;
51 let state = self.inner.lock();
52 control.check()?;
53 visit(state.map.get(key).map(Vec::as_slice))?;
54 control.check()
55 }
56
57 fn visit_prefix_after(
58 &self,
59 prefix: &[u8],
60 after: Option<&[u8]>,
61 limit: usize,
62 control: &crate::read_control::StorageReadControl,
63 visit: &mut crate::read_control::KeyValueReadVisitor<'_>,
64 ) -> StorageBackendResult<()> {
65 use std::ops::Bound::{Excluded, Included, Unbounded};
66 control.check()?;
67 if limit == 0 {
68 return Ok(());
69 }
70 let state = self.inner.lock();
71 let lower = match after {
72 Some(after) if after >= prefix => Excluded(after),
73 _ => Included(prefix),
74 };
75 for (key, value) in state.map.range::<[u8], _>((lower, Unbounded)).take(limit) {
76 control.check()?;
77 if !key.starts_with(prefix) {
78 break;
79 }
80 visit(key, value)?;
81 }
82 control.check()
83 }
84
85 fn get(&self, key: &[u8]) -> StorageBackendResult<Option<Vec<u8>>> {
86 Ok(self.inner.lock().map.get(key).cloned())
87 }
88
89 fn contains_key(&self, key: &[u8]) -> StorageBackendResult<bool> {
90 Ok(self.inner.lock().map.contains_key(key))
91 }
92
93 fn put(&self, key: &[u8], value: &[u8]) -> StorageBackendResult<()> {
94 let mut inner = self.inner.lock();
95 prepare_write(&mut inner)?;
96 inner.map.insert(key.to_vec(), value.to_vec());
97 finish_autocommit_write(&mut inner);
98 Ok(())
99 }
100
101 fn delete(&self, key: &[u8]) -> StorageBackendResult<()> {
102 let mut inner = self.inner.lock();
103 prepare_write(&mut inner)?;
104 inner.map.remove(key);
105 finish_autocommit_write(&mut inner);
106 Ok(())
107 }
108
109 fn scan_prefix(&self, prefix: &[u8]) -> StorageBackendResult<Vec<(Vec<u8>, Vec<u8>)>> {
110 Ok(self
111 .inner
112 .lock()
113 .map
114 .range(prefix.to_vec()..)
115 .take_while(|(key, _)| key.starts_with(prefix))
116 .map(|(key, value)| (key.clone(), value.clone()))
117 .collect())
118 }
119
120 fn scan_prefix_after(
121 &self,
122 prefix: &[u8],
123 after: Option<&[u8]>,
124 limit: usize,
125 ) -> StorageBackendResult<Vec<(Vec<u8>, Vec<u8>)>> {
126 use std::ops::Bound::{Excluded, Included, Unbounded};
127
128 if limit == 0 {
129 return Ok(Vec::new());
130 }
131 let inner = self.inner.lock();
132 let lower = match after {
133 Some(after) if after >= prefix => Excluded(after.to_vec()),
134 Some(_) | None => Included(prefix.to_vec()),
135 };
136 Ok(inner
137 .map
138 .range((lower, Unbounded))
139 .take_while(|(key, _)| key.starts_with(prefix))
140 .take(limit)
141 .map(|(key, value)| (key.clone(), value.clone()))
142 .collect())
143 }
144
145 fn scan_prefix_keys_after(
146 &self,
147 prefix: &[u8],
148 after: Option<&[u8]>,
149 limit: usize,
150 ) -> StorageBackendResult<Vec<Vec<u8>>> {
151 use std::ops::Bound::{Excluded, Included, Unbounded};
152
153 if limit == 0 {
154 return Ok(Vec::new());
155 }
156 let inner = self.inner.lock();
157 let lower = match after {
158 Some(after) if after >= prefix => Excluded(after.to_vec()),
159 Some(_) | None => Included(prefix.to_vec()),
160 };
161 Ok(inner
162 .map
163 .range((lower, Unbounded))
164 .take_while(|(key, _)| key.starts_with(prefix))
165 .take(limit)
166 .map(|(key, _)| key.clone())
167 .collect())
168 }
169
170 fn first_prefix_after(
171 &self,
172 prefix: &[u8],
173 after: Option<&[u8]>,
174 ) -> StorageBackendResult<Option<(Vec<u8>, Vec<u8>)>> {
175 use std::ops::Bound::{Excluded, Included, Unbounded};
176
177 let inner = self.inner.lock();
178 let lower = match after {
179 Some(after) if after >= prefix => Excluded(after.to_vec()),
180 Some(_) | None => Included(prefix.to_vec()),
181 };
182 Ok(inner
183 .map
184 .range((lower, Unbounded))
185 .next()
186 .filter(|(key, _)| key.starts_with(prefix))
187 .map(|(key, value)| (key.clone(), value.clone())))
188 }
189
190 fn delete_prefix(&self, prefix: &[u8]) -> StorageBackendResult<usize> {
191 let mut inner = self.inner.lock();
192 prepare_write(&mut inner)?;
193 let keys = inner
194 .map
195 .range(prefix.to_vec()..)
196 .take_while(|(key, _)| key.starts_with(prefix))
197 .map(|(key, _)| key.clone())
198 .collect::<Vec<_>>();
199 for key in &keys {
200 inner.map.remove(key);
201 }
202 finish_autocommit_write(&mut inner);
203 Ok(keys.len())
204 }
205
206 fn batch(&self) -> Box<dyn KeyValueBatch + '_> {
207 Box::new(MemoryKeyValueBatch {
208 store: self,
209 operations: Vec::new(),
210 })
211 }
212
213 fn begin_transaction(&self) -> StorageBackendResult<()> {
214 let mut inner = self.inner.lock();
215 if !inner.transactions.is_empty() {
216 return Err(StorageBackendError::Other(
217 "a KeyValue transaction is already open".into(),
218 ));
219 }
220 let snapshot = inner.map.clone();
221 inner.transactions.push(snapshot);
222 inner.transaction_read_only = false;
223 inner.transaction_written = false;
224 Ok(())
225 }
226
227 fn begin_read_transaction(&self) -> StorageBackendResult<()> {
228 let mut inner = self.inner.lock();
229 if !inner.transactions.is_empty() {
230 return Err(StorageBackendError::Other(
231 "a KeyValue transaction is already open".into(),
232 ));
233 }
234 let snapshot = inner.map.clone();
235 inner.transactions.push(snapshot);
236 inner.transaction_read_only = true;
237 inner.transaction_written = false;
238 Ok(())
239 }
240
241 fn in_transaction(&self) -> bool {
242 !self.inner.lock().transactions.is_empty()
243 }
244
245 fn transaction_has_written(&self) -> StorageBackendResult<bool> {
246 Ok(self.inner.lock().transaction_written)
247 }
248
249 fn change_version(&self) -> StorageBackendResult<Option<u64>> {
250 Ok(Some(self.inner.lock().change_version))
251 }
252
253 fn commit_transaction(&self) -> StorageBackendResult<()> {
254 let mut inner = self.inner.lock();
255 inner.transactions.pop().ok_or_else(|| {
256 StorageBackendError::Other("no open KeyValue transaction to commit".into())
257 })?;
258 if inner.transaction_written {
259 inner.change_version = inner.change_version.wrapping_add(1);
260 }
261 inner.transaction_read_only = false;
262 inner.transaction_written = false;
263 inner.savepoints.clear();
264 Ok(())
265 }
266
267 fn rollback_transaction(&self) -> StorageBackendResult<()> {
268 let mut inner = self.inner.lock();
269 let snapshot = inner.transactions.pop().ok_or_else(|| {
270 StorageBackendError::Other("no open KeyValue transaction to roll back".into())
271 })?;
272 inner.map = snapshot;
273 inner.transaction_read_only = false;
274 inner.transaction_written = false;
275 inner.savepoints.clear();
276 Ok(())
277 }
278
279 fn savepoint(&self, name: &str) -> StorageBackendResult<()> {
280 let mut inner = self.inner.lock();
281 if inner.transactions.is_empty() {
282 return Err(StorageBackendError::Other(
283 "cannot create a savepoint outside a KeyValue transaction".into(),
284 ));
285 }
286 let snapshot = inner.map.clone();
287 inner.savepoints.push(MemorySavepoint {
288 name: name.to_string(),
289 snapshot,
290 });
291 Ok(())
292 }
293
294 fn release_savepoint(&self, name: &str) -> StorageBackendResult<()> {
295 let mut inner = self.inner.lock();
296 let position = inner
297 .savepoints
298 .iter()
299 .rposition(|savepoint| savepoint.name == name)
300 .ok_or_else(|| StorageBackendError::Other(format!("unknown savepoint `{name}`")))?;
301 inner.savepoints.truncate(position);
302 Ok(())
303 }
304
305 fn rollback_to_savepoint(&self, name: &str) -> StorageBackendResult<()> {
306 let mut inner = self.inner.lock();
307 let position = inner
308 .savepoints
309 .iter()
310 .rposition(|savepoint| savepoint.name == name)
311 .ok_or_else(|| StorageBackendError::Other(format!("unknown savepoint `{name}`")))?;
312 inner.map = inner.savepoints[position].snapshot.clone();
313 inner.savepoints.truncate(position + 1);
314 Ok(())
315 }
316}
317
318struct MemoryKeyValueBatch<'a> {
319 store: &'a MemoryKeyValueStore,
320 operations: Vec<KeyValueBatchOperation>,
321}
322
323impl KeyValueBatch for MemoryKeyValueBatch<'_> {
324 fn put(&mut self, key: &[u8], value: &[u8]) -> StorageBackendResult<()> {
325 self.operations
326 .push(KeyValueBatchOperation::Put(key.to_vec(), value.to_vec()));
327 Ok(())
328 }
329
330 fn delete(&mut self, key: &[u8]) -> StorageBackendResult<()> {
331 self.operations
332 .push(KeyValueBatchOperation::Delete(key.to_vec()));
333 Ok(())
334 }
335
336 fn delete_prefix(&mut self, prefix: &[u8]) -> StorageBackendResult<()> {
337 self.operations
338 .push(KeyValueBatchOperation::DeletePrefix(prefix.to_vec()));
339 Ok(())
340 }
341
342 fn commit(self: Box<Self>) -> StorageBackendResult<()> {
343 let mut inner = self.store.inner.lock();
344 prepare_write(&mut inner)?;
345 for operation in self.operations {
346 match operation {
347 KeyValueBatchOperation::Put(key, value) => {
348 inner.map.insert(key, value);
349 }
350 KeyValueBatchOperation::Delete(key) => {
351 inner.map.remove(&key);
352 }
353 KeyValueBatchOperation::DeletePrefix(prefix) => {
354 let keys = inner
355 .map
356 .range(prefix.clone()..)
357 .take_while(|(key, _)| key.starts_with(&prefix))
358 .map(|(key, _)| key.clone())
359 .collect::<Vec<_>>();
360 for key in keys {
361 inner.map.remove(&key);
362 }
363 }
364 }
365 }
366 finish_autocommit_write(&mut inner);
367 Ok(())
368 }
369}
370
371fn prepare_write(inner: &mut MemoryKeyValueState) -> StorageBackendResult<()> {
372 if !inner.transactions.is_empty() && inner.transaction_read_only {
373 return Err(StorageBackendError::Other(
374 "cannot write in a read-only KeyValue transaction".into(),
375 ));
376 }
377 if !inner.transactions.is_empty() {
378 inner.transaction_written = true;
379 }
380 Ok(())
381}
382
383fn finish_autocommit_write(inner: &mut MemoryKeyValueState) {
384 if inner.transactions.is_empty() {
385 inner.change_version = inner.change_version.wrapping_add(1);
386 }
387}