Skip to main content

memscope_rs/capture/types/
fragmentation.rs

1//! Fragmentation analysis types.
2//!
3//! This module contains types for analyzing memory fragmentation,
4//! including block distribution, metrics, and cause analysis.
5
6use serde::{Deserialize, Serialize};
7
8use super::allocation::ImpactLevel;
9
10/// Enhanced memory fragmentation analysis.
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12pub struct EnhancedFragmentationAnalysis {
13    /// Total heap size.
14    pub total_heap_size: usize,
15    /// Used heap size.
16    pub used_heap_size: usize,
17    /// Free heap size.
18    pub free_heap_size: usize,
19    /// Number of free blocks.
20    pub free_block_count: usize,
21    /// Free block size distribution.
22    pub free_block_distribution: Vec<BlockSizeRange>,
23    /// Fragmentation metrics.
24    pub fragmentation_metrics: FragmentationMetrics,
25    /// Allocation patterns causing fragmentation.
26    pub fragmentation_causes: Vec<FragmentationCause>,
27}
28
29/// Block size range for distribution analysis.
30#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
31pub struct BlockSizeRange {
32    /// Minimum size in range.
33    pub min_size: usize,
34    /// Maximum size in range.
35    pub max_size: usize,
36    /// Number of blocks in this range.
37    pub block_count: usize,
38    /// Total size of blocks in this range.
39    pub total_size: usize,
40}
41
42/// Fragmentation metrics.
43#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
44pub struct FragmentationMetrics {
45    /// External fragmentation ratio.
46    pub external_fragmentation: f64,
47    /// Internal fragmentation ratio.
48    pub internal_fragmentation: f64,
49    /// Largest free block size.
50    pub largest_free_block: usize,
51    /// Average free block size.
52    pub average_free_block_size: f64,
53    /// Fragmentation severity level.
54    pub severity_level: FragmentationSeverity,
55}
56
57/// Fragmentation severity levels.
58#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
59pub enum FragmentationSeverity {
60    /// Low fragmentation severity.
61    Low,
62    /// Moderate fragmentation severity.
63    Moderate,
64    /// High fragmentation severity.
65    High,
66    /// Critical fragmentation severity.
67    Critical,
68}
69
70/// Fragmentation cause analysis.
71#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
72pub struct FragmentationCause {
73    /// Cause type.
74    pub cause_type: FragmentationCauseType,
75    /// Description of the cause.
76    pub description: String,
77    /// Impact on fragmentation.
78    pub impact_level: ImpactLevel,
79    /// Suggested mitigation.
80    pub mitigation_suggestion: String,
81}
82
83/// Types of fragmentation causes.
84#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
85pub enum FragmentationCauseType {
86    /// Mixed allocation sizes.
87    MixedAllocationSizes,
88    /// Frequent allocation/deallocation.
89    FrequentAllocDealloc,
90    /// Long-lived allocations blocking coalescing.
91    LongLivedAllocations,
92    /// Poor allocation strategy.
93    PoorAllocationStrategy,
94    /// Memory leaks.
95    MemoryLeaks,
96}
97
98// Implement From trait for converting from core::types to capture::types
99impl From<crate::core::types::EnhancedFragmentationAnalysis> for EnhancedFragmentationAnalysis {
100    fn from(old: crate::core::types::EnhancedFragmentationAnalysis) -> Self {
101        Self {
102            total_heap_size: old.total_heap_size,
103            used_heap_size: old.used_heap_size,
104            free_heap_size: old.free_heap_size,
105            free_block_count: old.free_block_count,
106            free_block_distribution: old
107                .free_block_distribution
108                .into_iter()
109                .map(|b| BlockSizeRange {
110                    min_size: b.min_size,
111                    max_size: b.max_size,
112                    block_count: b.block_count,
113                    total_size: b.total_size,
114                })
115                .collect(),
116            fragmentation_metrics: FragmentationMetrics {
117                external_fragmentation: old.fragmentation_metrics.external_fragmentation,
118                internal_fragmentation: old.fragmentation_metrics.internal_fragmentation,
119                largest_free_block: old.fragmentation_metrics.largest_free_block,
120                average_free_block_size: old.fragmentation_metrics.average_free_block_size,
121                severity_level: match old.fragmentation_metrics.severity_level {
122                    crate::core::types::FragmentationSeverity::Low => FragmentationSeverity::Low,
123                    crate::core::types::FragmentationSeverity::Moderate => {
124                        FragmentationSeverity::Moderate
125                    }
126                    crate::core::types::FragmentationSeverity::High => FragmentationSeverity::High,
127                    crate::core::types::FragmentationSeverity::Critical => {
128                        FragmentationSeverity::Critical
129                    }
130                },
131            },
132            fragmentation_causes: old
133                .fragmentation_causes
134                .into_iter()
135                .map(|c| FragmentationCause {
136                    cause_type: match c.cause_type {
137                        crate::core::types::FragmentationCauseType::MixedAllocationSizes => {
138                            FragmentationCauseType::MixedAllocationSizes
139                        }
140                        crate::core::types::FragmentationCauseType::FrequentAllocDealloc => {
141                            FragmentationCauseType::FrequentAllocDealloc
142                        }
143                        crate::core::types::FragmentationCauseType::LongLivedAllocations => {
144                            FragmentationCauseType::LongLivedAllocations
145                        }
146                        crate::core::types::FragmentationCauseType::PoorAllocationStrategy => {
147                            FragmentationCauseType::PoorAllocationStrategy
148                        }
149                        crate::core::types::FragmentationCauseType::MemoryLeaks => {
150                            FragmentationCauseType::MemoryLeaks
151                        }
152                    },
153                    description: c.description,
154                    impact_level: match c.impact_level {
155                        crate::core::types::ImpactLevel::Low => ImpactLevel::Low,
156                        crate::core::types::ImpactLevel::Medium => ImpactLevel::Medium,
157                        crate::core::types::ImpactLevel::High => ImpactLevel::High,
158                        crate::core::types::ImpactLevel::Critical => ImpactLevel::Critical,
159                    },
160                    mitigation_suggestion: c.mitigation_suggestion,
161                })
162                .collect(),
163        }
164    }
165}
166
167#[cfg(test)]
168mod tests {
169    use super::*;
170
171    #[test]
172    fn test_enhanced_fragmentation_analysis() {
173        let analysis = EnhancedFragmentationAnalysis {
174            total_heap_size: 1024 * 1024,
175            used_heap_size: 512 * 1024,
176            free_heap_size: 512 * 1024,
177            free_block_count: 10,
178            free_block_distribution: vec![],
179            fragmentation_metrics: FragmentationMetrics {
180                external_fragmentation: 0.3,
181                internal_fragmentation: 0.1,
182                largest_free_block: 256 * 1024,
183                average_free_block_size: 51200.0,
184                severity_level: FragmentationSeverity::Low,
185            },
186            fragmentation_causes: vec![],
187        };
188
189        assert_eq!(analysis.total_heap_size, 1024 * 1024);
190        assert_eq!(analysis.free_block_count, 10);
191    }
192
193    #[test]
194    fn test_fragmentation_severity() {
195        let severity = FragmentationSeverity::High;
196        assert!(matches!(severity, FragmentationSeverity::High));
197    }
198
199    #[test]
200    fn test_fragmentation_cause_type() {
201        let cause = FragmentationCauseType::MixedAllocationSizes;
202        assert!(matches!(
203            cause,
204            FragmentationCauseType::MixedAllocationSizes
205        ));
206    }
207}