@@ -3,19 +3,25 @@ use std::sync::Arc;
33use arrow_array:: cast:: AsArray ;
44use arrow_array:: types:: ByteViewType ;
55use arrow_array:: { Datum , GenericByteViewArray } ;
6+ use arrow_buffer:: ScalarBuffer ;
67use arrow_ord:: cmp;
78use arrow_schema:: DataType ;
9+ use itertools:: Itertools ;
10+ use num_traits:: AsPrimitive ;
811use vortex_buffer:: Buffer ;
12+ use vortex_dtype:: { match_each_integer_ptype, PType } ;
913use vortex_error:: { vortex_bail, VortexResult , VortexUnwrap } ;
1014use vortex_scalar:: Scalar ;
1115
1216use crate :: array:: varbin:: varbin_scalar;
1317use crate :: array:: varbinview:: { VarBinViewArray , VIEW_SIZE_BYTES } ;
14- use crate :: array:: { varbinview_as_arrow , ConstantArray } ;
18+ use crate :: array:: { ConstantArray , PrimitiveArray } ;
1519use crate :: arrow:: FromArrowArray ;
1620use crate :: compute:: unary:: ScalarAtFn ;
1721use crate :: compute:: { slice, ArrayCompute , MaybeCompareFn , Operator , SliceFn , TakeFn , TakeOptions } ;
18- use crate :: { ArrayDType , ArrayData , IntoArrayData , IntoCanonical } ;
22+ use crate :: validity:: Validity ;
23+ use crate :: variants:: PrimitiveArrayTrait ;
24+ use crate :: { ArrayDType , ArrayData , IntoArrayData , IntoArrayVariant , IntoCanonical } ;
1925
2026impl ArrayCompute for VarBinViewArray {
2127 fn compare ( & self , other : & ArrayData , operator : Operator ) -> Option < VortexResult < ArrayData > > {
@@ -67,23 +73,58 @@ impl SliceFn for VarBinViewArray {
6773/// Take involves creating a new array that references the old array, just with the given set of views.
6874impl TakeFn for VarBinViewArray {
6975 fn take ( & self , indices : & ArrayData , options : TakeOptions ) -> VortexResult < ArrayData > {
70- let array_ref = varbinview_as_arrow ( self ) ;
71- let indices_arrow = indices. clone ( ) . into_canonical ( ) ?. into_arrow ( ) ?;
72-
73- let take_arrow = arrow_select:: take:: take (
74- & array_ref,
75- & indices_arrow,
76- Some ( arrow_select:: take:: TakeOptions {
77- check_bounds : !options. skip_bounds_check ,
78- } ) ,
79- ) ?;
80- Ok ( ArrayData :: from_arrow (
81- take_arrow,
82- self . dtype ( ) . is_nullable ( ) ,
83- ) )
76+ // Compute the new validity
77+ let validity = self . validity ( ) . take ( indices, options) ?;
78+
79+ // Convert our views array into an Arrow u128 ScalarBuffer (16 bytes per view)
80+ let views_buffer =
81+ ScalarBuffer :: < u128 > :: from ( self . views ( ) . into_primitive ( ) ?. into_buffer ( ) . into_arrow ( ) ) ;
82+
83+ let indices = indices. clone ( ) . into_primitive ( ) ?;
84+
85+ let views_buffer = match_each_integer_ptype ! ( indices. ptype( ) , |$I | {
86+ if options. skip_bounds_check {
87+ take_views_unchecked( views_buffer, indices. maybe_null_slice:: <$I >( ) )
88+ } else {
89+ take_views( views_buffer, indices. maybe_null_slice:: <$I >( ) )
90+ }
91+ } ) ;
92+
93+ // Cast views back to u8
94+ let views_array = PrimitiveArray :: new (
95+ views_buffer. into_inner ( ) . into ( ) ,
96+ PType :: U8 ,
97+ Validity :: NonNullable ,
98+ ) ;
99+
100+ Ok ( Self :: try_new (
101+ views_array. into_array ( ) ,
102+ self . buffers ( ) . collect_vec ( ) ,
103+ self . dtype ( ) . clone ( ) ,
104+ validity,
105+ ) ?
106+ . into_array ( ) )
84107 }
85108}
86109
110+ fn take_views < I : AsPrimitive < usize > > (
111+ views : ScalarBuffer < u128 > ,
112+ indices : & [ I ] ,
113+ ) -> ScalarBuffer < u128 > {
114+ ScalarBuffer :: < u128 > :: from_iter ( indices. iter ( ) . map ( |i| views[ i. as_ ( ) ] ) )
115+ }
116+
117+ fn take_views_unchecked < I : AsPrimitive < usize > > (
118+ views : ScalarBuffer < u128 > ,
119+ indices : & [ I ] ,
120+ ) -> ScalarBuffer < u128 > {
121+ ScalarBuffer :: < u128 > :: from_iter (
122+ indices
123+ . iter ( )
124+ . map ( |i| unsafe { * views. get_unchecked ( i. as_ ( ) ) } ) ,
125+ )
126+ }
127+
87128impl MaybeCompareFn for VarBinViewArray {
88129 fn maybe_compare (
89130 & self ,
0 commit comments