vortex_array/arrays/listview/compute/
take.rs1use num_traits::Zero;
5use vortex_error::VortexResult;
6
7use super::REBUILD_DENSITY_THRESHOLD;
8use crate::ArrayRef;
9use crate::ExecutionCtx;
10use crate::IntoArray;
11use crate::array::ArrayView;
12use crate::arrays::ListView;
13use crate::arrays::ListViewArray;
14use crate::arrays::dict::TakeExecute;
15use crate::arrays::dict::TakeReduce;
16use crate::arrays::listview::ListViewArrayExt;
17use crate::arrays::listview::ListViewRebuildMode;
18use crate::builtins::ArrayBuiltins;
19use crate::dtype::Nullability;
20use crate::match_each_integer_ptype;
21use crate::scalar::Scalar;
22
23impl TakeReduce for ListView {
25 fn take(array: ArrayView<'_, ListView>, indices: &ArrayRef) -> VortexResult<Option<ArrayRef>> {
26 let kept_row_fraction = indices.len() as f32 / array.sizes().len() as f32;
30 if kept_row_fraction < REBUILD_DENSITY_THRESHOLD {
31 return Ok(None);
32 }
33
34 Ok(Some(apply_take(array, indices)?.into_array()))
35 }
36}
37
38impl TakeExecute for ListView {
43 fn take(
44 array: ArrayView<'_, ListView>,
45 indices: &ArrayRef,
46 _ctx: &mut ExecutionCtx,
47 ) -> VortexResult<Option<ArrayRef>> {
48 let kept_row_fraction = indices.len() as f32 / array.sizes().len() as f32;
49 let taken = apply_take(array, indices)?;
50
51 if kept_row_fraction < REBUILD_DENSITY_THRESHOLD {
52 Ok(Some(
56 taken
57 .rebuild(ListViewRebuildMode::MakeZeroCopyToList)?
58 .into_array(),
59 ))
60 } else {
61 Ok(Some(taken.into_array()))
62 }
63 }
64}
65
66fn apply_take(array: ArrayView<'_, ListView>, indices: &ArrayRef) -> VortexResult<ListViewArray> {
69 let elements = array.elements();
70 let offsets = array.offsets();
71 let sizes = array.sizes();
72
73 let new_validity = array.validity()?.take(indices)?;
75
76 let nullable_new_offsets = offsets.take(indices.clone())?;
79 let nullable_new_sizes = sizes.take(indices.clone())?;
80
81 let new_offsets = match_each_integer_ptype!(nullable_new_offsets.dtype().as_ptype(), |O| {
84 nullable_new_offsets.fill_null(Scalar::primitive(O::zero(), Nullability::NonNullable))?
85 });
86 let new_sizes = match_each_integer_ptype!(nullable_new_sizes.dtype().as_ptype(), |S| {
87 nullable_new_sizes.fill_null(Scalar::primitive(S::zero(), Nullability::NonNullable))?
88 });
89
90 Ok(unsafe {
96 ListViewArray::new_unchecked(elements.clone(), new_offsets, new_sizes, new_validity)
97 })
98}