Skip to main content

devsper_graph/
event_log.rs

1use devsper_core::{GraphEvent, GraphSnapshot};
2
3/// Append-only log of all graph events.
4/// Snapshots every N events for efficient recovery without full replay.
5pub struct EventLog {
6    events: Vec<GraphEvent>,
7    snapshot_interval: u64,
8    last_snapshot: Option<GraphSnapshot>,
9    last_snapshot_at: u64,
10}
11
12impl EventLog {
13    pub fn new(snapshot_interval: u64) -> Self {
14        Self {
15            events: Vec::new(),
16            snapshot_interval,
17            last_snapshot: None,
18            last_snapshot_at: 0,
19        }
20    }
21
22    pub fn append(&mut self, event: GraphEvent) {
23        self.events.push(event);
24    }
25
26    pub fn events(&self) -> &[GraphEvent] {
27        &self.events
28    }
29
30    pub fn len(&self) -> usize {
31        self.events.len()
32    }
33
34    pub fn is_empty(&self) -> bool {
35        self.events.is_empty()
36    }
37
38    pub fn record_snapshot(&mut self, snapshot: GraphSnapshot) {
39        self.last_snapshot_at = self.events.len() as u64;
40        self.last_snapshot = Some(snapshot);
41    }
42
43    pub fn should_snapshot(&self) -> bool {
44        self.snapshot_interval > 0
45            && (self.events.len() as u64).saturating_sub(self.last_snapshot_at)
46                >= self.snapshot_interval
47    }
48
49    pub fn last_snapshot(&self) -> Option<&GraphSnapshot> {
50        self.last_snapshot.as_ref()
51    }
52
53    /// Events since last snapshot (for replay from snapshot)
54    pub fn events_since_snapshot(&self) -> &[GraphEvent] {
55        let start = self.last_snapshot_at as usize;
56        if start < self.events.len() {
57            &self.events[start..]
58        } else {
59            &[]
60        }
61    }
62}