Skip to main content

azoth_lmdb/
iter.rs

1use azoth_core::{
2    error::{AzothError, Result},
3    traits::EventIter,
4    types::EventId,
5};
6use lmdb::{Database, Environment, Transaction};
7use std::sync::Arc;
8
9use crate::keys::event_id_to_key;
10
11/// Iterator over events in LMDB
12///
13/// Note: This holds an Environment reference and creates read transactions on demand
14pub struct LmdbEventIter {
15    env: Arc<Environment>,
16    db: Database,
17    current: EventId,
18    to: Option<EventId>,
19}
20
21impl LmdbEventIter {
22    pub fn new(env: Arc<Environment>, db: Database, from: EventId, to: Option<EventId>) -> Self {
23        Self {
24            env,
25            db,
26            current: from,
27            to,
28        }
29    }
30}
31
32impl EventIter for LmdbEventIter {
33    fn next(&mut self) -> Result<Option<(EventId, Vec<u8>)>> {
34        // Check if we've exceeded the upper bound
35        if let Some(to) = self.to {
36            if self.current >= to {
37                return Ok(None);
38            }
39        }
40
41        // Create a read transaction for this operation
42        let txn = self
43            .env
44            .begin_ro_txn()
45            .map_err(|e| AzothError::Transaction(e.to_string()))?;
46
47        // Try to get the current event
48        let key = event_id_to_key(self.current);
49        match txn.get(self.db, &key) {
50            Ok(bytes) => {
51                let event_id = self.current;
52                self.current += 1;
53                Ok(Some((event_id, bytes.to_vec())))
54            }
55            Err(lmdb::Error::NotFound) => Ok(None),
56            Err(e) => Err(AzothError::Transaction(e.to_string())),
57        }
58    }
59}