use crate::event_store::event::MemoryEvent;
use crate::event_store::EventStore;
use std::sync::Arc;
pub struct TimelineReplay {
position: usize,
events: Vec<MemoryEvent>,
}
impl TimelineReplay {
pub fn new(event_store: Arc<EventStore>) -> Self {
let events = event_store.snapshot();
let mut sorted_events = events;
sorted_events.sort_by_key(|a| a.timestamp);
Self {
position: 0,
events: sorted_events,
}
}
pub fn reset(&mut self) {
self.position = 0;
}
pub fn advance_until(&mut self, timestamp: u64) -> Vec<MemoryEvent> {
let mut result = Vec::new();
for event in self.by_ref() {
if event.timestamp > timestamp {
break;
}
result.push(event);
}
result
}
pub fn get_events_between(&self, start: u64, end: u64) -> Vec<MemoryEvent> {
self.events
.iter()
.filter(|e| e.timestamp >= start && e.timestamp < end)
.cloned()
.collect()
}
pub fn len(&self) -> usize {
self.events.len()
}
pub fn is_empty(&self) -> bool {
self.events.is_empty()
}
pub fn position(&self) -> usize {
self.position
}
pub fn progress(&self) -> f64 {
if self.events.is_empty() {
0.0
} else {
self.position as f64 / self.events.len() as f64
}
}
}
impl Iterator for TimelineReplay {
type Item = MemoryEvent;
fn next(&mut self) -> Option<Self::Item> {
if self.position < self.events.len() {
let event = self.events[self.position].clone();
self.position += 1;
Some(event)
} else {
None
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_timeline_replay_creation() {
let event_store = Arc::new(EventStore::new());
let replay = TimelineReplay::new(event_store);
assert_eq!(replay.position(), 0);
assert!(replay.is_empty());
}
#[test]
fn test_timeline_replay_next() {
let event_store = Arc::new(EventStore::new());
let event = MemoryEvent::allocate(0x1000, 1024, 123);
event_store.record(event);
event_store.record(MemoryEvent::deallocate(0x1000, 1024, 456));
let mut replay = TimelineReplay::new(event_store);
assert_eq!(replay.len(), 2);
let first = replay.next();
assert!(first.is_some());
assert_eq!(first.unwrap().thread_id, 123);
let second = replay.next();
assert!(second.is_some());
assert_eq!(second.unwrap().thread_id, 456);
let third = replay.next();
assert!(third.is_none());
}
#[test]
fn test_timeline_replay_reset() {
let event_store = Arc::new(EventStore::new());
event_store.record(MemoryEvent::allocate(0x1000, 1024, 100));
event_store.record(MemoryEvent::allocate(0x2000, 2048, 200));
let mut replay = TimelineReplay::new(event_store);
assert_eq!(replay.position(), 0);
replay.next();
assert_eq!(replay.position(), 1);
replay.reset();
assert_eq!(replay.position(), 0);
}
#[test]
fn test_timeline_replay_progress_empty() {
let event_store = Arc::new(EventStore::new());
let replay = TimelineReplay::new(event_store);
assert_eq!(replay.progress(), 0.0);
}
#[test]
fn test_timeline_replay_progress() {
let event_store = Arc::new(EventStore::new());
event_store.record(MemoryEvent::allocate(0x1000, 1024, 100));
event_store.record(MemoryEvent::allocate(0x2000, 2048, 200));
let mut replay = TimelineReplay::new(event_store);
assert_eq!(replay.progress(), 0.0);
replay.next();
assert_eq!(replay.progress(), 0.5);
replay.next();
assert_eq!(replay.progress(), 1.0);
}
#[test]
fn test_timeline_replay_advance_until() {
let event_store = Arc::new(EventStore::new());
event_store.record(MemoryEvent::allocate(0x1000, 1024, 100));
event_store.record(MemoryEvent::allocate(0x2000, 2048, 200));
event_store.record(MemoryEvent::allocate(0x3000, 4096, 300));
let replay = TimelineReplay::new(event_store);
assert!(!replay.is_empty());
}
#[test]
fn test_timeline_replay_get_events_between() {
let event_store = Arc::new(EventStore::new());
event_store.record(MemoryEvent::allocate(0x1000, 1024, 100));
event_store.record(MemoryEvent::allocate(0x2000, 2048, 200));
event_store.record(MemoryEvent::allocate(0x3000, 4096, 300));
let replay = TimelineReplay::new(event_store);
let events = replay.get_events_between(0, u64::MAX);
assert!(!events.is_empty());
}
#[test]
fn test_timeline_replay_len() {
let event_store = Arc::new(EventStore::new());
assert_eq!(TimelineReplay::new(event_store.clone()).len(), 0);
event_store.record(MemoryEvent::allocate(0x1000, 1024, 100));
assert_eq!(TimelineReplay::new(event_store.clone()).len(), 1);
event_store.record(MemoryEvent::allocate(0x2000, 2048, 200));
assert_eq!(TimelineReplay::new(event_store).len(), 2);
}
#[test]
fn test_timeline_replay_iterator() {
let event_store = Arc::new(EventStore::new());
event_store.record(MemoryEvent::allocate(0x1000, 1024, 100));
event_store.record(MemoryEvent::allocate(0x2000, 2048, 200));
event_store.record(MemoryEvent::allocate(0x3000, 4096, 300));
let replay = TimelineReplay::new(event_store);
let events: Vec<_> = replay.collect();
assert_eq!(events.len(), 3);
}
#[test]
fn test_timeline_replay_sorted_order() {
let event_store = Arc::new(EventStore::new());
event_store.record(MemoryEvent::allocate(0x3000, 4096, 300));
event_store.record(MemoryEvent::allocate(0x1000, 1024, 100));
event_store.record(MemoryEvent::allocate(0x2000, 2048, 200));
let mut replay = TimelineReplay::new(event_store);
let mut count = 0;
while replay.next().is_some() {
count += 1;
}
assert_eq!(count, 3);
}
}