anondb_kv/
lib.rs

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
19/// A standard interface for accessing entries in the KV.
20pub trait OpaqueItem {
21    fn key(&self) -> &[u8];
22    fn value(&self) -> &[u8];
23}
24
25/// A generic key-value store. Assumed to be capable of transactional mutation of key-value collections.
26pub trait KV: Sized + ReadOperations + WriteOperations {
27    type ReadTransaction: ReadOperations;
28    type WriteTransaction: WriteTx;
29
30    /// Initialize a kv persisted to a path. What path is (directory, file, etc) is determined by
31    /// the underlying implementation.
32    fn at_path(path: &std::path::Path) -> Result<Self>;
33    /// Initialize a kv with a byte representation of the initial state. This byte
34    /// representation is arbitrary to the concrete implementation.
35    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    /// Iterate over the contents of a collection, in ascending lexicographic order. Must be
40    /// `O(N)`.
41    fn scan<S>(&self, table: &str, predicate: S) -> Result<()>
42    where
43        S: Fn(&[u8], &[u8]) -> Result<bool>;
44}
45
46pub trait ReadOperations {
47    /// Determine the number of keys present in a table.
48    fn count(&self, table: &str) -> Result<u64>;
49    /// Retrieve the value associated to a key for a table. Must be `O(1)`.
50    fn get(&self, table: &str, key: &[u8]) -> Result<Option<Vec<u8>>>;
51    /// Retrieve an iterator over a range of keys. Returns a reference to each key and value.
52    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    /// Determine the number of keys present in a multimap table.
59    fn count_multimap(&self, table: &str) -> Result<u64>;
60    /// Retrieve values associated with a key in a multimap table.
61    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    /// Insert a key for a multimap table. Must be `O(1)`.
120    fn insert_multimap(&self, table: &str, key: &[u8], value: &[u8]) -> Result<()>;
121    /// Remove a key and value from a multimap table. Returns `true` if the key/value pair was
122    /// present in the table. Must be `O(1)`.
123    fn remove_multimap(&self, table: &str, key: &[u8], value: &[u8]) -> Result<bool>;
124    /// Remove all values associated with a key in a multimap table. Must be `O(1)`.
125    fn remove_all_multimap(&self, table: &str, key: &[u8]) -> Result<()>;
126
127    /// Insert a key for a table and return the old value if it exists. Must be `O(1)`.
128    fn insert(&self, table: &str, key: &[u8], value: &[u8]) -> Result<Option<Vec<u8>>>;
129    /// Remove a key from a table. Must be `O(1)`.
130    fn remove(&self, table: &str, key: &[u8]) -> Result<Option<Vec<u8>>>;
131    /// Remove all entries in a table.
132    fn clear(&self, table: &str) -> Result<()>;
133    /// Remove all entries in a multimap table.
134    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}