use vortex_array::ArrayRef;
use vortex_array::Canonical;
use vortex_array::aggregate_fn::fns::is_constant::is_constant;
use vortex_error::VortexResult;
use super::is_float_primitive;
use crate::CascadingCompressor;
use crate::builtins::FloatConstantScheme;
use crate::builtins::constant::compress_constant_array_with_validity;
use crate::ctx::CompressorContext;
use crate::estimate::CompressionEstimate;
use crate::estimate::DeferredEstimate;
use crate::estimate::EstimateVerdict;
use crate::scheme::Scheme;
use crate::stats::ArrayAndStats;
impl Scheme for FloatConstantScheme {
fn scheme_name(&self) -> &'static str {
"vortex.float.constant"
}
fn matches(&self, canonical: &Canonical) -> bool {
is_float_primitive(canonical)
}
fn expected_compression_ratio(
&self,
data: &mut ArrayAndStats,
ctx: CompressorContext,
) -> CompressionEstimate {
if ctx.is_sample() {
return CompressionEstimate::Verdict(EstimateVerdict::Skip);
}
let array_len = data.array().len();
let stats = data.float_stats();
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);
}
CompressionEstimate::Deferred(DeferredEstimate::Callback(Box::new(
|compressor, data, _ctx| {
if is_constant(data.array(), &mut compressor.execution_ctx())? {
Ok(EstimateVerdict::AlwaysUse)
} else {
Ok(EstimateVerdict::Skip)
}
},
)))
}
fn compress(
&self,
_compressor: &CascadingCompressor,
data: &mut ArrayAndStats,
_ctx: CompressorContext,
) -> VortexResult<ArrayRef> {
compress_constant_array_with_validity(data.array())
}
}