1use serde::{Deserialize, Serialize};
7use std::fmt;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
11pub enum MemoryEventType {
12 Allocate,
14 Deallocate,
16 Reallocate,
18 Move,
20 Borrow,
22 Return,
24}
25
26impl fmt::Display for MemoryEventType {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 match self {
29 MemoryEventType::Allocate => write!(f, "Allocate"),
30 MemoryEventType::Deallocate => write!(f, "Deallocate"),
31 MemoryEventType::Reallocate => write!(f, "Reallocate"),
32 MemoryEventType::Move => write!(f, "Move"),
33 MemoryEventType::Borrow => write!(f, "Borrow"),
34 MemoryEventType::Return => write!(f, "Return"),
35 }
36 }
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct MemoryEvent {
45 pub timestamp: u64,
47 pub event_type: MemoryEventType,
49 pub ptr: usize,
51 pub size: usize,
53 pub old_size: Option<usize>,
55 pub thread_id: u64,
57 pub var_name: Option<String>,
59 pub type_name: Option<String>,
61 pub call_stack_hash: Option<u64>,
63 pub thread_name: Option<String>,
65}
66
67impl MemoryEvent {
68 pub fn allocate(ptr: usize, size: usize, thread_id: u64) -> Self {
70 Self {
71 timestamp: Self::now(),
72 event_type: MemoryEventType::Allocate,
73 ptr,
74 size,
75 old_size: None,
76 thread_id,
77 var_name: None,
78 type_name: None,
79 call_stack_hash: None,
80 thread_name: None,
81 }
82 }
83
84 pub fn deallocate(ptr: usize, size: usize, thread_id: u64) -> Self {
86 Self {
87 timestamp: Self::now(),
88 event_type: MemoryEventType::Deallocate,
89 ptr,
90 size,
91 old_size: None,
92 thread_id,
93 var_name: None,
94 type_name: None,
95 call_stack_hash: None,
96 thread_name: None,
97 }
98 }
99
100 pub fn reallocate(ptr: usize, old_size: usize, new_size: usize, thread_id: u64) -> Self {
102 Self {
103 timestamp: Self::now(),
104 event_type: MemoryEventType::Reallocate,
105 ptr,
106 size: new_size,
107 old_size: Some(old_size),
108 thread_id,
109 var_name: None,
110 type_name: None,
111 call_stack_hash: None,
112 thread_name: None,
113 }
114 }
115
116 pub fn now() -> u64 {
119 use std::time::{SystemTime, UNIX_EPOCH};
120 SystemTime::now()
121 .duration_since(UNIX_EPOCH)
122 .map(|d| d.as_nanos() as u64)
123 .unwrap_or_default()
124 }
125
126 pub fn with_var_name(mut self, name: String) -> Self {
128 self.var_name = Some(name);
129 self
130 }
131
132 pub fn with_type_name(mut self, name: String) -> Self {
134 self.type_name = Some(name);
135 self
136 }
137
138 pub fn with_call_stack_hash(mut self, hash: u64) -> Self {
140 self.call_stack_hash = Some(hash);
141 self
142 }
143
144 pub fn with_thread_name(mut self, name: String) -> Self {
146 self.thread_name = Some(name);
147 self
148 }
149
150 pub fn is_allocation(&self) -> bool {
152 matches!(
153 self.event_type,
154 MemoryEventType::Allocate | MemoryEventType::Reallocate
155 )
156 }
157
158 pub fn is_deallocation(&self) -> bool {
160 matches!(self.event_type, MemoryEventType::Deallocate)
161 }
162
163 pub fn is_move(&self) -> bool {
165 matches!(self.event_type, MemoryEventType::Move)
166 }
167
168 pub fn is_borrow(&self) -> bool {
170 matches!(self.event_type, MemoryEventType::Borrow)
171 }
172
173 pub fn is_return(&self) -> bool {
175 matches!(self.event_type, MemoryEventType::Return)
176 }
177}