sim_kernel/
event_ledger.rs1use std::collections::BTreeMap;
7
8use crate::{
9 error::{Error, Result},
10 event::{Event, EventKind, Tick, validate_ticks},
11 ref_id::Ref,
12};
13
14#[derive(Clone, Debug, Default)]
32pub struct EventLedger {
33 next_seq_by_run: BTreeMap<Ref, u64>,
34 events_by_run: BTreeMap<Ref, Vec<Event>>,
35}
36
37impl EventLedger {
38 pub fn new() -> Self {
40 Self::default()
41 }
42
43 pub fn len(&self) -> usize {
45 self.events_by_run.values().map(Vec::len).sum()
46 }
47
48 pub fn is_empty(&self) -> bool {
50 self.events_by_run.values().all(Vec::is_empty)
51 }
52
53 pub fn len_for_run(&self, run: &Ref) -> usize {
55 self.events_by_run.get(run).map_or(0, Vec::len)
56 }
57
58 pub fn events_for_run(&self, run: &Ref) -> &[Event] {
60 self.events_by_run.get(run).map_or(&[], Vec::as_slice)
61 }
62
63 pub fn iter(&self) -> impl Iterator<Item = &Event> {
65 self.events_by_run.values().flat_map(|events| events.iter())
66 }
67
68 pub fn push(&mut self, run: Ref, kind: EventKind) -> Result<Event> {
70 self.push_with_ticks(run, Vec::new(), kind)
71 }
72
73 pub fn push_with_ticks(
75 &mut self,
76 run: Ref,
77 ticks: Vec<Tick>,
78 kind: EventKind,
79 ) -> Result<Event> {
80 validate_ticks(&ticks)?;
81 let seq = self.allocate_seq(&run)?;
82 let event = Event::new(run.clone(), seq, ticks, kind)?;
83 self.events_by_run
84 .entry(run)
85 .or_default()
86 .push(event.clone());
87 Ok(event)
88 }
89
90 pub fn started(&mut self, run: Ref, request: Ref) -> Result<Event> {
92 self.push(run, EventKind::Started { request })
93 }
94
95 pub fn final_value(&mut self, run: Ref, value: Ref) -> Result<Event> {
97 self.push(run, EventKind::Final(value))
98 }
99
100 pub fn failed(&mut self, run: Ref, error: Ref) -> Result<Event> {
102 self.push(run, EventKind::Failed(error))
103 }
104
105 pub fn done(&mut self, run: Ref) -> Result<Event> {
107 self.push(run, EventKind::Done)
108 }
109
110 fn allocate_seq(&mut self, run: &Ref) -> Result<u64> {
111 let next = self.next_seq_by_run.entry(run.clone()).or_insert(0);
112 let seq = *next;
113 *next = (*next)
114 .checked_add(1)
115 .ok_or_else(|| Error::Eval("event sequence overflow".to_owned()))?;
116 Ok(seq)
117 }
118}