1use std::{
6 collections::{BTreeMap, Bound, HashMap},
7 sync::{Arc, RwLock},
8};
9
10use bincode::Options;
11use serde::de::DeserializeOwned;
12use typed_store_error::TypedStoreError;
13
14type InMemoryStoreInternal = Arc<RwLock<HashMap<String, BTreeMap<Vec<u8>, Vec<u8>>>>>;
15
16#[derive(Clone, Debug)]
17pub struct InMemoryDB {
18 data: InMemoryStoreInternal,
19}
20
21#[derive(Clone, Debug)]
22enum InMemoryChange {
23 Delete((String, Vec<u8>)),
24 Put((String, Vec<u8>, Vec<u8>)),
25}
26
27#[derive(Clone, Debug, Default)]
28pub struct InMemoryBatch {
29 data: Vec<InMemoryChange>,
30}
31
32impl InMemoryBatch {
33 pub fn delete_cf<K: AsRef<[u8]>>(&mut self, cf_name: &str, key: K) {
34 self.data.push(InMemoryChange::Delete((
35 cf_name.to_string(),
36 key.as_ref().to_vec(),
37 )));
38 }
39
40 pub fn put_cf<K, V>(&mut self, cf_name: &str, key: K, value: V)
41 where
42 K: AsRef<[u8]>,
43 V: AsRef<[u8]>,
44 {
45 self.data.push(InMemoryChange::Put((
46 cf_name.to_string(),
47 key.as_ref().to_vec(),
48 value.as_ref().to_vec(),
49 )));
50 }
51}
52
53impl InMemoryDB {
54 pub fn get<K: AsRef<[u8]>>(&self, cf_name: &str, key: K) -> Option<Vec<u8>> {
55 let data = self.data.read().expect("can't read data");
56 match data.get(cf_name) {
57 Some(cf) => cf.get(key.as_ref()).cloned(),
58 None => None,
59 }
60 }
61
62 pub fn multi_get<I, K>(&self, cf_name: &str, keys: I) -> Vec<Option<Vec<u8>>>
63 where
64 I: IntoIterator<Item = K>,
65 K: AsRef<[u8]>,
66 {
67 let data = self.data.read().expect("can't read data");
68 match data.get(cf_name) {
69 Some(cf) => keys
70 .into_iter()
71 .map(|k| cf.get(k.as_ref()).cloned())
72 .collect(),
73 None => vec![],
74 }
75 }
76
77 pub fn delete(&self, cf_name: &str, key: &[u8]) {
78 let mut data = self.data.write().expect("can't write data");
79 data.entry(cf_name.to_string()).or_default().remove(key);
80 }
81
82 pub fn put(&self, cf_name: &str, key: Vec<u8>, value: Vec<u8>) {
83 let mut data = self.data.write().expect("can't write data");
84 data.entry(cf_name.to_string())
85 .or_default()
86 .insert(key, value);
87 }
88
89 pub fn write(&self, batch: InMemoryBatch) {
90 for change in batch.data {
91 match change {
92 InMemoryChange::Delete((cf_name, key)) => self.delete(&cf_name, &key),
93 InMemoryChange::Put((cf_name, key, value)) => self.put(&cf_name, key, value),
94 }
95 }
96 }
97
98 pub fn has_cf(&self, name: &str) -> bool {
99 self.data
100 .read()
101 .expect("can't read data")
102 .contains_key(name)
103 }
104
105 pub fn drop_cf(&self, name: &str) {
106 self.data.write().expect("can't write data").remove(name);
107 }
108
109 pub fn iterator<K, V>(
110 &self,
111 cf_name: &str,
112 lower_bound: Option<Vec<u8>>,
113 upper_bound: Option<Vec<u8>>,
114 reverse: bool,
115 ) -> Box<dyn Iterator<Item = Result<(K, V), TypedStoreError>> + '_>
116 where
117 K: DeserializeOwned,
118 V: DeserializeOwned,
119 {
120 let config = bincode::DefaultOptions::new()
121 .with_big_endian()
122 .with_fixint_encoding();
123 let lower_bound = lower_bound.map(Bound::Included).unwrap_or(Bound::Unbounded);
124 let upper_bound = upper_bound.map(Bound::Excluded).unwrap_or(Bound::Unbounded);
125
126 let data = self.data.read().expect("can't read data");
127 let mut section: Vec<_> = data
128 .get(cf_name)
129 .unwrap_or(&BTreeMap::new())
130 .range((lower_bound, upper_bound))
131 .map(|(k, v)| (k.clone(), v.clone()))
132 .collect();
133 if reverse {
134 section.reverse();
135 }
136 Box::new(section.into_iter().map(move |(raw_key, raw_value)| {
137 let key = config
138 .deserialize(&raw_key)
139 .map_err(|e| TypedStoreError::Serialization(e.to_string()))?;
140 let value = bcs::from_bytes(&raw_value)
141 .map_err(|e| TypedStoreError::Serialization(e.to_string()))?;
142 Ok((key, value))
143 }))
144 }
145}