blockchain_compression/algorithms/
practical_max.rs1use crate::core::traits::{CompressionStrategy, CompressionError, CompressionMetadata, CompressionStats};
6use crate::core::pattern_engine::{PatternEngine, PatternConfig, FixedPatternConfig, CompressionBackend};
7use crate::algorithms::enhanced_ctw::{EnhancedCTW, DataCharacteristics};
8use crate::algorithms::multi_pass::MultiPassCompressor;
9use serde::{Serialize, Deserialize};
10
11pub struct PracticalMaxCompression {
13 pattern_engine: PatternEngine,
15
16 enhanced_ctw: EnhancedCTW,
18
19 multi_pass: MultiPassCompressor,
21
22 stats: CompressionStats,
24
25 config: PracticalMaxConfig,
27}
28
29#[derive(Debug, Clone)]
31pub struct PracticalMaxConfig {
32 pub use_patterns: bool,
34
35 pub use_multi_pass: bool,
37
38 pub max_passes: usize,
40
41 pub ctw_depth: usize,
43
44 pub max_patterns: usize,
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
50struct CompressedPackage {
51 version: u8,
53
54 pattern_data: Option<Vec<u8>>,
56
57 compressed_data: Vec<u8>,
59
60 metadata: PackageMetadata,
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize)]
65struct PackageMetadata {
66 original_size: usize,
67 compressed_size: usize,
68 compression_time_ns: u64,
69 passes_used: usize,
70 patterns_used: usize,
71}
72
73impl PracticalMaxCompression {
74 pub fn new() -> Self {
76 let config = PracticalMaxConfig::default();
77
78 let pattern_config = PatternConfig {
80 fixed_patterns: vec![
81 FixedPatternConfig {
82 name: "signature".to_string(),
83 size: 64,
84 marker: 0xFE,
85 max_count: 255,
86 skip_zeros: true,
87 description: "64-byte blockchain signatures".to_string(),
88 },
89 FixedPatternConfig {
90 name: "account".to_string(),
91 size: 32,
92 marker: 0xFD,
93 max_count: 255,
94 skip_zeros: true,
95 description: "32-byte account addresses".to_string(),
96 },
97 FixedPatternConfig {
98 name: "amount".to_string(),
99 size: 8,
100 marker: 0xFC,
101 max_count: 255,
102 skip_zeros: true,
103 description: "8-byte amounts".to_string(),
104 },
105 ],
106 variable_patterns: vec![],
107 max_patterns: config.max_patterns,
108 min_usage_threshold: 2,
109 auto_optimize: true,
110 backend: if cfg!(feature = "deflate") {
111 CompressionBackend::Deflate { level: 9 }
112 } else if cfg!(feature = "lz4") {
113 CompressionBackend::Lz4 { acceleration: 1 }
114 } else if cfg!(feature = "zstd") {
115 CompressionBackend::Zstd { level: 19 }
116 } else {
117 CompressionBackend::None
118 },
119 };
120
121 let pattern_engine = PatternEngine::new(pattern_config);
122 let enhanced_ctw = EnhancedCTW::with_config(config.ctw_depth, 0.5, 0.5);
123 let multi_pass = MultiPassCompressor::with_config(config.max_passes, 0.05);
124
125 Self {
126 pattern_engine,
127 enhanced_ctw,
128 multi_pass,
129 stats: CompressionStats::new(),
130 config,
131 }
132 }
133
134 pub fn with_config(config: PracticalMaxConfig) -> Self {
136 let mut compressor = Self::new();
137 compressor.config = config;
138 compressor
139 }
140
141 pub fn compress_block_data(&mut self, data: &[u8]) -> Result<Vec<u8>, CompressionError> {
143 let start_time = std::time::Instant::now();
144
145 log::info!("PRACTICAL MAX COMPRESSION: {} bytes", data.len());
146
147 let characteristics = self.enhanced_ctw.analyze_data(data);
149 log::info!(
150 "Data analysis: Entropy={:.3}, Patterns={:.3}, Repetition={:.3}",
151 characteristics.entropy,
152 characteristics.pattern_density,
153 characteristics.repetition_factor
154 );
155
156 let mut current_data = data.to_vec();
157 let mut passes_used = 0;
158 let mut patterns_used = 0;
159
160 if self.config.use_patterns {
162 current_data = self.apply_blockchain_patterns(¤t_data)?;
163 patterns_used = self.pattern_engine.pattern_count();
164
165 let pattern_ratio = data.len() as f32 / current_data.len() as f32;
166 log::info!(
167 "Pattern replacement: {:.2}:1 ({} -> {} bytes)",
168 pattern_ratio,
169 data.len(),
170 current_data.len()
171 );
172 }
173
174 if self.config.use_multi_pass {
176 current_data = self.multi_pass.compress(¤t_data)?;
177 passes_used = self.config.max_passes;
178 }
179
180 self.enhanced_ctw.adjust_parameters(&characteristics);
182 let final_compressed = self.enhanced_ctw.compress(¤t_data)?;
183
184 let package = CompressedPackage {
186 version: 0x03, pattern_data: if self.config.use_patterns {
188 Some(self.serialize_pattern_state()?)
189 } else {
190 None
191 },
192 compressed_data: final_compressed,
193 metadata: PackageMetadata {
194 original_size: data.len(),
195 compressed_size: current_data.len(),
196 compression_time_ns: start_time.elapsed().as_nanos() as u64,
197 passes_used,
198 patterns_used,
199 },
200 };
201
202 let final_result = self.serialize_package(&package)?;
203
204 let total_ratio = data.len() as f32 / final_result.len() as f32;
206 let compression_time = start_time.elapsed().as_nanos() as u64;
207 self.stats.record_compression(data.len(), final_result.len(), compression_time);
208
209 log::info!(
210 "FINAL RESULT: {:.2}:1 compression ({} -> {} bytes) in {:?}",
211 total_ratio,
212 data.len(),
213 final_result.len(),
214 start_time.elapsed()
215 );
216
217 Ok(final_result)
218 }
219
220 pub fn decompress_block_data(&self, data: &[u8]) -> Result<Vec<u8>, CompressionError> {
222 if data.is_empty() {
223 return Err(CompressionError::InvalidFormat);
224 }
225
226 let package = self.deserialize_package(data)?;
227
228 match package.version {
229 0x03 => self.decompress_v3_full(&package),
230 _ => Err(CompressionError::UnsupportedVersion {
231 version: format!("0x{:02x}", package.version),
232 }),
233 }
234 }
235
236 fn decompress_v3_full(&self, package: &CompressedPackage) -> Result<Vec<u8>, CompressionError> {
237 let ctw_decompressed = self.enhanced_ctw.decompress(&package.compressed_data)?;
239
240 let mut current_data = ctw_decompressed;
242 if package.metadata.passes_used > 0 {
243 }
246
247 if let Some(ref pattern_data) = package.pattern_data {
249 current_data = self.reconstruct_patterns(¤t_data, pattern_data)?;
250 }
251
252 Ok(current_data)
253 }
254
255 fn apply_blockchain_patterns(&mut self, data: &[u8]) -> Result<Vec<u8>, CompressionError> {
256 self.pattern_engine.compress(data)
258 }
259
260 fn reconstruct_patterns(&self, data: &[u8], _pattern_data: &[u8]) -> Result<Vec<u8>, CompressionError> {
261 self.pattern_engine.decompress(data)
263 }
264
265 fn serialize_pattern_state(&self) -> Result<Vec<u8>, CompressionError> {
266 Ok(Vec::new())
269 }
270
271 fn serialize_package(&self, package: &CompressedPackage) -> Result<Vec<u8>, CompressionError> {
272 bincode::serialize(package)
273 .map_err(|e| CompressionError::Serialization(e.to_string()))
274 }
275
276 fn deserialize_package(&self, data: &[u8]) -> Result<CompressedPackage, CompressionError> {
277 bincode::deserialize(data)
278 .map_err(|e| CompressionError::Serialization(e.to_string()))
279 }
280
281 pub fn get_stats(&self) -> &CompressionStats {
283 &self.stats
284 }
285
286 pub fn get_best_compression_ratio(&self) -> f64 {
288 self.stats.best_ratio
289 }
290
291 pub fn reset_state(&mut self) {
293 self.pattern_engine.reset();
294 self.enhanced_ctw.reset();
295 self.multi_pass.reset();
296 self.stats = CompressionStats::new();
297 }
298}
299
300impl CompressionStrategy for PracticalMaxCompression {
301 type Error = CompressionError;
302
303 fn compress(&mut self, data: &[u8]) -> Result<Vec<u8>, Self::Error> {
304 self.compress_block_data(data)
305 }
306
307 fn decompress(&self, data: &[u8]) -> Result<Vec<u8>, Self::Error> {
308 self.decompress_block_data(data)
309 }
310
311 fn metadata(&self) -> CompressionMetadata {
312 CompressionMetadata {
313 name: "Practical Maximum Compression".to_string(),
314 version: "1.0.0".to_string(),
315 description: "Maximum practical compression combining all techniques".to_string(),
316 deterministic: false, memory_usage: std::mem::size_of::<Self>() +
318 self.pattern_engine.memory_usage() +
319 std::mem::size_of::<EnhancedCTW>() +
320 std::mem::size_of::<MultiPassCompressor>(),
321 domains: vec!["blockchain".to_string(), "solana".to_string()],
322 }
323 }
324
325 fn stats(&self) -> CompressionStats {
326 self.stats.clone()
327 }
328
329 fn reset(&mut self) {
330 self.reset_state();
331 }
332}
333
334impl Default for PracticalMaxConfig {
335 fn default() -> Self {
336 Self {
337 use_patterns: true,
338 use_multi_pass: false, max_passes: 2,
340 ctw_depth: 8,
341 max_patterns: 1000,
342 }
343 }
344}
345
346impl Default for PracticalMaxCompression {
347 fn default() -> Self {
348 Self::new()
349 }
350}
351
352#[cfg(test)]
353mod tests {
354 use super::*;
355
356 #[test]
357 fn test_practical_max_compression() {
358 let mut compressor = PracticalMaxCompression::new();
359
360 let test_data = create_test_blockchain_data();
362
363 let compressed = compressor.compress(&test_data).unwrap();
364 let decompressed = compressor.decompress(&compressed).unwrap();
365
366 let ratio = compressor.get_best_compression_ratio();
367 println!("Practical maximum compression ratio: {:.2}:1", ratio);
368
369 assert_eq!(test_data.len(), decompressed.len());
371 assert!(ratio > 1.5);
376 }
377
378 #[test]
379 fn test_with_custom_config() {
380 let config = PracticalMaxConfig {
381 use_patterns: true,
382 use_multi_pass: false,
383 max_passes: 1,
384 ctw_depth: 4,
385 max_patterns: 100,
386 };
387
388 let mut compressor = PracticalMaxCompression::with_config(config);
389 let test_data = b"Test data for custom configuration".repeat(100);
390
391 let compressed = compressor.compress(&test_data).unwrap();
392 assert!(compressed.len() < test_data.len());
393 }
394
395 fn create_test_blockchain_data() -> Vec<u8> {
396 let mut data = Vec::new();
397
398 for i in 0..20 {
400 data.extend_from_slice(&[(i % 10) as u8; 64]);
402
403 data.extend_from_slice(&[(i % 5) as u8; 32]);
405 data.extend_from_slice(&[((i + 1) % 5) as u8; 32]);
406
407 data.extend_from_slice(&[0x02, 0x00, 0x00, 0x00]);
409
410 let amount = ((i % 20) as u64 + 1) * 1000000;
412 data.extend_from_slice(&amount.to_le_bytes());
413 }
414
415 data
416 }
417}