use num_traits::Zero;
use vortex_error::VortexResult;
use super::REBUILD_DENSITY_THRESHOLD;
use crate::ArrayRef;
use crate::ExecutionCtx;
use crate::IntoArray;
use crate::array::ArrayView;
use crate::arrays::ListView;
use crate::arrays::ListViewArray;
use crate::arrays::dict::TakeExecute;
use crate::arrays::dict::TakeReduce;
use crate::arrays::listview::ListViewArrayExt;
use crate::arrays::listview::ListViewRebuildMode;
use crate::builtins::ArrayBuiltins;
use crate::dtype::Nullability;
use crate::match_each_integer_ptype;
use crate::scalar::Scalar;
impl TakeReduce for ListView {
fn take(array: ArrayView<'_, ListView>, indices: &ArrayRef) -> VortexResult<Option<ArrayRef>> {
let kept_row_fraction = indices.len() as f32 / array.sizes().len() as f32;
if kept_row_fraction < REBUILD_DENSITY_THRESHOLD {
return Ok(None);
}
Ok(Some(apply_take(array, indices)?.into_array()))
}
}
impl TakeExecute for ListView {
fn take(
array: ArrayView<'_, ListView>,
indices: &ArrayRef,
_ctx: &mut ExecutionCtx,
) -> VortexResult<Option<ArrayRef>> {
let kept_row_fraction = indices.len() as f32 / array.sizes().len() as f32;
let taken = apply_take(array, indices)?;
if kept_row_fraction < REBUILD_DENSITY_THRESHOLD {
Ok(Some(
taken
.rebuild(ListViewRebuildMode::MakeZeroCopyToList)?
.into_array(),
))
} else {
Ok(Some(taken.into_array()))
}
}
}
fn apply_take(array: ArrayView<'_, ListView>, indices: &ArrayRef) -> VortexResult<ListViewArray> {
let elements = array.elements();
let offsets = array.offsets();
let sizes = array.sizes();
let new_validity = array.validity()?.take(indices)?;
let nullable_new_offsets = offsets.take(indices.clone())?;
let nullable_new_sizes = sizes.take(indices.clone())?;
let new_offsets = match_each_integer_ptype!(nullable_new_offsets.dtype().as_ptype(), |O| {
nullable_new_offsets.fill_null(Scalar::primitive(O::zero(), Nullability::NonNullable))?
});
let new_sizes = match_each_integer_ptype!(nullable_new_sizes.dtype().as_ptype(), |S| {
nullable_new_sizes.fill_null(Scalar::primitive(S::zero(), Nullability::NonNullable))?
});
Ok(unsafe {
ListViewArray::new_unchecked(elements.clone(), new_offsets, new_sizes, new_validity)
})
}