use std::io::Write;
use structured_zstd::decoding::{Dictionary, DictionaryHandle, FrameDecoder};
use structured_zstd::encoding::{
CompressionLevel, CompressionParameters, Strategy, StreamingEncoder,
};
fn dictionary() -> &'static [u8] {
let dict: &'static [u8] = include_bytes!("../dict_tests/dictionary");
&dict[dict.len() - 4096..]
}
fn configurations() -> impl Iterator<Item = (String, CompressionParameters)> {
let forced = (1..=9).map(|ordinal| {
let strategy = Strategy::from_ordinal(ordinal).unwrap();
let params = CompressionParameters::builder(CompressionLevel::Level(3))
.strategy(strategy)
.window_log(13)
.hash_log(10)
.chain_log(10)
.search_log(3)
.build()
.unwrap();
(format!("{strategy:?}"), params)
});
let accelerated = CompressionParameters::builder(CompressionLevel::Level(-5))
.build()
.unwrap();
forced.chain(core::iter::once((String::from("level -5"), accelerated)))
}
fn compress(input: &[u8], params: &CompressionParameters, dictionary: Option<&[u8]>) -> Vec<u8> {
let mut encoder = StreamingEncoder::new(Vec::new(), CompressionLevel::Level(3));
encoder.set_parameters(params).unwrap();
if let Some(dictionary) = dictionary {
encoder.set_dictionary_from_bytes(dictionary).unwrap();
}
encoder.write_all(input).unwrap();
encoder.finish().unwrap()
}
fn sample() -> Vec<u8> {
let dict = dictionary();
let mut data = Vec::with_capacity(2048);
let mut state = 0x9E37_79B9u32;
while data.len() < 2048 {
state ^= state << 13;
state ^= state >> 17;
state ^= state << 5;
match state % 3 {
0 => data.extend_from_slice(&dict[(state as usize >> 4) % (dict.len() - 64)..][..48]),
1 => data.extend_from_slice(b"label=orders|tenant=demo|segment=0001|"),
_ => data.extend_from_slice(&state.to_le_bytes()),
}
}
data
}
#[test]
fn every_backend_round_trips() {
let input = sample();
for (name, params) in configurations() {
let frame = compress(&input, ¶ms, None);
let mut out = Vec::with_capacity(input.len());
FrameDecoder::new()
.decode_all_to_vec(&frame, &mut out)
.unwrap();
assert_eq!(out, input, "{name}");
}
}
#[test]
fn every_backend_round_trips_with_a_dictionary() {
let input = sample();
let handle = DictionaryHandle::from_dictionary(
Dictionary::from_raw_content(0, dictionary().to_vec()).unwrap(),
);
for (name, params) in configurations() {
let frame = compress(&input, ¶ms, Some(dictionary()));
let mut out = vec![0u8; input.len()];
let written = FrameDecoder::new()
.decode_all_with_dict_handle(&frame, &mut out, &handle)
.unwrap();
assert_eq!(&out[..written], input.as_slice(), "{name}");
}
}