Skip to main content

blockchain_compression/core/
traits.rs

1//! Core traits for blockchain compression algorithms
2//!
3//! This module defines the fundamental interfaces that all compression implementations
4//! must satisfy, enabling composable and pluggable compression strategies.
5
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9/// A trait for compression algorithms that can compress and decompress data
10pub trait CompressionStrategy {
11    /// The error type produced by this compression strategy
12    type Error: std::error::Error + Send + Sync + 'static;
13
14    /// Compresses the input data
15    fn compress(&mut self, data: &[u8]) -> Result<Vec<u8>, Self::Error>;
16
17    /// Decompresses the input data
18    fn decompress(&self, data: &[u8]) -> Result<Vec<u8>, Self::Error>;
19
20    /// Returns metadata about this compression algorithm
21    fn metadata(&self) -> CompressionMetadata;
22
23    /// Returns the current compression statistics
24    fn stats(&self) -> CompressionStats;
25
26    /// Resets internal state (useful for stateful compressors)
27    fn reset(&mut self);
28}
29
30/// Metadata about a compression algorithm
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct CompressionMetadata {
33    /// Human-readable name of the algorithm
34    pub name: String,
35    /// Version identifier
36    pub version: String,
37    /// Description of the algorithm
38    pub description: String,
39    /// Whether this algorithm is deterministic
40    pub deterministic: bool,
41    /// Approximate memory usage in bytes
42    pub memory_usage: usize,
43    /// Supported data types/domains
44    pub domains: Vec<String>,
45}
46
47/// Statistics for compression performance
48#[derive(Debug, Clone, Serialize, Deserialize)]
49pub struct CompressionStats {
50    /// Total number of compression operations performed
51    pub compressions: u64,
52    /// Total number of decompression operations performed
53    pub decompressions: u64,
54    /// Total original bytes processed
55    pub total_input_bytes: u64,
56    /// Total compressed bytes produced
57    pub total_output_bytes: u64,
58    /// Best compression ratio achieved (input/output)
59    pub best_ratio: f64,
60    /// Average compression ratio
61    pub average_ratio: f64,
62    /// Total time spent compressing (nanoseconds)
63    pub compression_time_ns: u64,
64    /// Total time spent decompressing (nanoseconds)
65    pub decompression_time_ns: u64,
66    /// Number of compression errors encountered
67    pub errors: u64,
68}
69
70impl CompressionStats {
71    /// Create new empty statistics
72    pub fn new() -> Self {
73        Self {
74            compressions: 0,
75            decompressions: 0,
76            total_input_bytes: 0,
77            total_output_bytes: 0,
78            best_ratio: 1.0,
79            average_ratio: 1.0,
80            compression_time_ns: 0,
81            decompression_time_ns: 0,
82            errors: 0,
83        }
84    }
85
86    /// Record a successful compression operation
87    pub fn record_compression(&mut self, input_size: usize, output_size: usize, time_ns: u64) {
88        self.compressions += 1;
89        self.total_input_bytes += input_size as u64;
90        self.total_output_bytes += output_size as u64;
91        self.compression_time_ns += time_ns;
92
93        let ratio = input_size as f64 / output_size as f64;
94        if ratio > self.best_ratio {
95            self.best_ratio = ratio;
96        }
97
98        // Update average ratio
99        if self.total_output_bytes > 0 {
100            self.average_ratio = self.total_input_bytes as f64 / self.total_output_bytes as f64;
101        }
102    }
103
104    /// Record a successful decompression operation
105    pub fn record_decompression(&mut self, time_ns: u64) {
106        self.decompressions += 1;
107        self.decompression_time_ns += time_ns;
108    }
109
110    /// Record an error
111    pub fn record_error(&mut self) {
112        self.errors += 1;
113    }
114
115    /// Get compression throughput in MB/s
116    pub fn compression_throughput_mbps(&self) -> f64 {
117        if self.compression_time_ns == 0 {
118            return 0.0;
119        }
120        let mb_processed = self.total_input_bytes as f64 / 1_000_000.0;
121        let seconds = self.compression_time_ns as f64 / 1_000_000_000.0;
122        mb_processed / seconds
123    }
124
125    /// Get decompression throughput in MB/s
126    pub fn decompression_throughput_mbps(&self) -> f64 {
127        if self.decompression_time_ns == 0 {
128            return 0.0;
129        }
130        let mb_processed = self.total_output_bytes as f64 / 1_000_000.0;
131        let seconds = self.decompression_time_ns as f64 / 1_000_000_000.0;
132        mb_processed / seconds
133    }
134}
135
136impl Default for CompressionStats {
137    fn default() -> Self {
138        Self::new()
139    }
140}
141
142/// A trait for pattern-based compression strategies
143pub trait PatternCompressionStrategy: CompressionStrategy {
144    /// The type representing a pattern
145    type Pattern: Clone + Send + Sync;
146
147    /// The type representing pattern configuration
148    type Config: Clone + Send + Sync;
149
150    /// Create a new instance with the given configuration
151    fn with_config(config: Self::Config) -> Self;
152
153    /// Add a pattern to the compression dictionary
154    fn add_pattern(&mut self, pattern: Self::Pattern) -> Result<(), Self::Error>;
155
156    /// Remove a pattern from the compression dictionary
157    fn remove_pattern(&mut self, pattern_id: &str) -> Result<(), Self::Error>;
158
159    /// Get information about registered patterns
160    fn pattern_info(&self) -> HashMap<String, PatternInfo>;
161
162    /// Optimize pattern dictionary based on usage statistics
163    fn optimize_patterns(&mut self) -> Result<(), Self::Error>;
164}
165
166/// Information about a compression pattern
167#[derive(Debug, Clone, Serialize, Deserialize)]
168pub struct PatternInfo {
169    /// Unique identifier for this pattern
170    pub id: String,
171    /// Size of the pattern in bytes
172    pub size: usize,
173    /// Number of times this pattern has been used
174    pub usage_count: u64,
175    /// Compression benefit (bytes saved) from this pattern
176    pub bytes_saved: u64,
177    /// Human-readable description
178    pub description: String,
179}
180
181/// A trait for multi-stage compression pipelines
182pub trait PipelineCompressionStrategy: CompressionStrategy {
183    /// The type representing a compression stage
184    type Stage: CompressionStrategy;
185
186    /// Add a stage to the compression pipeline
187    fn add_stage(&mut self, stage: Self::Stage) -> Result<(), Self::Error>;
188
189    /// Remove a stage from the pipeline
190    fn remove_stage(&mut self, index: usize) -> Result<Self::Stage, Self::Error>;
191
192    /// Get the number of stages in the pipeline
193    fn stage_count(&self) -> usize;
194
195    /// Get statistics for each stage
196    fn stage_stats(&self) -> Vec<CompressionStats>;
197
198    /// Enable or disable a specific stage
199    fn set_stage_enabled(&mut self, index: usize, enabled: bool) -> Result<(), Self::Error>;
200}
201
202/// A trait for adaptive compression strategies that learn from data
203pub trait AdaptiveCompressionStrategy: CompressionStrategy {
204    /// Train the compressor on a dataset
205    fn train(&mut self, training_data: &[&[u8]]) -> Result<(), Self::Error>;
206
207    /// Get the current learning progress (0.0 to 1.0)
208    fn learning_progress(&self) -> f64;
209
210    /// Save the learned model to bytes
211    fn save_model(&self) -> Result<Vec<u8>, Self::Error>;
212
213    /// Load a previously learned model from bytes
214    fn load_model(&mut self, model_data: &[u8]) -> Result<(), Self::Error>;
215
216    /// Get information about what the algorithm has learned
217    fn learning_info(&self) -> LearningInfo;
218}
219
220/// Information about what an adaptive algorithm has learned
221#[derive(Debug, Clone, Serialize, Deserialize)]
222pub struct LearningInfo {
223    /// Number of training samples processed
224    pub training_samples: u64,
225    /// Estimated model quality (0.0 to 1.0)
226    pub model_quality: f64,
227    /// Key patterns or features discovered
228    pub discovered_features: Vec<String>,
229    /// Memory usage of the learned model
230    pub model_size_bytes: usize,
231}
232
233/// Common error types for compression algorithms
234#[derive(Debug, thiserror::Error)]
235pub enum CompressionError {
236    #[error("Invalid compression format")]
237    InvalidFormat,
238
239    #[error("Unsupported algorithm version: {version}")]
240    UnsupportedVersion { version: String },
241
242    #[error("Configuration error: {message}")]
243    Configuration { message: String },
244
245    #[error("Pattern error: {message}")]
246    Pattern { message: String },
247
248    #[error("Pipeline error at stage {stage}: {message}")]
249    Pipeline { stage: usize, message: String },
250
251    #[error("Training error: {message}")]
252    Training { message: String },
253
254    #[error("IO error: {0}")]
255    Io(#[from] std::io::Error),
256
257    #[error("Serialization error: {0}")]
258    Serialization(String),
259
260    #[error("Internal error: {message}")]
261    Internal { message: String },
262}