Skip to main content

memscope_rs/capture/types/
stats.rs

1//! Memory statistics types.
2//!
3//! This module contains types for tracking memory usage statistics,
4//! including allocation counts, memory sizes, and fragmentation analysis.
5
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9use super::allocation::AllocationInfo;
10use super::scope::ScopeLifecycleMetrics;
11
12/// Memory statistics.
13///
14/// Comprehensive statistics about memory allocations, deallocations,
15/// leaks, and fragmentation.
16#[derive(Debug, Clone, Default, Serialize)]
17pub struct MemoryStats {
18    /// Total number of allocations made.
19    pub total_allocations: usize,
20    /// Total bytes allocated.
21    pub total_allocated: usize,
22    /// Number of currently active allocations.
23    pub active_allocations: usize,
24    /// Total bytes in active allocations.
25    pub active_memory: usize,
26    /// Peak number of concurrent allocations.
27    pub peak_allocations: usize,
28    /// Peak memory usage in bytes.
29    pub peak_memory: usize,
30    /// Total number of deallocations performed.
31    pub total_deallocations: usize,
32    /// Total bytes deallocated.
33    pub total_deallocated: usize,
34    /// Number of leaked allocations.
35    pub leaked_allocations: usize,
36    /// Total bytes in leaked allocations.
37    pub leaked_memory: usize,
38    /// Analysis of memory fragmentation.
39    pub fragmentation_analysis: FragmentationAnalysis,
40    /// Lifecycle statistics for scopes.
41    pub lifecycle_stats: ScopeLifecycleMetrics,
42    /// List of all allocation information.
43    pub allocations: Vec<AllocationInfo>,
44    /// Statistics for system library allocations.
45    pub system_library_stats: SystemLibraryStats,
46    /// Analysis of concurrent memory operations.
47    pub concurrency_analysis: ConcurrencyAnalysis,
48}
49
50impl MemoryStats {
51    /// Create a new empty MemoryStats.
52    pub fn new() -> Self {
53        Self {
54            total_allocations: 0,
55            total_allocated: 0,
56            active_allocations: 0,
57            active_memory: 0,
58            peak_allocations: 0,
59            peak_memory: 0,
60            total_deallocations: 0,
61            total_deallocated: 0,
62            leaked_allocations: 0,
63            leaked_memory: 0,
64            fragmentation_analysis: FragmentationAnalysis::default(),
65            lifecycle_stats: ScopeLifecycleMetrics::default(),
66            allocations: Vec::new(),
67            system_library_stats: SystemLibraryStats::default(),
68            concurrency_analysis: ConcurrencyAnalysis::default(),
69        }
70    }
71}
72
73impl From<crate::core::types::MemoryStats> for MemoryStats {
74    fn from(old: crate::core::types::MemoryStats) -> Self {
75        Self {
76            total_allocations: old.total_allocations,
77            total_allocated: old.total_allocated,
78            active_allocations: old.active_allocations,
79            active_memory: old.active_memory,
80            peak_allocations: old.peak_allocations,
81            peak_memory: old.peak_memory,
82            total_deallocations: old.total_deallocations,
83            total_deallocated: old.total_deallocated,
84            leaked_allocations: old.leaked_allocations,
85            leaked_memory: old.leaked_memory,
86            // Convert FragmentationAnalysis
87            fragmentation_analysis: FragmentationAnalysis {
88                fragmentation_ratio: old.fragmentation_analysis.fragmentation_ratio,
89                largest_free_block: old.fragmentation_analysis.largest_free_block,
90                smallest_free_block: old.fragmentation_analysis.smallest_free_block,
91                free_block_count: old.fragmentation_analysis.free_block_count,
92                total_free_memory: old.fragmentation_analysis.total_free_memory,
93                external_fragmentation: old.fragmentation_analysis.external_fragmentation,
94                internal_fragmentation: old.fragmentation_analysis.internal_fragmentation,
95            },
96            // Use default values for complex nested types to avoid unsafe conversions
97            lifecycle_stats: ScopeLifecycleMetrics::default(),
98            allocations: old.allocations.into_iter().map(|a| a.into()).collect(),
99            system_library_stats: SystemLibraryStats::default(),
100            concurrency_analysis: ConcurrencyAnalysis::default(),
101        }
102    }
103}
104
105/// Memory type analysis.
106#[derive(Debug, Clone, Serialize)]
107pub struct MemoryTypeInfo {
108    /// Name of the memory type.
109    pub type_name: String,
110    /// Total size in bytes for this type.
111    pub total_size: usize,
112    /// Number of allocations of this type.
113    pub allocation_count: usize,
114    /// Average size of allocations for this type.
115    pub average_size: usize,
116    /// Size of the largest allocation for this type.
117    pub largest_allocation: usize,
118    /// Size of the smallest allocation for this type.
119    pub smallest_allocation: usize,
120    /// Number of currently active instances.
121    pub active_instances: usize,
122    /// Number of leaked instances.
123    pub leaked_instances: usize,
124}
125
126/// Type memory usage information.
127#[derive(Debug, Clone, Serialize)]
128pub struct TypeMemoryUsage {
129    /// Name of the type.
130    pub type_name: String,
131    /// Total size allocated for this type.
132    pub total_size: usize,
133    /// Number of allocations for this type.
134    pub allocation_count: usize,
135    /// Average allocation size for this type.
136    pub average_size: f64,
137    /// Peak memory usage for this type.
138    pub peak_size: usize,
139    /// Current memory usage for this type.
140    pub current_size: usize,
141    /// Memory efficiency score for this type.
142    pub efficiency_score: f64,
143}
144
145/// Fragmentation analysis.
146#[derive(Debug, Clone, Default, Serialize, Deserialize)]
147pub struct FragmentationAnalysis {
148    /// Ratio of fragmented to total memory.
149    pub fragmentation_ratio: f64,
150    /// Size of the largest free memory block.
151    pub largest_free_block: usize,
152    /// Size of the smallest free memory block.
153    pub smallest_free_block: usize,
154    /// Total number of free memory blocks.
155    pub free_block_count: usize,
156    /// Total amount of free memory.
157    pub total_free_memory: usize,
158    /// External fragmentation percentage.
159    pub external_fragmentation: f64,
160    /// Internal fragmentation percentage.
161    pub internal_fragmentation: f64,
162}
163
164/// System library usage statistics.
165#[derive(Debug, Clone, Default, Serialize)]
166pub struct SystemLibraryStats {
167    /// Usage statistics for standard collections.
168    pub std_collections: LibraryUsage,
169    /// Usage statistics for async runtime.
170    pub async_runtime: LibraryUsage,
171    /// Usage statistics for network I/O.
172    pub network_io: LibraryUsage,
173    /// Usage statistics for file system operations.
174    pub file_system: LibraryUsage,
175    /// Usage statistics for serialization.
176    pub serialization: LibraryUsage,
177    /// Usage statistics for regex operations.
178    pub regex_engine: LibraryUsage,
179    /// Usage statistics for cryptographic operations.
180    pub crypto_security: LibraryUsage,
181    /// Usage statistics for database operations.
182    pub database: LibraryUsage,
183    /// Usage statistics for graphics and UI.
184    pub graphics_ui: LibraryUsage,
185    /// Usage statistics for HTTP operations.
186    pub http_stack: LibraryUsage,
187}
188
189/// Library usage information.
190#[derive(Debug, Clone, Default, Serialize)]
191pub struct LibraryUsage {
192    /// Number of allocations.
193    pub allocation_count: usize,
194    /// Total bytes allocated.
195    pub total_bytes: usize,
196    /// Peak memory usage in bytes.
197    pub peak_bytes: usize,
198    /// Average allocation size.
199    pub average_size: f64,
200    /// Categorized usage statistics.
201    pub categories: HashMap<String, usize>,
202    /// Functions with high allocation activity.
203    pub hotspot_functions: Vec<String>,
204}
205
206/// Concurrency safety analysis.
207#[derive(Debug, Clone, Default, Serialize)]
208pub struct ConcurrencyAnalysis {
209    /// Thread Safety Allocations.
210    pub thread_safety_allocations: usize,
211    /// Shared Memory Bytes.
212    pub shared_memory_bytes: usize,
213    /// Mutex Protected.
214    pub mutex_protected: usize,
215    /// Arc Shared.
216    pub arc_shared: usize,
217    /// Rc Shared.
218    pub rc_shared: usize,
219    /// Channel Buffers.
220    pub channel_buffers: usize,
221    /// Thread Local Storage.
222    pub thread_local_storage: usize,
223    /// Atomic Operations.
224    pub atomic_operations: usize,
225    /// Lock Contention Risk.
226    pub lock_contention_risk: String,
227}
228
229#[cfg(test)]
230mod tests {
231    use super::*;
232
233    #[test]
234    fn test_memory_stats_creation() {
235        let stats = MemoryStats::new();
236
237        assert_eq!(stats.total_allocations, 0);
238        assert_eq!(stats.total_allocated, 0);
239        assert_eq!(stats.active_allocations, 0);
240    }
241
242    #[test]
243    fn test_fragmentation_analysis_default() {
244        let frag = FragmentationAnalysis::default();
245
246        assert_eq!(frag.fragmentation_ratio, 0.0);
247        assert_eq!(frag.largest_free_block, 0);
248        assert_eq!(frag.free_block_count, 0);
249    }
250
251    #[test]
252    fn test_system_library_stats_default() {
253        let stats = SystemLibraryStats::default();
254
255        assert_eq!(stats.std_collections.allocation_count, 0);
256        assert_eq!(stats.async_runtime.total_bytes, 0);
257        assert_eq!(stats.network_io.peak_bytes, 0);
258    }
259
260    #[test]
261    fn test_library_usage_default() {
262        let usage = LibraryUsage::default();
263
264        assert_eq!(usage.allocation_count, 0);
265        assert_eq!(usage.total_bytes, 0);
266        assert_eq!(usage.average_size, 0.0);
267        assert!(usage.categories.is_empty());
268        assert!(usage.hotspot_functions.is_empty());
269    }
270
271    #[test]
272    fn test_concurrency_analysis_default() {
273        let analysis = ConcurrencyAnalysis::default();
274
275        assert_eq!(analysis.thread_safety_allocations, 0);
276        assert_eq!(analysis.shared_memory_bytes, 0);
277        assert_eq!(analysis.mutex_protected, 0);
278    }
279}