Skip to main content

luct_core/
store.rs

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