use vortex_utils::aliases::hash_set::HashSet;
use crate::BtrBlocksCompressor;
use crate::CascadingCompressor;
use crate::Scheme;
use crate::SchemeExt;
use crate::SchemeId;
use crate::schemes::bool;
use crate::schemes::decimal;
use crate::schemes::float;
use crate::schemes::integer;
use crate::schemes::string;
use crate::schemes::temporal;
pub const ALL_SCHEMES: &[&dyn Scheme] = &[
&bool::BoolConstantScheme,
&integer::IntConstantScheme,
&integer::FoRScheme,
&integer::ZigZagScheme,
&integer::BitPackingScheme,
&integer::SparseScheme,
&integer::IntDictScheme,
&integer::RunEndScheme,
&integer::SequenceScheme,
&integer::IntRLEScheme,
&float::FloatConstantScheme,
&float::ALPScheme,
&float::ALPRDScheme,
&float::FloatDictScheme,
&float::NullDominatedSparseScheme,
&float::FloatRLEScheme,
&string::StringDictScheme,
&string::FSSTScheme,
&string::StringConstantScheme,
&string::NullDominatedSparseScheme,
&decimal::DecimalScheme,
&temporal::TemporalScheme,
];
#[derive(Debug, Clone)]
pub struct BtrBlocksCompressorBuilder {
schemes: Vec<&'static dyn Scheme>,
}
impl Default for BtrBlocksCompressorBuilder {
fn default() -> Self {
Self {
schemes: ALL_SCHEMES.to_vec(),
}
}
}
impl BtrBlocksCompressorBuilder {
pub fn empty() -> Self {
Self {
schemes: Vec::new(),
}
}
pub fn with_new_scheme(mut self, scheme: &'static dyn Scheme) -> Self {
assert!(
!self.schemes.iter().any(|s| s.id() == scheme.id()),
"scheme {:?} is already present in the builder",
scheme.id(),
);
self.schemes.push(scheme);
self
}
#[cfg(feature = "zstd")]
pub fn with_compact(self) -> Self {
let builder = self.with_new_scheme(&string::ZstdScheme);
#[cfg(feature = "pco")]
let builder = builder
.with_new_scheme(&integer::PcoScheme)
.with_new_scheme(&float::PcoScheme);
builder
}
#[cfg(feature = "unstable_encodings")]
pub fn with_turboquant(self) -> Self {
use vortex_tensor::encodings::turboquant::TurboQuantScheme;
self.with_new_scheme(&TurboQuantScheme)
}
pub fn only_cuda_compatible(self) -> Self {
let builder = self.exclude_schemes([
integer::SparseScheme.id(),
integer::IntRLEScheme.id(),
float::FloatRLEScheme.id(),
float::NullDominatedSparseScheme.id(),
string::StringDictScheme.id(),
string::FSSTScheme.id(),
]);
#[cfg(all(feature = "zstd", feature = "unstable_encodings"))]
let builder = builder.with_new_scheme(&string::ZstdBuffersScheme);
#[cfg(all(feature = "zstd", not(feature = "unstable_encodings")))]
let builder = builder.with_new_scheme(&string::ZstdScheme);
builder
}
pub fn exclude_schemes(mut self, ids: impl IntoIterator<Item = SchemeId>) -> Self {
let ids: HashSet<_> = ids.into_iter().collect();
self.schemes.retain(|s| !ids.contains(&s.id()));
self
}
pub fn build(self) -> BtrBlocksCompressor {
BtrBlocksCompressor(CascadingCompressor::new(self.schemes))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_starts_with_no_schemes() {
let builder = BtrBlocksCompressorBuilder::empty();
assert!(builder.schemes.is_empty());
}
#[test]
fn default_includes_all_schemes() {
let builder = BtrBlocksCompressorBuilder::default();
assert_eq!(builder.schemes.len(), ALL_SCHEMES.len());
}
}