Skip to main content

scirs2_sparse/adaptive_memory_compression/
config.rs

1//! Configuration for adaptive memory compression
2//!
3//! This module contains configuration structures and enums that control
4//! the behavior of the adaptive memory compression system.
5
6/// Configuration for adaptive memory compression
7#[derive(Debug, Clone)]
8pub struct AdaptiveCompressionConfig {
9    /// Maximum memory budget in bytes
10    pub memory_budget: usize,
11    /// Compression algorithm to use
12    pub compression_algorithm: CompressionAlgorithm,
13    /// Enable hierarchical compression
14    pub hierarchical_compression: bool,
15    /// Block size for compression
16    pub block_size: usize,
17    /// Compression threshold (compress when usage exceeds this ratio)
18    pub compression_threshold: f64,
19    /// Enable adaptive compression based on access patterns
20    pub adaptive_compression: bool,
21    /// Cache size for frequently accessed blocks
22    pub cache_size: usize,
23    /// Enable out-of-core processing
24    pub out_of_core: bool,
25    /// Temporary directory for out-of-core storage
26    pub temp_directory: String,
27    /// Enable memory mapping
28    pub memory_mapping: bool,
29}
30
31/// Compression algorithms for sparse matrix data
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
33pub enum CompressionAlgorithm {
34    /// No compression
35    None,
36    /// Run-Length Encoding
37    RLE,
38    /// Delta encoding for indices
39    Delta,
40    /// Huffman coding
41    Huffman,
42    /// LZ77 compression
43    LZ77,
44    /// Sparse-specific compression
45    SparseOptimized,
46    /// Hybrid adaptive compression
47    Adaptive,
48}
49
50impl Default for AdaptiveCompressionConfig {
51    fn default() -> Self {
52        // Use reasonable defaults for 32-bit platforms (wasm32)
53        #[cfg(target_pointer_width = "32")]
54        let default_memory_budget = 512 * 1024 * 1024; // 512MB for 32-bit
55        #[cfg(target_pointer_width = "64")]
56        let default_memory_budget = 8usize * 1024 * 1024 * 1024; // 8GB for 64-bit
57
58        #[cfg(target_pointer_width = "32")]
59        let default_cache_size = 64 * 1024 * 1024; // 64MB cache for 32-bit
60        #[cfg(target_pointer_width = "64")]
61        let default_cache_size = 256 * 1024 * 1024; // 256MB cache for 64-bit
62
63        Self {
64            memory_budget: default_memory_budget,
65            compression_algorithm: CompressionAlgorithm::Adaptive,
66            hierarchical_compression: true,
67            block_size: 1024 * 1024, // 1MB blocks
68            compression_threshold: 0.8,
69            adaptive_compression: true,
70            cache_size: default_cache_size,
71            out_of_core: true,
72            temp_directory: "/tmp/scirs2_sparse".to_string(),
73            memory_mapping: true,
74        }
75    }
76}
77
78impl AdaptiveCompressionConfig {
79    /// Create a new configuration with default values
80    pub fn new() -> Self {
81        Self::default()
82    }
83
84    /// Set memory budget
85    pub fn with_memory_budget(mut self, budget: usize) -> Self {
86        self.memory_budget = budget;
87        self
88    }
89
90    /// Set compression algorithm
91    pub fn with_compression_algorithm(mut self, algorithm: CompressionAlgorithm) -> Self {
92        self.compression_algorithm = algorithm;
93        self
94    }
95
96    /// Enable or disable hierarchical compression
97    pub fn with_hierarchical_compression(mut self, enabled: bool) -> Self {
98        self.hierarchical_compression = enabled;
99        self
100    }
101
102    /// Set block size for compression
103    pub fn with_block_size(mut self, size: usize) -> Self {
104        self.block_size = size;
105        self
106    }
107
108    /// Set compression threshold
109    pub fn with_compression_threshold(mut self, threshold: f64) -> Self {
110        self.compression_threshold = threshold;
111        self
112    }
113
114    /// Enable or disable adaptive compression
115    pub fn with_adaptive_compression(mut self, enabled: bool) -> Self {
116        self.adaptive_compression = enabled;
117        self
118    }
119
120    /// Set cache size
121    pub fn with_cache_size(mut self, size: usize) -> Self {
122        self.cache_size = size;
123        self
124    }
125
126    /// Enable or disable out-of-core processing
127    pub fn with_out_of_core(mut self, enabled: bool) -> Self {
128        self.out_of_core = enabled;
129        self
130    }
131
132    /// Set temporary directory for out-of-core storage
133    pub fn with_temp_directory(mut self, dir: impl Into<String>) -> Self {
134        self.temp_directory = dir.into();
135        self
136    }
137
138    /// Enable or disable memory mapping
139    pub fn with_memory_mapping(mut self, enabled: bool) -> Self {
140        self.memory_mapping = enabled;
141        self
142    }
143
144    /// Validate configuration parameters
145    pub fn validate(&self) -> Result<(), String> {
146        if self.memory_budget == 0 {
147            return Err("Memory budget must be greater than 0".to_string());
148        }
149
150        if self.block_size == 0 {
151            return Err("Block size must be greater than 0".to_string());
152        }
153
154        if self.compression_threshold < 0.0 || self.compression_threshold > 1.0 {
155            return Err("Compression threshold must be between 0.0 and 1.0".to_string());
156        }
157
158        if self.cache_size == 0 {
159            return Err("Cache size must be greater than 0".to_string());
160        }
161
162        if self.cache_size > self.memory_budget {
163            return Err("Cache size cannot exceed memory budget".to_string());
164        }
165
166        if self.temp_directory.is_empty() {
167            return Err("Temporary directory must be specified".to_string());
168        }
169
170        Ok(())
171    }
172
173    /// Create a lightweight configuration for testing
174    pub fn lightweight() -> Self {
175        Self {
176            memory_budget: 64 * 1024 * 1024, // 64MB
177            compression_algorithm: CompressionAlgorithm::RLE,
178            hierarchical_compression: false,
179            block_size: 64 * 1024, // 64KB blocks
180            compression_threshold: 0.9,
181            adaptive_compression: false,
182            cache_size: 16 * 1024 * 1024, // 16MB cache
183            out_of_core: false,
184            temp_directory: "/tmp/scirs2_test".to_string(),
185            memory_mapping: false,
186        }
187    }
188
189    /// Create a high-performance configuration
190    pub fn high_performance() -> Self {
191        // Use reasonable defaults for 32-bit platforms (wasm32)
192        #[cfg(target_pointer_width = "32")]
193        let hp_memory_budget = 1024 * 1024 * 1024; // 1GB for 32-bit
194        #[cfg(target_pointer_width = "64")]
195        let hp_memory_budget = 32usize * 1024 * 1024 * 1024; // 32GB for 64-bit
196
197        #[cfg(target_pointer_width = "32")]
198        let hp_cache_size = 256 * 1024 * 1024; // 256MB cache for 32-bit
199        #[cfg(target_pointer_width = "64")]
200        let hp_cache_size = 2usize * 1024 * 1024 * 1024; // 2GB cache for 64-bit
201
202        Self {
203            memory_budget: hp_memory_budget,
204            compression_algorithm: CompressionAlgorithm::Adaptive,
205            hierarchical_compression: true,
206            block_size: 4 * 1024 * 1024, // 4MB blocks
207            compression_threshold: 0.7,
208            adaptive_compression: true,
209            cache_size: hp_cache_size,
210            out_of_core: true,
211            temp_directory: "/tmp/scirs2_hiperf".to_string(),
212            memory_mapping: true,
213        }
214    }
215
216    /// Create a memory-efficient configuration
217    pub fn memory_efficient() -> Self {
218        Self {
219            memory_budget: 1024 * 1024 * 1024, // 1GB
220            compression_algorithm: CompressionAlgorithm::LZ77,
221            hierarchical_compression: true,
222            block_size: 256 * 1024, // 256KB blocks
223            compression_threshold: 0.5,
224            adaptive_compression: true,
225            cache_size: 128 * 1024 * 1024, // 128MB cache
226            out_of_core: true,
227            temp_directory: "/tmp/scirs2_memeff".to_string(),
228            memory_mapping: true,
229        }
230    }
231}
232
233impl CompressionAlgorithm {
234    /// Check if the algorithm supports adaptive compression
235    pub fn supports_adaptive(&self) -> bool {
236        matches!(
237            self,
238            CompressionAlgorithm::Adaptive | CompressionAlgorithm::SparseOptimized
239        )
240    }
241
242    /// Get expected compression ratio for the algorithm
243    pub fn expected_compression_ratio(&self) -> f64 {
244        match self {
245            CompressionAlgorithm::None => 1.0,
246            CompressionAlgorithm::RLE => 0.6,
247            CompressionAlgorithm::Delta => 0.7,
248            CompressionAlgorithm::Huffman => 0.5,
249            CompressionAlgorithm::LZ77 => 0.4,
250            CompressionAlgorithm::SparseOptimized => 0.3,
251            CompressionAlgorithm::Adaptive => 0.25,
252        }
253    }
254
255    /// Get relative compression speed (higher = faster)
256    pub fn compression_speed(&self) -> f64 {
257        match self {
258            CompressionAlgorithm::None => 10.0,
259            CompressionAlgorithm::RLE => 8.0,
260            CompressionAlgorithm::Delta => 7.0,
261            CompressionAlgorithm::Huffman => 4.0,
262            CompressionAlgorithm::LZ77 => 3.0,
263            CompressionAlgorithm::SparseOptimized => 5.0,
264            CompressionAlgorithm::Adaptive => 2.0,
265        }
266    }
267
268    /// Get description of the algorithm
269    pub fn description(&self) -> &'static str {
270        match self {
271            CompressionAlgorithm::None => "No compression applied",
272            CompressionAlgorithm::RLE => "Run-Length Encoding for repeated values",
273            CompressionAlgorithm::Delta => "Delta encoding for sparse indices",
274            CompressionAlgorithm::Huffman => "Huffman coding for optimal entropy",
275            CompressionAlgorithm::LZ77 => "LZ77 dictionary-based compression",
276            CompressionAlgorithm::SparseOptimized => "Specialized sparse matrix compression",
277            CompressionAlgorithm::Adaptive => "Adaptive hybrid compression strategy",
278        }
279    }
280}