@@ -5,10 +5,10 @@ use std::marker::PhantomData;
55use std:: sync:: Arc ;
66
77use num_traits:: ToPrimitive ;
8- use vortex_buffer:: { Buffer , BufferMut , ByteBuffer } ;
9- use vortex_compute:: filter:: Filter ;
10- use vortex_dtype:: { DType , PTypeDowncastExt , match_each_integer_ptype} ;
8+ use vortex_buffer:: { Buffer , ByteBuffer } ;
9+ use vortex_dtype:: { DType , IntegerPType , PTypeDowncastExt , match_each_integer_ptype} ;
1110use vortex_error:: { VortexExpect , VortexResult , vortex_ensure} ;
11+ use vortex_mask:: Mask ;
1212use vortex_vector:: Vector ;
1313use vortex_vector:: binaryview:: {
1414 BinaryType , BinaryView , BinaryViewType , BinaryViewVector , StringType ,
@@ -95,23 +95,17 @@ impl<V: BinaryViewType> BatchKernel for VarBinKernel<V> {
9595 } )
9696 . collect( ) ;
9797
98- let mut views = BufferMut :: with_capacity( lens. len( ) ) ;
99-
100- for ( offset, len) in std:: iter:: zip( offsets, lens) {
101- let offset = offset. to_u32( ) . vortex_expect( "offset must fit in u32" ) ;
102- let bytes = & self . bytes[ offset as usize ..( offset + len) as usize ] ;
103- let view = if len as usize <= BinaryView :: MAX_INLINED_SIZE {
104- BinaryView :: new_inlined( bytes)
105- } else {
106- BinaryView :: make_view( bytes, 0 , offset)
107- } ;
108- views. push( view) ;
109- }
110-
11198 let selection = self . selection. execute( ) ?;
112- let validity = self . validity. execute( ) ?;
11399
114- let views = views. freeze( ) . filter( & selection) ;
100+ let views = match selection {
101+ Mask :: AllFalse ( _) => Buffer :: empty( ) ,
102+ Mask :: AllTrue ( _) => make_views:: <T >( offsets. as_ref( ) , lens, & self . bytes) ,
103+ Mask :: Values ( values) => {
104+ make_views_filtered:: <T >( offsets. as_ref( ) , lens, values. indices( ) , & self . bytes)
105+ }
106+ } ;
107+
108+ let validity = self . validity. execute( ) ?;
115109
116110 vortex_ensure!(
117111 validity. len( ) == views. len( ) ,
@@ -131,6 +125,50 @@ impl<V: BinaryViewType> BatchKernel for VarBinKernel<V> {
131125 }
132126}
133127
128+ // Returns a set of views
129+ fn make_views < OffsetType : IntegerPType > (
130+ offsets : & [ OffsetType ] ,
131+ lens : Buffer < u32 > ,
132+ bytes : & [ u8 ] ,
133+ ) -> Buffer < BinaryView > {
134+ std:: iter:: zip ( offsets, lens)
135+ . map ( |( offset, len) | {
136+ let offset = offset. to_u32 ( ) . vortex_expect ( "offset must fit in u32" ) ;
137+ let bytes = & bytes[ offset as usize ..( offset + len) as usize ] ;
138+ if len as usize <= BinaryView :: MAX_INLINED_SIZE {
139+ BinaryView :: new_inlined ( bytes)
140+ } else {
141+ BinaryView :: make_view ( bytes, 0 , offset)
142+ }
143+ } )
144+ . collect ( )
145+ }
146+
147+ /// Only make views for values at the given `indices`
148+ fn make_views_filtered < OffsetType : IntegerPType > (
149+ offsets : & [ OffsetType ] ,
150+ lens : Buffer < u32 > ,
151+ indices : & [ usize ] ,
152+ bytes : & [ u8 ] ,
153+ ) -> Buffer < BinaryView > {
154+ indices
155+ . iter ( )
156+ . copied ( )
157+ . map ( |index| {
158+ let offset = offsets[ index]
159+ . to_u32 ( )
160+ . vortex_expect ( "offset must fit in u32" ) ;
161+ let len = lens[ index] ;
162+ let bytes = & bytes[ offset as usize ..( offset + len) as usize ] ;
163+ if len as usize <= BinaryView :: MAX_INLINED_SIZE {
164+ BinaryView :: new_inlined ( bytes)
165+ } else {
166+ BinaryView :: make_view ( bytes, 0 , offset)
167+ }
168+ } )
169+ . collect ( )
170+ }
171+
134172#[ cfg( test) ]
135173mod tests {
136174 use rstest:: { fixture, rstest} ;
0 commit comments