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