1pub mod block;
19pub mod config;
20pub mod engine;
21pub mod format;
22pub mod index;
23
24pub use config::{
26 EngineConfiguration, EngineConfigurationBuilder, ProgressCallback, ProgressEvent, ProgressPhase,
27};
28pub use engine::{
29 compress, compress_file, compress_stream, compress_to_writer, decompress,
30 decompress_from_reader,
31};
32pub use format::BlockIndexEntry;
33pub use index::{decompress_block, load_index, BlockIndex};
34
35use crush_core::error::Result;
36use crush_core::plugin::{CompressionAlgorithm, PluginMetadata, COMPRESSION_ALGORITHMS};
37use linkme::distributed_slice;
38use std::sync::atomic::AtomicBool;
39use std::sync::Arc;
40
41pub const PLUGIN_MAGIC: [u8; 4] = [0x43, 0x52, 0x01, 0x02];
47
48struct ParallelDeflatePlugin;
50
51impl CompressionAlgorithm for ParallelDeflatePlugin {
52 fn name(&self) -> &'static str {
53 "parallel-deflate"
54 }
55
56 fn metadata(&self) -> PluginMetadata {
57 PluginMetadata {
58 name: "parallel-deflate",
59 version: env!("CARGO_PKG_VERSION"),
60 magic_number: PLUGIN_MAGIC,
61 throughput: 500.0,
62 compression_ratio: 0.65,
63 description: "Multi-threaded DEFLATE with CRSH block format; parallel decompress and random access",
64 }
65 }
66
67 fn compress(&self, input: &[u8], cancel_flag: Arc<AtomicBool>) -> Result<Vec<u8>> {
68 use crate::config::ProgressCallback;
69 use std::sync::atomic::Ordering;
70 use std::sync::Mutex;
71
72 let cb: ProgressCallback = Box::new(move |_event| !cancel_flag.load(Ordering::Acquire));
74 let config = EngineConfiguration::builder()
75 .progress(Arc::new(Mutex::new(cb)))
76 .build()?;
77 compress(input, &config)
78 }
79
80 fn decompress(&self, input: &[u8], cancel_flag: Arc<AtomicBool>) -> Result<Vec<u8>> {
81 use crate::config::ProgressCallback;
82 use std::sync::atomic::Ordering;
83 use std::sync::Mutex;
84
85 let cb: ProgressCallback = Box::new(move |_event| !cancel_flag.load(Ordering::Acquire));
86 let config = EngineConfiguration::builder()
87 .progress(Arc::new(Mutex::new(cb)))
88 .build()?;
89 decompress(input, &config)
90 }
91
92 fn detect(&self, file_header: &[u8]) -> bool {
93 file_header.len() >= 4 && file_header[0..4] == crate::format::CRSH_MAGIC
95 }
96}
97
98#[distributed_slice(COMPRESSION_ALGORITHMS)]
100static PARALLEL_DEFLATE_PLUGIN: &dyn CompressionAlgorithm = &ParallelDeflatePlugin;