#[derive(Debug, Clone)]
pub struct AdaptiveCompressionConfig {
pub memory_budget: usize,
pub compression_algorithm: CompressionAlgorithm,
pub hierarchical_compression: bool,
pub block_size: usize,
pub compression_threshold: f64,
pub adaptive_compression: bool,
pub cache_size: usize,
pub out_of_core: bool,
pub temp_directory: String,
pub memory_mapping: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum CompressionAlgorithm {
None,
RLE,
Delta,
Huffman,
LZ77,
SparseOptimized,
Adaptive,
}
impl Default for AdaptiveCompressionConfig {
fn default() -> Self {
#[cfg(target_pointer_width = "32")]
let default_memory_budget = 512 * 1024 * 1024; #[cfg(target_pointer_width = "64")]
let default_memory_budget = 8usize * 1024 * 1024 * 1024;
#[cfg(target_pointer_width = "32")]
let default_cache_size = 64 * 1024 * 1024; #[cfg(target_pointer_width = "64")]
let default_cache_size = 256 * 1024 * 1024;
Self {
memory_budget: default_memory_budget,
compression_algorithm: CompressionAlgorithm::Adaptive,
hierarchical_compression: true,
block_size: 1024 * 1024, compression_threshold: 0.8,
adaptive_compression: true,
cache_size: default_cache_size,
out_of_core: true,
temp_directory: {
let mut p = std::env::temp_dir();
p.push("scirs2_sparse");
p.to_string_lossy().into_owned()
},
memory_mapping: true,
}
}
}
impl AdaptiveCompressionConfig {
pub fn new() -> Self {
Self::default()
}
pub fn with_memory_budget(mut self, budget: usize) -> Self {
self.memory_budget = budget;
self
}
pub fn with_compression_algorithm(mut self, algorithm: CompressionAlgorithm) -> Self {
self.compression_algorithm = algorithm;
self
}
pub fn with_hierarchical_compression(mut self, enabled: bool) -> Self {
self.hierarchical_compression = enabled;
self
}
pub fn with_block_size(mut self, size: usize) -> Self {
self.block_size = size;
self
}
pub fn with_compression_threshold(mut self, threshold: f64) -> Self {
self.compression_threshold = threshold;
self
}
pub fn with_adaptive_compression(mut self, enabled: bool) -> Self {
self.adaptive_compression = enabled;
self
}
pub fn with_cache_size(mut self, size: usize) -> Self {
self.cache_size = size;
self
}
pub fn with_out_of_core(mut self, enabled: bool) -> Self {
self.out_of_core = enabled;
self
}
pub fn with_temp_directory(mut self, dir: impl Into<String>) -> Self {
self.temp_directory = dir.into();
self
}
pub fn with_memory_mapping(mut self, enabled: bool) -> Self {
self.memory_mapping = enabled;
self
}
pub fn validate(&self) -> Result<(), String> {
if self.memory_budget == 0 {
return Err("Memory budget must be greater than 0".to_string());
}
if self.block_size == 0 {
return Err("Block size must be greater than 0".to_string());
}
if self.compression_threshold < 0.0 || self.compression_threshold > 1.0 {
return Err("Compression threshold must be between 0.0 and 1.0".to_string());
}
if self.cache_size == 0 {
return Err("Cache size must be greater than 0".to_string());
}
if self.cache_size > self.memory_budget {
return Err("Cache size cannot exceed memory budget".to_string());
}
if self.temp_directory.is_empty() {
return Err("Temporary directory must be specified".to_string());
}
Ok(())
}
pub fn lightweight() -> Self {
Self {
memory_budget: 64 * 1024 * 1024, compression_algorithm: CompressionAlgorithm::RLE,
hierarchical_compression: false,
block_size: 64 * 1024, compression_threshold: 0.9,
adaptive_compression: false,
cache_size: 16 * 1024 * 1024, out_of_core: false,
temp_directory: {
let mut p = std::env::temp_dir();
p.push("scirs2_test");
p.to_string_lossy().into_owned()
},
memory_mapping: false,
}
}
pub fn high_performance() -> Self {
#[cfg(target_pointer_width = "32")]
let hp_memory_budget = 1024 * 1024 * 1024; #[cfg(target_pointer_width = "64")]
let hp_memory_budget = 32usize * 1024 * 1024 * 1024;
#[cfg(target_pointer_width = "32")]
let hp_cache_size = 256 * 1024 * 1024; #[cfg(target_pointer_width = "64")]
let hp_cache_size = 2usize * 1024 * 1024 * 1024;
Self {
memory_budget: hp_memory_budget,
compression_algorithm: CompressionAlgorithm::Adaptive,
hierarchical_compression: true,
block_size: 4 * 1024 * 1024, compression_threshold: 0.7,
adaptive_compression: true,
cache_size: hp_cache_size,
out_of_core: true,
temp_directory: {
let mut p = std::env::temp_dir();
p.push("scirs2_hiperf");
p.to_string_lossy().into_owned()
},
memory_mapping: true,
}
}
pub fn memory_efficient() -> Self {
Self {
memory_budget: 1024 * 1024 * 1024, compression_algorithm: CompressionAlgorithm::LZ77,
hierarchical_compression: true,
block_size: 256 * 1024, compression_threshold: 0.5,
adaptive_compression: true,
cache_size: 128 * 1024 * 1024, out_of_core: true,
temp_directory: {
let mut p = std::env::temp_dir();
p.push("scirs2_memeff");
p.to_string_lossy().into_owned()
},
memory_mapping: true,
}
}
}
impl CompressionAlgorithm {
pub fn supports_adaptive(&self) -> bool {
matches!(
self,
CompressionAlgorithm::Adaptive | CompressionAlgorithm::SparseOptimized
)
}
pub fn expected_compression_ratio(&self) -> f64 {
match self {
CompressionAlgorithm::None => 1.0,
CompressionAlgorithm::RLE => 0.6,
CompressionAlgorithm::Delta => 0.7,
CompressionAlgorithm::Huffman => 0.5,
CompressionAlgorithm::LZ77 => 0.4,
CompressionAlgorithm::SparseOptimized => 0.3,
CompressionAlgorithm::Adaptive => 0.25,
}
}
pub fn compression_speed(&self) -> f64 {
match self {
CompressionAlgorithm::None => 10.0,
CompressionAlgorithm::RLE => 8.0,
CompressionAlgorithm::Delta => 7.0,
CompressionAlgorithm::Huffman => 4.0,
CompressionAlgorithm::LZ77 => 3.0,
CompressionAlgorithm::SparseOptimized => 5.0,
CompressionAlgorithm::Adaptive => 2.0,
}
}
pub fn description(&self) -> &'static str {
match self {
CompressionAlgorithm::None => "No compression applied",
CompressionAlgorithm::RLE => "Run-Length Encoding for repeated values",
CompressionAlgorithm::Delta => "Delta encoding for sparse indices",
CompressionAlgorithm::Huffman => "Huffman coding for optimal entropy",
CompressionAlgorithm::LZ77 => "LZ77 dictionary-based compression",
CompressionAlgorithm::SparseOptimized => "Specialized sparse matrix compression",
CompressionAlgorithm::Adaptive => "Adaptive hybrid compression strategy",
}
}
}