use vortex_array::ArrayRef;
use vortex_array::Canonical;
use vortex_array::ExecutionCtx;
use vortex_error::VortexResult;
use super::is_integer_primitive;
use crate::CascadingCompressor;
use crate::builtins::IntConstantScheme;
use crate::builtins::constant::compress_constant_array_with_validity;
use crate::ctx::CompressorContext;
use crate::estimate::CompressionEstimate;
use crate::estimate::EstimateVerdict;
use crate::scheme::Scheme;
use crate::stats::ArrayAndStats;
impl Scheme for IntConstantScheme {
fn scheme_name(&self) -> &'static str {
"vortex.int.constant"
}
fn matches(&self, canonical: &Canonical) -> bool {
is_integer_primitive(canonical)
}
fn expected_compression_ratio(
&self,
data: &ArrayAndStats,
compress_ctx: CompressorContext,
exec_ctx: &mut ExecutionCtx,
) -> CompressionEstimate {
if compress_ctx.is_sample() {
return CompressionEstimate::Verdict(EstimateVerdict::Skip);
}
let array_len = data.array().len();
let stats = data.integer_stats(exec_ctx);
if let Some(distinct_count) = stats.distinct_count() {
if distinct_count > 1 {
return CompressionEstimate::Verdict(EstimateVerdict::Skip);
} else {
debug_assert_eq!(distinct_count, 1);
return CompressionEstimate::Verdict(EstimateVerdict::AlwaysUse);
}
}
if stats.value_count() == 0 {
debug_assert_eq!(stats.null_count() as usize, array_len);
return CompressionEstimate::Verdict(EstimateVerdict::AlwaysUse);
}
match stats.erased().max_minus_min().checked_ilog2() {
Some(_) => CompressionEstimate::Verdict(EstimateVerdict::Skip),
None => CompressionEstimate::Verdict(EstimateVerdict::AlwaysUse),
}
}
fn compress(
&self,
_compressor: &CascadingCompressor,
data: &ArrayAndStats,
_compress_ctx: CompressorContext,
exec_ctx: &mut ExecutionCtx,
) -> VortexResult<ArrayRef> {
compress_constant_array_with_validity(data.array(), exec_ctx)
}
}