vortex_array/arrays/listview/vtable/operations.rs
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use std::ops::Range;
5use std::sync::Arc;
6
7use vortex_scalar::Scalar;
8
9use crate::arrays::{ListViewArray, ListViewVTable};
10use crate::vtable::{OperationsVTable, ValidityHelper};
11use crate::{ArrayRef, IntoArray};
12
13impl OperationsVTable<ListViewVTable> for ListViewVTable {
14 fn slice(array: &ListViewArray, range: Range<usize>) -> ArrayRef {
15 let start = range.start;
16 let end = range.end;
17
18 // We implement slice by simply slicing the views. We leave the child `elements` array alone
19 // since slicing could potentially require calculating which elements are referenced by the
20 // new set of views.
21
22 // SAFETY: The preconditions of `slice` mean that the bounds have already been checked, and
23 // slicing the components of an existing valid array is still valid.
24 // Additionally, slicing elements of a `ListViewArray` that is already zero-copyable to a
25 // `ListArray` does not reorder or create gaps and overlaps, slicing maintains whatever
26 // `is_zero_copy_to_list` flag it already had.
27 unsafe {
28 ListViewArray::new_unchecked(
29 array.elements().clone(),
30 array.offsets().slice(start..end),
31 array.sizes().slice(start..end),
32 array.validity().slice(start..end),
33 )
34 .with_zero_copy_to_list(array.is_zero_copy_to_list())
35 }
36 .into_array()
37 }
38
39 fn scalar_at(array: &ListViewArray, index: usize) -> Scalar {
40 // By the preconditions we know that the list scalar is not null.
41 let list = array.list_elements_at(index);
42 let children: Vec<Scalar> = (0..list.len()).map(|i| list.scalar_at(i)).collect();
43
44 Scalar::list(
45 Arc::new(list.dtype().clone()),
46 children,
47 array.dtype.nullability(),
48 )
49 }
50}