guardian_db/stores/event_log_store/
index.rs1use crate::error::GuardianError;
2use crate::ipfs_log::{entry::Entry, log::Log};
3use crate::traits::StoreIndex;
4use parking_lot::RwLock;
5use std::sync::Arc;
6
7pub struct EventIndex {
13 entries_cache: Arc<RwLock<Vec<Entry>>>,
15}
16
17impl Default for EventIndex {
18 fn default() -> Self {
19 Self::new()
20 }
21}
22
23impl EventIndex {
24 pub fn new() -> Self {
26 EventIndex {
27 entries_cache: Arc::new(RwLock::new(Vec::new())),
28 }
29 }
30
31 pub fn len(&self) -> usize {
33 let cache = self.entries_cache.read();
34 cache.len()
35 }
36
37 pub fn is_empty(&self) -> bool {
39 let cache = self.entries_cache.read();
40 cache.is_empty()
41 }
42
43 pub fn get_all_entries(&self) -> Vec<Entry> {
45 let cache = self.entries_cache.read();
46 cache.clone()
47 }
48
49 pub fn get_entry_at(&self, index: usize) -> Option<Entry> {
51 let cache = self.entries_cache.read();
52 cache.get(index).cloned()
53 }
54
55 pub fn get_last_entries(&self, count: usize) -> Vec<Entry> {
57 let cache = self.entries_cache.read();
58 let start = cache.len().saturating_sub(count);
59 cache[start..].to_vec()
60 }
61}
62
63impl StoreIndex for EventIndex {
65 type Error = GuardianError;
66
67 fn contains_key(&self, key: &str) -> std::result::Result<bool, Self::Error> {
70 if let Ok(index) = key.parse::<usize>() {
71 let cache = self.entries_cache.read();
72 Ok(index < cache.len())
73 } else {
74 Ok(false)
75 }
76 }
77
78 fn get_bytes(&self, key: &str) -> std::result::Result<Option<Vec<u8>>, Self::Error> {
81 if let Ok(index) = key.parse::<usize>() {
82 let cache = self.entries_cache.read();
83 if let Some(entry) = cache.get(index) {
84 Ok(Some(entry.payload().as_bytes().to_vec()))
86 } else {
87 Ok(None)
88 }
89 } else {
90 Ok(None)
91 }
92 }
93
94 fn keys(&self) -> std::result::Result<Vec<String>, GuardianError> {
96 let cache = self.entries_cache.read();
97
98 let keys: Vec<String> = (0..cache.len()).map(|i| i.to_string()).collect();
100
101 Ok(keys)
102 }
103
104 fn len(&self) -> std::result::Result<usize, Self::Error> {
106 let cache = self.entries_cache.read();
107 Ok(cache.len())
108 }
109
110 fn is_empty(&self) -> std::result::Result<bool, Self::Error> {
112 let cache = self.entries_cache.read();
113 Ok(cache.is_empty())
114 }
115
116 fn update_index(
120 &mut self,
121 _log: &Log,
122 entries: &[Entry],
123 ) -> std::result::Result<(), Self::Error> {
124 {
126 let mut cache = self.entries_cache.write();
127 cache.clear();
128 cache.extend_from_slice(entries);
129 }
130
131 Ok(())
132 }
133
134 fn clear(&mut self) -> std::result::Result<(), Self::Error> {
136 let mut cache = self.entries_cache.write();
137 cache.clear();
138 Ok(())
139 }
140
141 fn get_entries_range(&self, start: usize, end: usize) -> Option<Vec<Entry>> {
148 let cache = self.entries_cache.read();
149
150 if start > end || start >= cache.len() {
152 return None;
153 }
154
155 let actual_end = end.min(cache.len());
156 Some(cache[start..actual_end].to_vec())
157 }
158
159 fn get_last_entries(&self, count: usize) -> Option<Vec<Entry>> {
163 let cache = self.entries_cache.read();
164
165 if cache.is_empty() || count == 0 {
166 return Some(Vec::new());
167 }
168
169 let start = cache.len().saturating_sub(count);
170 Some(cache[start..].to_vec())
171 }
172
173 fn get_entry_by_cid(&self, cid: &cid::Cid) -> Option<Entry> {
178 let cache = self.entries_cache.read();
179 let cid_str = cid.to_string();
180
181 cache.iter().find(|entry| entry.hash() == cid_str).cloned()
183 }
184
185 fn supports_entry_queries(&self) -> bool {
187 true
188 }
189}
190
191pub fn new_event_index(_params: &[u8]) -> Box<dyn StoreIndex<Error = GuardianError>> {
193 Box::new(EventIndex::new())
194}
195
196#[cfg(test)]
197mod tests {
198 use super::*;
199 use crate::ipfs_log::{
200 entry::Entry,
201 identity::{Identity, Signatures},
202 };
203 use std::sync::Arc;
204
205 fn create_test_identity() -> Arc<Identity> {
206 Arc::new(Identity::new(
208 "test_id",
209 "test_public_key",
210 Signatures::new("id_signature", "public_signature"),
211 ))
212 }
213
214 fn create_test_entry(payload: &str) -> Entry {
215 let identity = (*create_test_identity()).clone();
216
217 Entry::new(
219 identity,
220 "test_log", payload, &[], None, )
225 }
226
227 #[test]
228 fn test_event_index_creation() {
229 let index = EventIndex::new();
230 assert!(index.is_empty());
231 assert_eq!(index.len(), 0);
232 }
233
234 #[test]
235 fn test_event_index_basic_operations() {
236 let index = EventIndex::new();
237
238 assert!(index.is_empty());
240 assert_eq!(index.len(), 0);
241 assert!(index.get_all_entries().is_empty());
242 assert!(index.get_entry_at(0).is_none());
243 assert!(index.get_last_entries(5).is_empty());
244 }
245
246 #[test]
247 fn test_entries_cache_functionality() {
248 let index = EventIndex::new();
249
250 {
252 let mut cache = index.entries_cache.write();
253 cache.push(create_test_entry("test1"));
254 cache.push(create_test_entry("test2"));
255 cache.push(create_test_entry("test3"));
256 }
257
258 assert_eq!(index.len(), 3);
259 assert!(!index.is_empty());
260
261 let all_entries = index.get_all_entries();
262 assert_eq!(all_entries.len(), 3);
263
264 let entry_at_1 = index.get_entry_at(1);
265 assert!(entry_at_1.is_some());
266 assert_eq!(entry_at_1.unwrap().payload(), "test2");
267
268 let last_2 = index.get_last_entries(2);
269 assert_eq!(last_2.len(), 2);
270 assert_eq!(last_2[0].payload(), "test2");
271 assert_eq!(last_2[1].payload(), "test3");
272 }
273
274 #[test]
275 fn test_new_event_index_factory() {
276 let params = b"test_params";
277 let index_box = new_event_index(params);
278
279 assert!(index_box.is_empty().unwrap()); assert_eq!(index_box.len().unwrap(), 0); }
283
284 #[test]
285 fn test_store_index_trait_implementation() {
286 let mut index = EventIndex::new();
287
288 assert!(index.is_empty());
290 assert_eq!(index.len(), 0);
291 assert!(index.get_all_entries().is_empty());
292
293 assert!(
295 (&index as &dyn StoreIndex<Error = GuardianError>)
296 .is_empty()
297 .unwrap()
298 );
299 assert_eq!(
300 (&index as &dyn StoreIndex<Error = GuardianError>)
301 .len()
302 .unwrap(),
303 0
304 );
305 assert!(
306 (&index as &dyn StoreIndex<Error = GuardianError>)
307 .keys()
308 .unwrap()
309 .is_empty()
310 );
311 assert!(
312 !(&index as &dyn StoreIndex<Error = GuardianError>)
313 .contains_key("0")
314 .unwrap()
315 );
316 assert!(
317 (&index as &dyn StoreIndex<Error = GuardianError>)
318 .get_bytes("0")
319 .unwrap()
320 .is_none()
321 );
322
323 {
325 let mut cache = index.entries_cache.write();
326 cache.push(create_test_entry("test1"));
327 cache.push(create_test_entry("test2"));
328 }
329
330 let store_index = &index as &dyn StoreIndex<Error = GuardianError>;
332 assert!(!store_index.is_empty().unwrap());
333 assert_eq!(store_index.len().unwrap(), 2);
334 assert_eq!(store_index.keys().unwrap(), vec!["0", "1"]);
335 assert!(store_index.contains_key("0").unwrap());
336 assert!(store_index.contains_key("1").unwrap());
337 assert!(!store_index.contains_key("2").unwrap());
338
339 let bytes_0 = store_index.get_bytes("0").unwrap();
341 assert!(bytes_0.is_some());
342 assert_eq!(bytes_0.unwrap(), b"test1".to_vec());
343
344 let bytes_1 = store_index.get_bytes("1").unwrap();
345 assert!(bytes_1.is_some());
346 assert_eq!(bytes_1.unwrap(), b"test2".to_vec());
347
348 index.clear().unwrap();
350 assert!(index.is_empty());
351 assert_eq!(index.len(), 0);
352 }
353}