memscope_rs/snapshot/
engine.rs1use crate::event_store::{MemoryEvent, SharedEventStore};
7use crate::snapshot::build_snapshot_from_events;
8use crate::snapshot::types::MemorySnapshot;
9
10pub struct SnapshotEngine {
20 event_store: SharedEventStore,
22}
23
24impl SnapshotEngine {
25 pub fn new(event_store: SharedEventStore) -> Self {
27 Self { event_store }
28 }
29
30 pub fn build_snapshot(&self) -> MemorySnapshot {
35 let events = self.event_store.snapshot();
36 build_snapshot_from_events(&events)
37 }
38
39 pub fn build_snapshot_from_events(&self, events: &[MemoryEvent]) -> MemorySnapshot {
54 build_snapshot_from_events(events)
55 }
56
57 pub fn event_store(&self) -> &SharedEventStore {
59 &self.event_store
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66 use crate::event_store::EventStore;
67 use std::sync::Arc;
68
69 #[test]
70 fn test_snapshot_engine_creation() {
71 let event_store = Arc::new(EventStore::new());
72 let engine = SnapshotEngine::new(event_store);
73 let snapshot = engine.build_snapshot();
74 assert_eq!(snapshot.active_count(), 0);
75 }
76
77 #[test]
78 fn test_snapshot_with_allocations() {
79 let event_store = Arc::new(EventStore::new());
80 event_store.record(MemoryEvent::allocate(0x1000, 1024, 1));
81 event_store.record(MemoryEvent::allocate(0x2000, 2048, 1));
82
83 let engine = SnapshotEngine::new(event_store);
84 let snapshot = engine.build_snapshot();
85
86 assert_eq!(snapshot.active_count(), 2);
87 assert_eq!(snapshot.current_memory(), 3072);
88 }
89
90 #[test]
91 fn test_snapshot_with_deallocations() {
92 let event_store = Arc::new(EventStore::new());
93 event_store.record(MemoryEvent::allocate(0x1000, 1024, 1));
94 event_store.record(MemoryEvent::deallocate(0x1000, 1024, 1));
95
96 let engine = SnapshotEngine::new(event_store);
97 let snapshot = engine.build_snapshot();
98
99 assert_eq!(snapshot.active_count(), 0);
100 assert_eq!(snapshot.current_memory(), 0);
101 assert_eq!(snapshot.stats.total_allocations, 1);
102 assert_eq!(snapshot.stats.total_deallocations, 1);
103 }
104
105 #[test]
106 fn test_snapshot_peak_memory() {
107 let event_store = Arc::new(EventStore::new());
108 event_store.record(MemoryEvent::allocate(0x1000, 1024, 1));
109 event_store.record(MemoryEvent::allocate(0x2000, 2048, 1));
110 event_store.record(MemoryEvent::deallocate(0x2000, 2048, 1));
111
112 let engine = SnapshotEngine::new(event_store);
113 let snapshot = engine.build_snapshot();
114
115 assert_eq!(snapshot.peak_memory(), 3072);
116 assert_eq!(snapshot.current_memory(), 1024);
117 }
118
119 #[test]
120 fn test_snapshot_thread_stats() {
121 let event_store = Arc::new(EventStore::new());
122 event_store.record(MemoryEvent::allocate(0x1000, 1024, 1));
123 event_store.record(MemoryEvent::allocate(0x2000, 2048, 2));
124
125 let engine = SnapshotEngine::new(event_store);
126 let snapshot = engine.build_snapshot();
127
128 assert_eq!(snapshot.thread_stats.len(), 2);
129
130 let thread1 = snapshot
131 .thread_stats
132 .get(&1)
133 .expect("Thread 1 stats should exist");
134 assert_eq!(thread1.allocation_count, 1);
135 assert_eq!(thread1.total_allocated, 1024);
136
137 let thread2 = snapshot
138 .thread_stats
139 .get(&2)
140 .expect("Thread 2 stats should exist");
141 assert_eq!(thread2.allocation_count, 1);
142 assert_eq!(thread2.total_allocated, 2048);
143 }
144
145 #[test]
146 fn test_deallocation_underflow_protection() {
147 let event_store = Arc::new(EventStore::new());
148 event_store.record(MemoryEvent::allocate(0x1000, 1024, 1));
149 event_store.record(MemoryEvent::deallocate(0x1000, 2048, 1));
150
151 let engine = SnapshotEngine::new(event_store);
152 let snapshot = engine.build_snapshot();
153
154 assert_eq!(snapshot.current_memory(), 0);
155 let thread1 = snapshot
156 .thread_stats
157 .get(&1)
158 .expect("Thread 1 stats should exist");
159 assert_eq!(thread1.current_memory, 0);
160 }
161
162 #[test]
163 fn test_build_snapshot_from_events_slice() {
164 let event_store = Arc::new(EventStore::new());
165 let engine = SnapshotEngine::new(event_store);
166
167 let events = vec![
168 MemoryEvent::allocate(0x1000, 1024, 1),
169 MemoryEvent::allocate(0x2000, 2048, 1),
170 ];
171
172 let snapshot = engine.build_snapshot_from_events(&events);
173
174 assert_eq!(events.len(), 2);
176 assert_eq!(snapshot.active_count(), 2);
177 }
178}