use std::fmt;
use vortex_array::ExecutionCtx;
use vortex_error::VortexResult;
use crate::CascadingCompressor;
use crate::scheme::CompressorContext;
use crate::stats::ArrayAndStats;
#[rustfmt::skip]
pub type EstimateFn = dyn FnOnce(
&CascadingCompressor,
&ArrayAndStats,
Option<EstimateScore>,
CompressorContext,
&mut ExecutionCtx,
) -> VortexResult<EstimateVerdict>
+ Send
+ Sync;
#[derive(Debug)]
pub enum CompressionEstimate {
Verdict(EstimateVerdict),
Deferred(DeferredEstimate),
}
#[derive(Debug)]
pub enum EstimateVerdict {
Skip,
AlwaysUse,
Ratio(f64),
}
pub enum DeferredEstimate {
Sample,
Callback(Box<EstimateFn>),
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum EstimateScore {
FiniteCompression(f64),
ZeroBytes,
}
impl EstimateScore {
pub(crate) fn from_sample_sizes(before_nbytes: u64, after_nbytes: u64) -> Self {
if after_nbytes == 0 {
Self::ZeroBytes
} else {
Self::FiniteCompression(before_nbytes as f64 / after_nbytes as f64)
}
}
pub fn finite_ratio(self) -> Option<f64> {
match self {
Self::FiniteCompression(ratio) => Some(ratio),
Self::ZeroBytes => None,
}
}
pub(crate) fn is_valid(self) -> bool {
match self {
Self::FiniteCompression(ratio) => {
ratio.is_finite() && !ratio.is_subnormal() && ratio > 1.0
}
Self::ZeroBytes => false,
}
}
pub(crate) fn beats(self, other: Self) -> bool {
match (self, other) {
(Self::ZeroBytes, _) => false,
(Self::FiniteCompression(_), Self::ZeroBytes) => true,
(Self::FiniteCompression(ratio), Self::FiniteCompression(best_ratio)) => {
ratio > best_ratio
}
}
}
}
impl fmt::Debug for DeferredEstimate {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DeferredEstimate::Sample => write!(f, "Sample"),
DeferredEstimate::Callback(_) => write!(f, "Callback(..)"),
}
}
}