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}