azoth_core/event_log.rs
1//! Event log trait and types
2//!
3//! Defines the interface for event storage backends (file-based, LMDB, etc.)
4
5use crate::error::Result;
6use crate::types::EventId;
7
8/// Iterator over events
9pub trait EventLogIterator: Iterator<Item = Result<(EventId, Vec<u8>)>> + Send {}
10
11impl<T: Iterator<Item = Result<(EventId, Vec<u8>)>> + Send> EventLogIterator for T {}
12
13/// Event log storage backend
14///
15/// Provides fast append-only event storage separate from the canonical KV store.
16/// This enables:
17/// - Higher write throughput (no ACID overhead)
18/// - Event rotation and archival
19/// - Multiple concurrent writers (with file locking)
20pub trait EventLog: Send + Sync {
21 /// Append an event with a pre-allocated EventId
22 ///
23 /// This should be fast - just append bytes to a file.
24 /// EventId must be provided by the caller (allocated from canonical store).
25 fn append_with_id(&self, event_id: EventId, event_bytes: &[u8]) -> Result<()>;
26
27 /// Append multiple events in a batch with pre-allocated EventIds
28 ///
29 /// The first event will have event_id = first_event_id,
30 /// subsequent events will have first_event_id + 1, first_event_id + 2, etc.
31 fn append_batch_with_ids(&self, first_event_id: EventId, events: &[Vec<u8>]) -> Result<()>;
32
33 /// Get the next EventId that will be assigned
34 fn next_event_id(&self) -> Result<EventId>;
35
36 /// Iterate over events in a range
37 ///
38 /// Returns events from `start` (inclusive) to `end` (exclusive).
39 /// If `end` is None, iterates to the latest event.
40 fn iter_range(&self, start: EventId, end: Option<EventId>)
41 -> Result<Box<dyn EventLogIterator>>;
42
43 /// Get a single event by ID
44 fn get(&self, event_id: EventId) -> Result<Option<Vec<u8>>>;
45
46 /// Delete events up to (and including) the given EventId
47 ///
48 /// Used after archival to free up space.
49 /// Returns the number of events deleted.
50 fn delete_range(&self, start: EventId, end: EventId) -> Result<usize>;
51
52 /// Rotate the current log file
53 ///
54 /// Closes the current file and starts a new one.
55 /// Returns the path to the rotated file.
56 fn rotate(&self) -> Result<std::path::PathBuf>;
57
58 /// Get the oldest event ID still in storage
59 fn oldest_event_id(&self) -> Result<EventId>;
60
61 /// Get the newest event ID in storage
62 fn newest_event_id(&self) -> Result<EventId>;
63
64 /// Sync all writes to disk
65 fn sync(&self) -> Result<()>;
66
67 /// Get statistics about the event log
68 fn stats(&self) -> Result<EventLogStats>;
69}
70
71/// Statistics about the event log
72#[derive(Debug, Clone)]
73pub struct EventLogStats {
74 /// Total number of events in storage
75 pub event_count: u64,
76
77 /// Oldest event ID still in storage
78 pub oldest_event_id: EventId,
79
80 /// Newest event ID in storage
81 pub newest_event_id: EventId,
82
83 /// Total bytes used by event storage
84 pub total_bytes: u64,
85
86 /// Number of active log files
87 pub file_count: usize,
88}