use vortex_error::VortexExpect;
use vortex_error::VortexResult;
use super::Between;
use super::BetweenOptions;
use super::precondition;
use crate::ArrayRef;
use crate::ExecutionCtx;
use crate::array::ArrayView;
use crate::array::VTable;
use crate::arrays::ScalarFnVTable;
use crate::arrays::scalar_fn::ExactScalarFn;
use crate::arrays::scalar_fn::ScalarFnArrayExt;
use crate::arrays::scalar_fn::ScalarFnArrayView;
use crate::kernel::ExecuteParentKernel;
use crate::optimizer::rules::ArrayParentReduceRule;
pub trait BetweenReduce: VTable {
fn between(
array: ArrayView<'_, Self>,
lower: &ArrayRef,
upper: &ArrayRef,
options: &BetweenOptions,
) -> VortexResult<Option<ArrayRef>>;
}
pub trait BetweenKernel: VTable {
fn between(
array: ArrayView<'_, Self>,
lower: &ArrayRef,
upper: &ArrayRef,
options: &BetweenOptions,
ctx: &mut ExecutionCtx,
) -> VortexResult<Option<ArrayRef>>;
}
#[derive(Default, Debug)]
pub struct BetweenReduceAdaptor<V>(pub V);
impl<V> ArrayParentReduceRule<V> for BetweenReduceAdaptor<V>
where
V: BetweenReduce,
{
type Parent = ExactScalarFn<Between>;
fn reduce_parent(
&self,
array: ArrayView<'_, V>,
parent: ScalarFnArrayView<'_, Between>,
child_idx: usize,
) -> VortexResult<Option<ArrayRef>> {
if child_idx != 0 {
return Ok(None);
}
let scalar_fn_array = parent
.as_opt::<ScalarFnVTable>()
.vortex_expect("ExactScalarFn matcher confirmed ScalarFnArray");
let children = scalar_fn_array.children();
let lower = &children[1];
let upper = &children[2];
let arr = array.array().clone();
if let Some(result) = precondition(&arr, lower, upper)? {
return Ok(Some(result));
}
<V as BetweenReduce>::between(array, lower, upper, parent.options)
}
}
#[derive(Default, Debug)]
pub struct BetweenExecuteAdaptor<V>(pub V);
impl<V> ExecuteParentKernel<V> for BetweenExecuteAdaptor<V>
where
V: BetweenKernel,
{
type Parent = ExactScalarFn<Between>;
fn execute_parent(
&self,
array: ArrayView<'_, V>,
parent: ScalarFnArrayView<'_, Between>,
child_idx: usize,
ctx: &mut ExecutionCtx,
) -> VortexResult<Option<ArrayRef>> {
if child_idx != 0 {
return Ok(None);
}
let scalar_fn_array = parent
.as_opt::<ScalarFnVTable>()
.vortex_expect("ExactScalarFn matcher confirmed ScalarFnArray");
let children = scalar_fn_array.children();
let lower = &children[1];
let upper = &children[2];
let arr = array.array().clone();
if let Some(result) = precondition(&arr, lower, upper)? {
return Ok(Some(result));
}
<V as BetweenKernel>::between(array, lower, upper, parent.options, ctx)
}
}