1#[cfg(feature = "redb")]
2mod kv_redb;
3mod lexicographic;
4mod sort;
5
6#[cfg(test)]
7mod test;
8
9#[cfg(feature = "redb")]
10pub use kv_redb::*;
11pub use lexicographic::*;
12pub use sort::*;
13
14use std::ops::RangeBounds;
15
16use anyhow::Result;
17use serde::Deserialize;
18
19pub trait OpaqueItem {
21 fn key(&self) -> &[u8];
22 fn value(&self) -> &[u8];
23}
24
25pub trait KV: Sized + ReadOperations + WriteOperations {
27 type ReadTransaction: ReadOperations;
28 type WriteTransaction: WriteTx;
29
30 fn at_path(path: &std::path::Path) -> Result<Self>;
33 fn in_memory(bytes_maybe: Option<&[u8]>) -> Result<Self>;
36 fn write_tx(&self) -> Result<Self::WriteTransaction>;
37 fn read_tx(&self) -> Result<Self::ReadTransaction>;
38
39 fn scan<S>(&self, table: &str, predicate: S) -> Result<()>
42 where
43 S: Fn(&[u8], &[u8]) -> Result<bool>;
44}
45
46pub trait ReadOperations {
47 fn count(&self, table: &str) -> Result<u64>;
49 fn get(&self, table: &str, key: &[u8]) -> Result<Option<Vec<u8>>>;
51 fn range<'a>(
53 &'a self,
54 table: &str,
55 range: impl RangeBounds<&'a [u8]> + 'a,
56 ) -> Result<impl Iterator<Item = Result<impl OpaqueItem>> + 'a>;
57
58 fn count_multimap(&self, table: &str) -> Result<u64>;
60 fn get_multimap(
62 &self,
63 table: &str,
64 key: &[u8],
65 ) -> Result<impl Iterator<Item = Result<impl OpaqueItem>>>;
66
67 fn range_multimap<'a>(
68 &'a self,
69 table: &str,
70 range: impl RangeBounds<&'a [u8]> + 'a,
71 ) -> Result<impl Iterator<Item = Result<impl OpaqueItem>> + 'a>;
72
73 fn range_buffered<'a, T: for<'de> Deserialize<'de>>(
74 &'a self,
75 table: &str,
76 range: impl RangeBounds<&'a [u8]> + 'a,
77 selector: impl Fn(&[u8], &[u8], &mut dyn FnMut()) -> Result<Option<T>>,
78 ) -> Result<Vec<T>> {
79 let mut is_done = false;
80 let mut out = Vec::default();
81 for item in self.range(table, range)? {
82 let item = item?;
83 if let Some(item) = selector(item.key(), item.value(), &mut || {
84 is_done = true;
85 })? {
86 out.push(item);
87 }
88 if is_done {
89 break;
90 }
91 }
92 Ok(out)
93 }
94
95 fn range_buffered_multimap<'a, T: for<'de> Deserialize<'de>>(
96 &'a self,
97 table: &str,
98 range: impl RangeBounds<&'a [u8]> + 'a,
99 selector: impl Fn(&[u8], &[u8], &mut dyn FnMut()) -> Result<Option<T>>,
100 ) -> Result<Vec<T>> {
101 let mut is_done = false;
102 let mut out = Vec::default();
103 for item in self.range_multimap(table, range)? {
104 let item = item?;
105 if let Some(item) = selector(item.key(), item.value(), &mut || {
106 is_done = true;
107 })? {
108 out.push(item);
109 }
110 if is_done {
111 break;
112 }
113 }
114 Ok(out)
115 }
116}
117
118pub trait WriteOperations {
119 fn insert_multimap(&self, table: &str, key: &[u8], value: &[u8]) -> Result<()>;
121 fn remove_multimap(&self, table: &str, key: &[u8], value: &[u8]) -> Result<bool>;
124 fn remove_all_multimap(&self, table: &str, key: &[u8]) -> Result<()>;
126
127 fn insert(&self, table: &str, key: &[u8], value: &[u8]) -> Result<Option<Vec<u8>>>;
129 fn remove(&self, table: &str, key: &[u8]) -> Result<Option<Vec<u8>>>;
131 fn clear(&self, table: &str) -> Result<()>;
133 fn clear_multimap(&self, table: &str) -> Result<()>;
135}
136
137pub trait WriteTx: ReadOperations + WriteOperations {
138 fn commit(self) -> Result<()>;
139}
140
141#[cfg(test)]
142pub fn rand_utf8(len: usize) -> String {
143 vec![char::default(); len]
144 .into_iter()
145 .map(|_| rand::random::<char>())
146 .collect()
147}
148
149impl<T: KV> WriteOperations for T {
150 fn insert_multimap(&self, table: &str, key: &[u8], value: &[u8]) -> Result<()> {
151 let tx: <Self as KV>::WriteTransaction = self.write_tx()?;
152 tx.insert_multimap(table, key, value)?;
153 tx.commit()?;
154 Ok(())
155 }
156
157 fn remove_multimap(&self, table: &str, key: &[u8], value: &[u8]) -> Result<bool> {
158 let tx: <Self as KV>::WriteTransaction = self.write_tx()?;
159 let removed = tx.remove_multimap(table, key, value)?;
160 tx.commit()?;
161 Ok(removed)
162 }
163
164 fn remove_all_multimap(&self, table: &str, key: &[u8]) -> Result<()> {
165 let tx: <Self as KV>::WriteTransaction = self.write_tx()?;
166 tx.remove_all_multimap(table, key)?;
167 tx.commit()?;
168 Ok(())
169 }
170
171 fn insert(&self, table: &str, key: &[u8], value: &[u8]) -> Result<Option<Vec<u8>>> {
172 let tx: <Self as KV>::WriteTransaction = self.write_tx()?;
173 let existing_maybe = tx.insert(table, key, value)?;
174 tx.commit()?;
175 Ok(existing_maybe)
176 }
177
178 fn remove(&self, table: &str, key: &[u8]) -> Result<Option<Vec<u8>>> {
179 let tx: <Self as KV>::WriteTransaction = self.write_tx()?;
180 let removed = tx.remove(table, key)?;
181 tx.commit()?;
182 Ok(removed)
183 }
184
185 fn clear(&self, table: &str) -> Result<()> {
186 let tx: <Self as KV>::WriteTransaction = self.write_tx()?;
187 tx.clear(table)?;
188 tx.commit()?;
189 Ok(())
190 }
191
192 fn clear_multimap(&self, table: &str) -> Result<()> {
193 let tx: <Self as KV>::WriteTransaction = self.write_tx()?;
194 tx.clear_multimap(table)?;
195 tx.commit()?;
196 Ok(())
197 }
198}