Skip to main content

memscope_rs/capture/types/
lifecycle.rs

1//! Object lifecycle tracking types.
2//!
3//! This module contains types for tracking object lifecycles,
4//! including lifecycle events, patterns, and efficiency metrics.
5
6use serde::{Deserialize, Serialize};
7
8use super::generic::SourceLocation;
9
10/// Object lifecycle event tracking.
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12pub struct ObjectLifecycleInfo {
13    /// Object identifier.
14    pub object_id: usize,
15    /// Object type name.
16    pub type_name: String,
17    /// Lifecycle events.
18    pub lifecycle_events: Vec<LifecycleEvent>,
19    /// Total lifetime duration.
20    pub total_lifetime_ns: Option<u64>,
21    /// Lifecycle stage durations.
22    pub stage_durations: LifecycleStageDurations,
23    /// Lifecycle efficiency metrics.
24    pub efficiency_metrics: LifecycleEfficiencyMetrics,
25    /// Lifecycle patterns.
26    pub lifecycle_patterns: Vec<LifecyclePattern>,
27}
28
29/// Lifecycle event information.
30#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
31pub struct LifecycleEvent {
32    /// Event type.
33    pub event_type: LifecycleEventType,
34    /// Timestamp when event occurred.
35    pub timestamp: u64,
36    /// Location where event occurred.
37    pub location: SourceLocation,
38    /// Memory state at event time.
39    pub memory_state: MemoryState,
40    /// Performance metrics at event time.
41    pub performance_metrics: EventPerformanceMetrics,
42    /// Call stack at event time.
43    pub call_stack: Vec<String>,
44}
45
46/// Types of lifecycle events.
47#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
48pub enum LifecycleEventType {
49    /// Object creation.
50    Creation,
51    /// Object initialization.
52    Initialization,
53    /// Object first use.
54    FirstUse,
55    /// Object move.
56    Move,
57    /// Object copy.
58    Copy,
59    /// Object clone.
60    Clone,
61    /// Object borrow.
62    Borrow,
63    /// Object mutable borrow.
64    MutableBorrow,
65    /// Object borrow release.
66    BorrowRelease,
67    /// Object modification.
68    Modification,
69    /// Object last use.
70    LastUse,
71    /// Object drop.
72    Drop,
73    /// Object destruction.
74    Destruction,
75    /// Object memory reclaim.
76    MemoryReclaim,
77}
78
79/// Memory state at event time.
80#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
81pub struct MemoryState {
82    /// Memory location.
83    pub memory_location: MemoryLocationType,
84    /// Memory address.
85    pub memory_address: usize,
86    /// Object size.
87    pub object_size: usize,
88    /// Reference count (if applicable).
89    pub reference_count: Option<u32>,
90    /// Borrow state.
91    pub borrow_state: BorrowState,
92}
93
94/// Borrow state information.
95#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
96pub enum BorrowState {
97    /// Object is not borrowed.
98    NotBorrowed,
99    /// Object is shared borrowed.
100    SharedBorrow {
101        /// Number of shared borrows.
102        count: u32,
103    },
104    /// Object is mutably borrowed.
105    MutableBorrow,
106    /// Object has been moved out.
107    MovedOut,
108}
109
110/// Memory location type.
111#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
112pub enum MemoryLocationType {
113    /// Stack memory location.
114    Stack,
115    /// Heap memory location.
116    Heap,
117    /// Register memory location.
118    Register,
119    /// Static memory location.
120    Static,
121    /// Thread-local memory location.
122    ThreadLocal,
123}
124
125/// Performance metrics at event time.
126#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
127pub struct EventPerformanceMetrics {
128    /// CPU cycles consumed by event.
129    pub cpu_cycles: u64,
130    /// Memory bandwidth used.
131    pub memory_bandwidth_bytes: usize,
132    /// Cache misses caused by event.
133    pub cache_misses: u32,
134    /// Event processing time.
135    pub processing_time_ns: u64,
136}
137
138/// Lifecycle stage durations.
139#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
140pub struct LifecycleStageDurations {
141    /// Time from creation to first use.
142    pub creation_to_first_use_ns: Option<u64>,
143    /// Time spent in active use.
144    pub active_use_duration_ns: Option<u64>,
145    /// Time from last use to destruction.
146    pub last_use_to_destruction_ns: Option<u64>,
147    /// Time spent borrowed.
148    pub borrowed_duration_ns: u64,
149    /// Time spent idle.
150    pub idle_duration_ns: u64,
151}
152
153/// Lifecycle efficiency metrics.
154#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
155pub struct LifecycleEfficiencyMetrics {
156    /// Utilization ratio (active time / total time).
157    pub utilization_ratio: f64,
158    /// Memory efficiency (useful operations / memory usage).
159    pub memory_efficiency: f64,
160    /// Performance efficiency score.
161    pub performance_efficiency: f64,
162    /// Resource waste assessment.
163    pub resource_waste: ResourceWasteAssessment,
164}
165
166impl Default for LifecycleEfficiencyMetrics {
167    fn default() -> Self {
168        Self {
169            utilization_ratio: 0.0,
170            memory_efficiency: 0.0,
171            performance_efficiency: 0.0,
172            resource_waste: ResourceWasteAssessment {
173                wasted_memory_percent: 0.0,
174                wasted_cpu_percent: 0.0,
175                premature_destructions: 0,
176                unused_instances: 0,
177                optimization_opportunities: Vec::new(),
178            },
179        }
180    }
181}
182
183/// Resource waste assessment.
184#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
185pub struct ResourceWasteAssessment {
186    /// Wasted memory percentage.
187    pub wasted_memory_percent: f64,
188    /// Wasted CPU cycles percentage.
189    pub wasted_cpu_percent: f64,
190    /// Premature destruction events.
191    pub premature_destructions: u32,
192    /// Unused object instances.
193    pub unused_instances: u32,
194    /// Optimization opportunities.
195    pub optimization_opportunities: Vec<String>,
196}
197
198/// Lifecycle pattern information.
199#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
200pub struct LifecyclePattern {
201    /// Pattern type.
202    pub pattern_type: LifecyclePatternType,
203    /// Pattern frequency.
204    pub frequency: u32,
205    /// Pattern efficiency.
206    pub efficiency_score: f64,
207    /// Associated performance impact.
208    pub performance_impact: f64,
209    /// Optimization suggestions.
210    pub optimization_suggestions: Vec<String>,
211}
212
213/// Types of lifecycle patterns.
214#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
215pub enum LifecyclePatternType {
216    /// Short-lived objects.
217    ShortLived,
218    /// Long-lived objects.
219    LongLived,
220    /// Cyclical objects.
221    Cyclical,
222    /// On-demand objects.
223    OnDemand,
224    /// Cached objects.
225    Cached,
226    /// Pooled objects.
227    Pooled,
228    /// Singleton objects.
229    Singleton,
230    /// Factory objects.
231    Factory,
232    /// RAII objects.
233    RAII,
234}
235
236/// Simple lifecycle pattern classification.
237#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
238pub enum SimpleLifecyclePattern {
239    /// Very short-lived (0-1ms).
240    Instant,
241    /// Short-lived (2-100ms).
242    ShortLived,
243    /// Medium-lived (101ms-10s).
244    MediumLived,
245    /// Long-lived (10s-5min).
246    LongLived,
247    /// Persistent (>5min).
248    Persistent,
249}
250
251impl From<crate::core::types::ObjectLifecycleInfo> for ObjectLifecycleInfo {
252    fn from(old: crate::core::types::ObjectLifecycleInfo) -> Self {
253        Self {
254            object_id: old.object_id,
255            type_name: old.type_name,
256            lifecycle_events: old
257                .lifecycle_events
258                .into_iter()
259                .map(|e| LifecycleEvent {
260                    event_type: match e.event_type {
261                        crate::core::types::LifecycleEventType::Creation => {
262                            LifecycleEventType::Creation
263                        }
264                        crate::core::types::LifecycleEventType::Initialization => {
265                            LifecycleEventType::Initialization
266                        }
267                        crate::core::types::LifecycleEventType::FirstUse => {
268                            LifecycleEventType::FirstUse
269                        }
270                        crate::core::types::LifecycleEventType::Move => LifecycleEventType::Move,
271                        crate::core::types::LifecycleEventType::Copy => LifecycleEventType::Copy,
272                        crate::core::types::LifecycleEventType::Clone => LifecycleEventType::Clone,
273                        crate::core::types::LifecycleEventType::Borrow => {
274                            LifecycleEventType::Borrow
275                        }
276                        crate::core::types::LifecycleEventType::MutableBorrow => {
277                            LifecycleEventType::MutableBorrow
278                        }
279                        crate::core::types::LifecycleEventType::BorrowRelease => {
280                            LifecycleEventType::BorrowRelease
281                        }
282                        crate::core::types::LifecycleEventType::Modification => {
283                            LifecycleEventType::Modification
284                        }
285                        crate::core::types::LifecycleEventType::LastUse => {
286                            LifecycleEventType::LastUse
287                        }
288                        crate::core::types::LifecycleEventType::Drop => LifecycleEventType::Drop,
289                        crate::core::types::LifecycleEventType::Destruction => {
290                            LifecycleEventType::Destruction
291                        }
292                        crate::core::types::LifecycleEventType::MemoryReclaim => {
293                            LifecycleEventType::MemoryReclaim
294                        }
295                    },
296                    timestamp: e.timestamp,
297                    location: SourceLocation {
298                        file: e.location.file,
299                        line: e.location.line,
300                        column: e.location.column,
301                    },
302                    memory_state: MemoryState {
303                        memory_location: match e.memory_state.memory_location {
304                            crate::core::types::MemoryLocationType::Stack => {
305                                MemoryLocationType::Stack
306                            }
307                            crate::core::types::MemoryLocationType::Heap => {
308                                MemoryLocationType::Heap
309                            }
310                            crate::core::types::MemoryLocationType::Register => {
311                                MemoryLocationType::Register
312                            }
313                            crate::core::types::MemoryLocationType::Static => {
314                                MemoryLocationType::Static
315                            }
316                            crate::core::types::MemoryLocationType::ThreadLocal => {
317                                MemoryLocationType::ThreadLocal
318                            }
319                        },
320                        memory_address: e.memory_state.memory_address,
321                        object_size: e.memory_state.object_size,
322                        reference_count: e.memory_state.reference_count,
323                        borrow_state: match e.memory_state.borrow_state {
324                            crate::core::types::BorrowState::NotBorrowed => {
325                                BorrowState::NotBorrowed
326                            }
327                            crate::core::types::BorrowState::SharedBorrow { count } => {
328                                BorrowState::SharedBorrow { count }
329                            }
330                            crate::core::types::BorrowState::MutableBorrow => {
331                                BorrowState::MutableBorrow
332                            }
333                            crate::core::types::BorrowState::MovedOut => BorrowState::MovedOut,
334                        },
335                    },
336                    performance_metrics: EventPerformanceMetrics {
337                        cpu_cycles: e.performance_metrics.cpu_cycles,
338                        memory_bandwidth_bytes: e.performance_metrics.memory_bandwidth_bytes,
339                        cache_misses: e.performance_metrics.cache_misses,
340                        processing_time_ns: e.performance_metrics.processing_time_ns,
341                    },
342                    call_stack: e.call_stack,
343                })
344                .collect(),
345            total_lifetime_ns: old.total_lifetime_ns,
346            stage_durations: LifecycleStageDurations {
347                creation_to_first_use_ns: old.stage_durations.creation_to_first_use_ns,
348                active_use_duration_ns: old.stage_durations.active_use_duration_ns,
349                last_use_to_destruction_ns: old.stage_durations.last_use_to_destruction_ns,
350                borrowed_duration_ns: old.stage_durations.borrowed_duration_ns,
351                idle_duration_ns: old.stage_durations.idle_duration_ns,
352            },
353            efficiency_metrics: LifecycleEfficiencyMetrics {
354                utilization_ratio: old.efficiency_metrics.utilization_ratio,
355                memory_efficiency: old.efficiency_metrics.memory_efficiency,
356                performance_efficiency: old.efficiency_metrics.performance_efficiency,
357                resource_waste: ResourceWasteAssessment {
358                    wasted_memory_percent: old
359                        .efficiency_metrics
360                        .resource_waste
361                        .wasted_memory_percent,
362                    wasted_cpu_percent: old.efficiency_metrics.resource_waste.wasted_cpu_percent,
363                    premature_destructions: old
364                        .efficiency_metrics
365                        .resource_waste
366                        .premature_destructions,
367                    unused_instances: old.efficiency_metrics.resource_waste.unused_instances,
368                    optimization_opportunities: old
369                        .efficiency_metrics
370                        .resource_waste
371                        .optimization_opportunities,
372                },
373            },
374            lifecycle_patterns: old
375                .lifecycle_patterns
376                .into_iter()
377                .map(|p| LifecyclePattern {
378                    pattern_type: match p.pattern_type {
379                        crate::core::types::LifecyclePatternType::ShortLived => {
380                            LifecyclePatternType::ShortLived
381                        }
382                        crate::core::types::LifecyclePatternType::LongLived => {
383                            LifecyclePatternType::LongLived
384                        }
385                        crate::core::types::LifecyclePatternType::Cyclical => {
386                            LifecyclePatternType::Cyclical
387                        }
388                        crate::core::types::LifecyclePatternType::OnDemand => {
389                            LifecyclePatternType::OnDemand
390                        }
391                        crate::core::types::LifecyclePatternType::Cached => {
392                            LifecyclePatternType::Cached
393                        }
394                        crate::core::types::LifecyclePatternType::Pooled => {
395                            LifecyclePatternType::Pooled
396                        }
397                        crate::core::types::LifecyclePatternType::Singleton => {
398                            LifecyclePatternType::Singleton
399                        }
400                        crate::core::types::LifecyclePatternType::Factory => {
401                            LifecyclePatternType::Factory
402                        }
403                        crate::core::types::LifecyclePatternType::RAII => {
404                            LifecyclePatternType::RAII
405                        }
406                    },
407                    frequency: p.frequency,
408                    efficiency_score: p.efficiency_score,
409                    performance_impact: p.performance_impact,
410                    optimization_suggestions: p.optimization_suggestions,
411                })
412                .collect(),
413        }
414    }
415}
416
417#[cfg(test)]
418mod tests {
419    use super::*;
420
421    #[test]
422    fn test_object_lifecycle_info() {
423        let info = ObjectLifecycleInfo {
424            object_id: 1,
425            type_name: "String".to_string(),
426            lifecycle_events: vec![],
427            total_lifetime_ns: Some(1000000),
428            stage_durations: LifecycleStageDurations {
429                creation_to_first_use_ns: Some(100),
430                active_use_duration_ns: Some(900000),
431                last_use_to_destruction_ns: Some(99900),
432                borrowed_duration_ns: 100000,
433                idle_duration_ns: 50000,
434            },
435            efficiency_metrics: LifecycleEfficiencyMetrics::default(),
436            lifecycle_patterns: vec![],
437        };
438
439        assert_eq!(info.object_id, 1);
440        assert_eq!(info.type_name, "String");
441    }
442
443    #[test]
444    fn test_lifecycle_event_type() {
445        let events = vec![
446            LifecycleEventType::Creation,
447            LifecycleEventType::FirstUse,
448            LifecycleEventType::Drop,
449        ];
450
451        for event in events {
452            assert!(!format!("{event:?}").is_empty());
453        }
454    }
455}