use std::fmt;
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Formatter;
use std::hash::Hash;
use vortex_error::VortexResult;
use vortex_error::vortex_bail;
use vortex_session::VortexSession;
use crate::ArrayRef;
use crate::Columnar;
use crate::ExecutionCtx;
use crate::IntoArray;
use crate::aggregate_fn::AggregateFn;
use crate::aggregate_fn::AggregateFnId;
use crate::aggregate_fn::AggregateFnRef;
use crate::arrays::ConstantArray;
use crate::dtype::DType;
use crate::scalar::Scalar;
pub trait AggregateFnVTable: 'static + Sized + Clone + Send + Sync {
type Options: 'static + Send + Sync + Clone + Debug + Display + PartialEq + Eq + Hash;
type Partial: 'static + Send;
fn id(&self) -> AggregateFnId;
fn serialize(&self, options: &Self::Options) -> VortexResult<Option<Vec<u8>>> {
_ = options;
Ok(None)
}
fn deserialize(
&self,
_metadata: &[u8],
_session: &VortexSession,
) -> VortexResult<Self::Options> {
vortex_bail!("Aggregate function {} is not deserializable", self.id());
}
fn coerce_args(&self, options: &Self::Options, input_dtype: &DType) -> VortexResult<DType> {
let _ = options;
Ok(input_dtype.clone())
}
fn return_dtype(&self, options: &Self::Options, input_dtype: &DType) -> Option<DType>;
fn partial_dtype(&self, options: &Self::Options, input_dtype: &DType) -> Option<DType>;
fn empty_partial(
&self,
options: &Self::Options,
input_dtype: &DType,
) -> VortexResult<Self::Partial>;
fn combine_partials(&self, partial: &mut Self::Partial, other: Scalar) -> VortexResult<()>;
fn to_scalar(&self, partial: &Self::Partial) -> VortexResult<Scalar>;
fn reset(&self, partial: &mut Self::Partial);
fn is_saturated(&self, state: &Self::Partial) -> bool;
fn try_accumulate(
&self,
_state: &mut Self::Partial,
_batch: &ArrayRef,
_ctx: &mut ExecutionCtx,
) -> VortexResult<bool> {
Ok(false)
}
fn accumulate(
&self,
state: &mut Self::Partial,
batch: &Columnar,
ctx: &mut ExecutionCtx,
) -> VortexResult<()>;
fn finalize(&self, states: ArrayRef) -> VortexResult<ArrayRef>;
fn finalize_scalar(&self, partial: &Self::Partial) -> VortexResult<Scalar> {
let scalar = self.to_scalar(partial)?;
let array = ConstantArray::new(scalar, 1).into_array();
let result = self.finalize(array)?;
result.scalar_at(0)
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct EmptyOptions;
impl Display for EmptyOptions {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "")
}
}
pub trait AggregateFnVTableExt: AggregateFnVTable {
fn bind(&self, options: Self::Options) -> AggregateFnRef {
AggregateFn::new(self.clone(), options).erased()
}
}
impl<V: AggregateFnVTable> AggregateFnVTableExt for V {}