memscope_rs/capture/types/
timeline.rs1use serde::{Deserialize, Serialize};
7
8use super::scope::{AllocationEventType, ScopeEventType};
9use super::stats::TypeMemoryUsage;
10
11#[derive(Debug, Clone, Serialize)]
13pub struct TimelineData {
14 pub time_range: TimeRange,
16 pub allocation_events: Vec<AllocationEvent>,
18 pub scope_events: Vec<ScopeEvent>,
20 pub memory_snapshots: Vec<MemorySnapshot>,
22}
23
24#[derive(Debug, Clone, Serialize)]
26pub struct TimeRange {
27 pub start_time: u64,
29 pub end_time: u64,
31 pub duration_ms: u64,
33}
34
35#[derive(Debug, Clone, Serialize)]
37pub struct MemorySnapshot {
38 pub timestamp: u64,
40 pub total_memory: usize,
42 pub active_allocations: usize,
44 pub fragmentation_ratio: f64,
46 pub top_types: Vec<TypeMemoryUsage>,
48}
49
50#[derive(Debug, Clone, Serialize)]
52pub struct AllocationEvent {
53 pub timestamp: u64,
55 pub event_type: AllocationEventType,
57 pub ptr: usize,
59 pub size: usize,
61 pub var_name: Option<String>,
63 pub type_name: Option<String>,
65}
66
67#[derive(Debug, Clone, Serialize)]
69pub struct ScopeEvent {
70 pub timestamp: u64,
72 pub event_type: ScopeEventType,
74 pub scope_name: String,
76 pub memory_usage: usize,
78 pub variable_count: usize,
80}
81
82#[derive(Debug, Clone, Serialize)]
84pub struct StackTraceData {
85 pub hotspots: Vec<StackTraceHotspot>,
87 pub allocation_patterns: Vec<AllocationPattern>,
89 pub total_samples: usize,
91}
92
93#[derive(Debug, Clone, Serialize)]
95pub struct StackTraceHotspot {
96 pub function_name: String,
98 pub allocation_count: usize,
100 pub total_bytes: usize,
102 pub average_size: f64,
104 pub percentage: f64,
106}
107
108#[derive(Debug, Clone, Serialize)]
110pub struct AllocationPattern {
111 pub pattern_type: String,
113 pub frequency: usize,
115 pub total_bytes: usize,
117 pub description: String,
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct StackFrame {
124 pub function_name: String,
126 pub file_name: Option<String>,
128 pub line_number: Option<u32>,
130 pub module_path: Option<String>,
132}
133
134#[derive(Debug, Clone, Serialize)]
136pub enum SafetyViolation {
137 PotentialLeak {
139 ptr: usize,
141 size: usize,
143 age_ms: u64,
145 description: String,
147 },
148 UseAfterFree {
150 ptr: usize,
152 description: String,
154 },
155 DoubleFree {
157 ptr: usize,
159 description: String,
161 },
162 BufferOverflow {
164 ptr: usize,
166 size: usize,
168 description: String,
170 },
171}
172
173#[derive(Debug, Clone, Serialize)]
175pub struct AllocationHotspot {
176 pub location: HotspotLocation,
178 pub allocation_count: usize,
180 pub total_bytes: usize,
182 pub average_size: f64,
184 pub frequency: f64,
186}
187
188#[derive(Debug, Clone, Serialize)]
190pub struct HotspotLocation {
191 pub function_name: String,
193 pub file_path: Option<String>,
195 pub line_number: Option<u32>,
197 pub module_path: Option<String>,
199}
200
201#[cfg(test)]
202mod tests {
203 use super::*;
204
205 #[test]
206 fn test_timeline_data() {
207 let timeline = TimelineData {
208 time_range: TimeRange {
209 start_time: 0,
210 end_time: 1000,
211 duration_ms: 1000,
212 },
213 allocation_events: vec![],
214 scope_events: vec![],
215 memory_snapshots: vec![],
216 };
217
218 assert_eq!(timeline.time_range.duration_ms, 1000);
219 }
220
221 #[test]
222 fn test_memory_snapshot() {
223 let snapshot = MemorySnapshot {
224 timestamp: 100,
225 total_memory: 1024 * 1024,
226 active_allocations: 10,
227 fragmentation_ratio: 0.1,
228 top_types: vec![],
229 };
230
231 assert_eq!(snapshot.active_allocations, 10);
232 }
233
234 #[test]
235 fn test_safety_violation() {
236 let violation = SafetyViolation::PotentialLeak {
237 ptr: 0x1000,
238 size: 1024,
239 age_ms: 5000,
240 description: "test leak".to_string(),
241 };
242
243 assert!(matches!(violation, SafetyViolation::PotentialLeak { .. }));
244 }
245}