vortex_array/arrays/varbinview/compute/
take.rs1use std::ops::Deref;
2
3use num_traits::AsPrimitive;
4use vortex_buffer::Buffer;
5use vortex_dtype::match_each_integer_ptype;
6use vortex_error::VortexResult;
7
8use crate::arrays::{BinaryView, VarBinViewArray, VarBinViewVTable};
9use crate::compute::{TakeKernel, TakeKernelAdapter};
10use crate::vtable::ValidityHelper;
11use crate::{Array, ArrayRef, IntoArray, ToCanonical, register_kernel};
12
13impl TakeKernel for VarBinViewVTable {
15 fn take(&self, array: &VarBinViewArray, indices: &dyn Array) -> VortexResult<ArrayRef> {
16 let validity = array.validity().take(indices)?;
21 let indices = indices.to_primitive()?;
22
23 let views_buffer = match_each_integer_ptype!(indices.ptype(), |$I| {
24 take_views(array.views(), indices.as_slice::<$I>())
26 });
27
28 Ok(VarBinViewArray::try_new(
29 views_buffer,
30 array.buffers().to_vec(),
31 array
32 .dtype()
33 .union_nullability(indices.dtype().nullability()),
34 validity,
35 )?
36 .into_array())
37 }
38}
39
40register_kernel!(TakeKernelAdapter(VarBinViewVTable).lift());
41
42fn take_views<I: AsPrimitive<usize>>(
43 views: &Buffer<BinaryView>,
44 indices: &[I],
45) -> Buffer<BinaryView> {
46 let views_ref = views.deref();
48 Buffer::<BinaryView>::from_iter(indices.iter().map(|i| views_ref[i.as_()]))
49}
50
51#[cfg(test)]
52mod tests {
53 use vortex_buffer::buffer;
54
55 use crate::IntoArray;
56 use crate::accessor::ArrayAccessor;
57 use crate::array::Array;
58 use crate::arrays::VarBinViewArray;
59 use crate::canonical::ToCanonical;
60 use crate::compute::take;
61
62 #[test]
63 fn take_nullable() {
64 let arr = VarBinViewArray::from_iter_nullable_str([
65 Some("one"),
66 None,
67 Some("three"),
68 Some("four"),
69 None,
70 Some("six"),
71 ]);
72
73 let taken = take(arr.as_ref(), &buffer![0, 3].into_array()).unwrap();
74
75 assert!(taken.dtype().is_nullable());
76 assert_eq!(
77 taken
78 .to_varbinview()
79 .unwrap()
80 .with_iterator(|it| it
81 .map(|v| v.map(|b| unsafe { String::from_utf8_unchecked(b.to_vec()) }))
82 .collect::<Vec<_>>())
83 .unwrap(),
84 [Some("one".to_string()), Some("four".to_string())]
85 );
86 }
87}