Skip to main content

luct_core/
store.rs

1use crate::tree::HashOutput;
2
3mod r#async;
4pub mod async_adapter;
5mod memory;
6
7pub use crate::store::r#async::{
8    AsyncAppendableStore, AsyncOrderedStore, AsyncOrderedStoreRead, AsyncSearchableStore,
9    AsyncSearchableStoreRead, AsyncStore, AsyncStoreRead, AsyncStoreWrite,
10};
11pub use crate::store::memory::MemoryStore;
12
13/// Trait indicating that an object can be hased with respect to the CT protocol
14///
15/// This for now always refers to the Sha256 algorithm, but this might change in the future
16pub trait Hashable {
17    /// Hash the object
18    fn hash(&self) -> HashOutput;
19}
20
21pub trait StoreBase {
22    type Key;
23    type Value;
24}
25
26pub trait StoreRead: StoreBase {
27    /// Returns the value associated with `key` from the [`Store`]
28    ///
29    /// # Arguments:
30    /// - `key`: the key indexing the object
31    ///
32    /// # Returns:
33    /// - `Some(value)`, if the value exists
34    /// - `None` otherwise
35    fn get(&self, key: &Self::Key) -> Option<Self::Value>;
36
37    /// Returns the number of elements in the [`Store`]
38    fn len(&self) -> usize;
39
40    /// Returns `true`, if the store is empty
41    fn is_empty(&self) -> bool {
42        self.len() == 0
43    }
44}
45
46pub trait StoreWrite: StoreBase {
47    /// Insert a value into the store
48    ///
49    /// # Arguments:
50    /// - `key`: the key associated with the value
51    /// - `value`: the value itself
52    fn insert(&self, key: Self::Key, value: Self::Value);
53
54    /// Remove a value from the store
55    ///
56    /// # Arguments
57    /// - `key`: the key to be removed
58    ///
59    /// # Returns
60    /// - `true` if the key existed and has been removed
61    /// - `false` otherwise
62    fn delete(&self, key: &Self::Key) -> bool;
63}
64
65/// The [`Store`] trait is a basic key-value store trait
66///
67/// Note that there is no ACID requirement in the trait.
68pub trait Store: StoreRead + StoreWrite {}
69impl<T> Store for T where T: StoreRead + StoreWrite {}
70
71/// Extension to regular [`Stores`](Store), which have ordered keys
72pub trait OrderedStoreRead: StoreRead<Key: Ord> {
73    /// Returns the last element in the store
74    ///
75    /// The last element is the largest element with respect to the keys [`Ord`] implementation.
76    ///
77    /// # Returns
78    /// - `Some(key, value)` if the store is non-empty
79    /// - `None` otherwise
80    fn last(&self) -> Option<(Self::Key, Self::Value)>;
81}
82
83pub trait OrderedStore: OrderedStoreRead + StoreWrite {}
84impl<T> OrderedStore for T where T: OrderedStoreRead + StoreWrite {}
85
86/// Extension to regular [`Stores`](Store), which use an index as a key
87///
88/// The main difference is, that the values can be inserted without providing a key.
89/// The key is then returned after insertion.
90///
91/// The key that was returned last must have be the largest value wrt [`Ord`].
92pub trait AppendableStore: OrderedStoreRead {
93    /// Insert a value into the store and return the index
94    ///
95    /// # Arguments:
96    /// - `value`: the value itself
97    ///
98    /// # Returns:
99    /// - the index of the new value. This is the key under which the value can later be retreived
100    fn append(&self, value: Self::Value) -> Self::Key;
101}
102
103/// Extension to a [`OrderedStoreRead`], that allows looking through the store to look for specific
104/// entries,
105pub trait SearchableStoreRead: OrderedStoreRead {
106    /// Search for all entries in the store, that fulfill a certain predicate
107    ///
108    /// Note that the elements are being searched through in the order specified by [`Ord`] of key
109    ///
110    /// # Arguments
111    /// - `pred`: A predicate that has access to the key and value
112    ///
113    /// # Returns
114    /// - An array of key-value pairs, for which `pred` holds true
115    fn filter(
116        &self,
117        pred: impl FnMut(&Self::Key, &Self::Value) -> bool,
118    ) -> Vec<(Self::Key, Self::Value)>;
119
120    fn find(
121        &self,
122        mut pred: impl FnMut(&Self::Key, &Self::Value) -> bool,
123    ) -> Option<(Self::Key, Self::Value)> {
124        let mut found = false;
125
126        let vals = self.filter(|key, value| {
127            if !found && pred(key, value) {
128                found = true;
129                true
130            } else {
131                false
132            }
133        });
134
135        if found {
136            assert_eq!(vals.len(), 1);
137            Some(vals.into_iter().next().unwrap())
138        } else {
139            None
140        }
141    }
142}
143
144pub trait SearchableStore: SearchableStoreRead + StoreWrite {}
145impl<T> SearchableStore for T where T: SearchableStoreRead + StoreWrite {}