aboutsummaryrefslogtreecommitdiffstats
path: root/src/compress.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-05 04:17:21 +0100
committertv <tv@krebsco.de>2026-11-05 04:17:21 +0100
commitc1b2645f3097f038c37ffa520f2a24ffd3c65649 (patch)
treefb0e2359ed63f8a73a9f96021e285b86ba14fc2b /src/compress.rs
parent0d3e68e20f0812a2fdf5c9736cf3161f30912211 (diff)
compress level 2
Diffstat (limited to 'src/compress.rs')
-rw-r--r--src/compress.rs21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/compress.rs b/src/compress.rs
index 77e634d..d175cda 100644
--- a/src/compress.rs
+++ b/src/compress.rs
@@ -12,12 +12,19 @@ use flate2::write::DeflateEncoder;
/// Below this, deflating saves too little to be worth it.
pub(crate) const WORTH_FROM: usize = 1024;
+/// Not 1 (`Compression::fast`): `flate2` runs on zlib-rs here (another dependency asks
+/// for it), whose level 1 is zlib-ng's quick deflate, with fixed Huffman codes only.
+/// Those can't use a skewed alphabet: 64 KiB of random hex shrinks to 87% at level 1, to
+/// 54% at level 2 (as at level 6), still quick.
+const LEVEL: u32 = 2;
+
/// `bytes` deflated, if that makes them at least a tenth smaller.
pub(crate) fn deflate(bytes: &[u8]) -> Option<Vec<u8>> {
if bytes.len() < WORTH_FROM {
return None;
}
- let mut encoder = DeflateEncoder::new(Vec::with_capacity(bytes.len() / 2), Compression::fast());
+ let mut encoder =
+ DeflateEncoder::new(Vec::with_capacity(bytes.len() / 2), Compression::new(LEVEL));
encoder.write_all(bytes).ok()?;
let deflated = encoder.finish().ok()?;
(deflated.len() < bytes.len() - bytes.len() / 10).then_some(deflated)
@@ -53,6 +60,18 @@ mod tests {
"over the limit"
);
assert!(deflate(b"short").is_none());
+ // Hex has 4 bits in 8: about half, as Huffman codes alone get it.
+ let mut rng = crate::testrand::Rng::new(2);
+ let hex: String = (0..4096)
+ .map(|_| format!("{:016x}", rng.next_u64()))
+ .collect();
+ let deflated = deflate(hex.as_bytes()).expect("hex shrinks");
+ assert!(
+ deflated.len() < hex.len() * 6 / 10,
+ "{} of {}",
+ deflated.len(),
+ hex.len()
+ );
let mut rng = crate::testrand::Rng::new(1);
let noise: Vec<u8> = (0..4096).map(|_| rng.next_u64() as u8).collect();
assert!(deflate(&noise).is_none(), "noise doesn't shrink");