use crate::prelude::*;
#[cfg(feature = "encode")]
pub(crate) fn compress<T: PartialEq, O: EncodeOptions>(data: &[T], stream: &mut EncoderStream<'_, O>, compressors: &impl CompressorSet<T>) -> ArrayTypeId {
profile_fn!(master_compress);
if compressors.len() == 1 {
return compressors.compress(0, data, stream).unwrap();
}
profile_section!(samples);
let restore_bytes = stream.bytes.len();
let restore_lens = stream.lens.len();
let sample_size = data.len().min(256);
let sample = &data[..sample_size];
let mut by_size = Vec::new();
for i in 0..compressors.len() {
if let Ok(size) = compressors.fast_size_for(i, sample, stream.options) {
by_size.push((i, size));
}
}
drop(samples);
profile_section!(actual_compress);
by_size.sort_unstable_by_key(|&(_, size)| size);
for ranked in by_size.iter() {
if let Ok(ok) = compressors.compress(ranked.0, data, stream) {
return ok;
}
stream.bytes.truncate(restore_bytes);
stream.lens.truncate(restore_lens);
}
panic!("Missing infallable compressor for type");
}
#[cfg(feature = "encode")]
pub(crate) fn fast_size_for<T: PartialEq, O: EncodeOptions>(data: &[T], compressors: &impl CompressorSet<T>, options: &O) -> usize {
profile_fn!(master fast_size_for);
let mut min = usize::MAX;
for i in 0..compressors.len() {
if let Ok(size) = compressors.fast_size_for(i, data, options) {
min = size.min(min);
}
}
debug_assert!(min != usize::MAX);
min
}
#[cfg(feature = "encode")]
pub(crate) trait Compressor<T> {
fn fast_size_for<O: EncodeOptions>(&self, data: &[T], options: &O) -> Result<usize, ()>;
fn compress<O: EncodeOptions>(&self, data: &[T], stream: &mut EncoderStream<'_, O>) -> Result<ArrayTypeId, ()>;
}
pub(crate) trait CompressorSet<T> {
fn len(&self) -> usize;
fn fast_size_for<O: EncodeOptions>(&self, compressor: usize, data: &[T], options: &O) -> Result<usize, ()>;
fn compress<O: EncodeOptions>(&self, compressor: usize, data: &[T], stream: &mut EncoderStream<'_, O>) -> Result<ArrayTypeId, ()>;
}