11// SPDX-License-Identifier: Apache-2.0
22// SPDX-FileCopyrightText: Copyright the Vortex contributors
33
4- use vortex_buffer:: Buffer ;
4+ use vortex_buffer:: { BitBuffer , Buffer } ;
55use vortex_compute:: filter:: Filter ;
6- use vortex_dtype:: { match_each_native_ptype , NativePType , PTypeDowncastExt } ;
6+ use vortex_dtype:: { NativePType , PTypeDowncastExt , match_each_native_ptype } ;
77use vortex_error:: VortexResult ;
8- use vortex_mask:: Mask ;
98use vortex_vector:: primitive:: PVector ;
109use vortex_vector:: { VectorMut , VectorMutOps } ;
1110
1211use crate :: arrays:: { MaskedVTable , PrimitiveArray , PrimitiveVTable } ;
13- use crate :: execution:: { kernel, BatchKernelRef , BindCtx } ;
14- use crate :: pipeline:: bit_view:: BitView ;
15- use crate :: pipeline:: { BindContext , KernelContext , PipelinedSource , SourceKernel , N } ;
12+ use crate :: execution:: { BatchKernelRef , BindCtx , kernel} ;
13+ use crate :: pipeline:: bit_view:: { BitSlice , BitView } ;
14+ use crate :: pipeline:: {
15+ AllNullSourceKernel , BindContext , KernelContext , N , PipelinedSource , SourceKernel ,
16+ } ;
17+ use crate :: validity:: Validity ;
1618use crate :: vtable:: { OperatorVTable , ValidityHelper } ;
1719use crate :: { ArrayRef , IntoArray } ;
1820
@@ -71,25 +73,81 @@ impl OperatorVTable<PrimitiveVTable> for PrimitiveVTable {
7173}
7274
7375impl PipelinedSource for PrimitiveArray {
74- fn bind_source ( & self , _ctx : & mut dyn BindContext ) -> VortexResult < Box < dyn SourceKernel > > {
75- match_each_native_ptype ! ( self . ptype( ) , |T | {
76- let primitive_kernel = PrimitiveKernel {
77- buffer: self . buffer:: <T >( ) . clone( ) ,
78- validity: self . validity_mask( ) ,
79- offset: 0 ,
80- } ;
81- Ok ( Box :: new( primitive_kernel) )
82- } )
76+ fn bind_source ( & self , ctx : & mut dyn BindContext ) -> VortexResult < Box < dyn SourceKernel > > {
77+ match self . validity ( ) {
78+ Validity :: NonNullable | Validity :: AllValid => {
79+ match_each_native_ptype ! ( self . ptype( ) , |T | {
80+ let primitive_kernel = NonNullablePrimitiveKernel {
81+ buffer: self . buffer:: <T >( ) ,
82+ offset: 0 ,
83+ } ;
84+ Ok ( Box :: new( primitive_kernel) )
85+ } )
86+ }
87+ Validity :: AllInvalid => Ok ( Box :: new ( AllNullSourceKernel ) ) ,
88+ Validity :: Array ( _) => {
89+ let validity = ctx. batch_input ( 0 ) . into_bool ( ) ;
90+ // Validity is non-nullable, so we extract the inner bit buffer.
91+ let ( validity, _) = validity. into_parts ( ) ;
92+
93+ match_each_native_ptype ! ( self . ptype( ) , |T | {
94+ let primitive_kernel = NullablePrimitiveKernel {
95+ buffer: self . buffer:: <T >( ) ,
96+ validity,
97+ offset: 0 ,
98+ } ;
99+ Ok ( Box :: new( primitive_kernel) )
100+ } )
101+ }
102+ }
103+ }
104+ }
105+
106+ struct NonNullablePrimitiveKernel < T : NativePType > {
107+ buffer : Buffer < T > ,
108+ offset : usize ,
109+ }
110+
111+ impl < T : NativePType > SourceKernel for NonNullablePrimitiveKernel < T > {
112+ fn skip ( & mut self , n : usize ) {
113+ self . offset += n * N ;
114+ }
115+
116+ fn step (
117+ & mut self ,
118+ _ctx : & KernelContext ,
119+ selection : & BitView ,
120+ out : & mut VectorMut ,
121+ ) -> VortexResult < ( ) > {
122+ let out = out. as_primitive_mut ( ) . downcast :: < T > ( ) ;
123+
124+ // SAFETY: we know the output has sufficient capacity.
125+ unsafe {
126+ out. validity_mut ( ) . append_n ( true , selection. true_count ( ) ) ;
127+ let prev_len = out. len ( ) ;
128+ out. elements_mut ( )
129+ . set_len ( prev_len + selection. true_count ( ) ) ;
130+ }
131+
132+ let source = & self . buffer . as_slice ( ) [ self . offset ..] ;
133+ let mut out_pos = 0 ;
134+ selection. iter_slices ( |BitSlice { start, len } | {
135+ out. as_mut ( ) [ out_pos..] [ ..len] . copy_from_slice ( & source[ start..] [ ..len] ) ;
136+ out_pos += len;
137+ } ) ;
138+
139+ Ok ( ( ) )
83140 }
84141}
85142
86- struct PrimitiveKernel < T : NativePType > {
143+ struct NullablePrimitiveKernel < T : NativePType > {
87144 buffer : Buffer < T > ,
88- validity : Mask ,
145+ #[ allow( dead_code) ] // TODO(ngates): implement appending validity bits
146+ validity : BitBuffer ,
89147 offset : usize ,
90148}
91149
92- impl < T : NativePType > SourceKernel for PrimitiveKernel < T > {
150+ impl < T : NativePType > SourceKernel for NullablePrimitiveKernel < T > {
93151 fn skip ( & mut self , n : usize ) {
94152 self . offset += n * N ;
95153 }
@@ -114,9 +172,14 @@ impl<T: NativePType> SourceKernel for PrimitiveKernel<T> {
114172 let source = & self . buffer . as_slice ( ) [ self . offset ..] ;
115173
116174 let mut out_pos = 0 ;
117- selection. iter_slices ( |( start, len) | {
175+ selection. iter_slices ( |BitSlice { start, len } | {
176+ // Copy over the elements.
118177 out. as_mut ( ) [ out_pos..] [ ..len] . copy_from_slice ( & source[ start..] [ ..len] ) ;
119178 out_pos += len;
179+
180+ // Append the validity bits.
181+ let _validity = unsafe { out. validity_mut ( ) } ;
182+ todo ! ( "Append validity bits correctly and optimally!" ) ;
120183 } ) ;
121184
122185 Ok ( ( ) )
0 commit comments