Skip to main content

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}