@@ -52,7 +52,6 @@ use vortex_array::scalar_fn::fns::operators::Operator;
5252use vortex_array:: search_sorted:: SearchSorted ;
5353use vortex_array:: search_sorted:: SearchSortedSide ;
5454use vortex_array:: stream:: ArrayStreamExt ;
55- use vortex_array:: stream:: SendableArrayStream ;
5655use vortex_array:: validity:: Validity ;
5756use vortex_buffer:: ByteBufferMut ;
5857use vortex_edition:: Edition ;
@@ -117,10 +116,10 @@ impl ReverseIndex {
117116 }
118117}
119118
120- /// One decoded chunk of the index: its sorted keys and their serialized posting lists .
119+ /// A run of index entries: sorted, distinct, non-null keys and the rows holding each .
121120pub struct Entries {
122121 keys : ArrayRef ,
123- postings : VarBinViewArray ,
122+ postings : Vec < RoaringBitmap > ,
124123}
125124
126125impl IndexVTable for ReverseIndex {
@@ -135,6 +134,10 @@ impl IndexVTable for ReverseIndex {
135134 * ID
136135 }
137136
137+ fn serialize_options ( & self , _options : & ( ) ) -> Vec < u8 > {
138+ vec ! [ ]
139+ }
140+
138141 fn deserialize_options ( & self , _options : & [ u8 ] ) -> VortexResult < ( ) > {
139142 Ok ( ( ) )
140143 }
@@ -200,23 +203,57 @@ impl IndexVTable for ReverseIndex {
200203 } ) )
201204 }
202205
206+ fn encode (
207+ & self ,
208+ chunk : & Entries ,
209+ _options : & ( ) ,
210+ _ctx : & mut ExecutionCtx ,
211+ ) -> VortexResult < ArrayRef > {
212+ let mut lists = Vec :: with_capacity ( chunk. postings . len ( ) ) ;
213+ for bitmap in & chunk. postings {
214+ let mut buffer = Vec :: with_capacity ( bitmap. serialized_size ( ) ) ;
215+ bitmap
216+ . serialize_into ( & mut buffer)
217+ . map_err ( |err| vortex_err ! ( "Failed to serialize postings: {err}" ) ) ?;
218+ lists. push ( buffer) ;
219+ }
220+
221+ Ok ( StructArray :: try_new_with_dtype (
222+ vec ! [
223+ chunk. keys. clone( ) ,
224+ VarBinViewArray :: from_iter_bin( lists) . into_array( ) ,
225+ ] ,
226+ index_fields ( chunk. keys . dtype ( ) . clone ( ) ) ,
227+ chunk. keys . len ( ) ,
228+ Validity :: NonNullable ,
229+ ) ?
230+ . into_array ( ) )
231+ }
232+
203233 fn decode (
204234 & self ,
205235 chunk : ArrayRef ,
206236 _options : & ( ) ,
207237 ctx : & mut ExecutionCtx ,
208238 ) -> VortexResult < Entries > {
209239 let entries = chunk. execute :: < StructArray > ( ctx) ?;
240+ let lists = entries
241+ . unmasked_field_by_name ( POSTINGS_FIELD ) ?
242+ . clone ( )
243+ . execute :: < VarBinViewArray > ( ctx) ?;
244+ let postings = ( 0 ..lists. len ( ) )
245+ . map ( |idx| {
246+ RoaringBitmap :: deserialize_from ( lists. bytes_at ( idx) . as_slice ( ) )
247+ . map_err ( |err| vortex_err ! ( "Failed to deserialize postings: {err}" ) )
248+ } )
249+ . collect :: < VortexResult < _ > > ( ) ?;
210250 Ok ( Entries {
211251 keys : entries
212252 . unmasked_field_by_name ( KEY_FIELD ) ?
213253 . clone ( )
214254 . execute :: < Canonical > ( ctx) ?
215255 . into_array ( ) ,
216- postings : entries
217- . unmasked_field_by_name ( POSTINGS_FIELD ) ?
218- . clone ( )
219- . execute :: < VarBinViewArray > ( ctx) ?,
256+ postings,
220257 } )
221258 }
222259
@@ -229,16 +266,13 @@ impl IndexVTable for ReverseIndex {
229266 ) -> VortexResult < RowLocator > {
230267 // Keys are unique and sorted across the partition, so at most one chunk holds the target.
231268 for chunk in chunks {
232- let Some ( idx) = chunk
269+ if let Some ( idx) = chunk
233270 . keys
234271 . search_sorted ( target, SearchSortedSide :: Left ) ?
235272 . to_found ( )
236- else {
237- continue ;
238- } ;
239- let bitmap = RoaringBitmap :: deserialize_from ( chunk. postings . bytes_at ( idx) . as_slice ( ) )
240- . map_err ( |err| vortex_err ! ( "Failed to deserialize postings: {err}" ) ) ?;
241- return Ok ( RowLocator :: Rows ( bitmap) ) ;
273+ {
274+ return Ok ( RowLocator :: Rows ( chunk. postings [ idx] . clone ( ) ) ) ;
275+ }
242276 }
243277 Ok ( RowLocator :: empty_rows ( ) )
244278 }
@@ -258,6 +292,9 @@ pub struct Builder {
258292}
259293
260294impl IndexBuilder for Builder {
295+ type Options = ( ) ;
296+ type Chunk = Entries ;
297+
261298 fn push (
262299 & mut self ,
263300 chunk : & ArrayRef ,
@@ -277,12 +314,12 @@ impl IndexBuilder for Builder {
277314 Ok ( ( ) )
278315 }
279316
280- fn finish ( self : Box < Self > ) -> VortexResult < Option < ( SendableArrayStream , Vec < u8 > ) > > {
317+ fn finish ( self ) -> VortexResult < Option < ( Vec < Entries > , ( ) ) > > {
281318 let Builder {
282319 dtype,
283320 postings,
284321 allocator,
285- } = * self ;
322+ } = self ;
286323
287324 let mut entries: Vec < ( Scalar , RoaringBitmap ) > = postings. into_iter ( ) . collect ( ) ;
288325 entries. sort_by ( |( a, _) , ( b, _) | {
@@ -291,31 +328,22 @@ impl IndexBuilder for Builder {
291328 } ) ;
292329
293330 let key_dtype = dtype. as_nonnullable ( ) ;
294- let mut key_builder = builder_with_capacity_in ( & key_dtype, entries. len ( ) , & allocator) ;
295- let mut lists = Vec :: with_capacity ( entries. len ( ) ) ;
296- for ( key, bitmap) in & entries {
331+ let mut keys = builder_with_capacity_in ( & key_dtype, entries. len ( ) , & allocator) ;
332+ let mut bitmaps = Vec :: with_capacity ( entries. len ( ) ) ;
333+ for ( key, bitmap) in entries {
297334 // Keys are never null (`push` skips them), but may carry the source column's nullable
298335 // dtype; the key column itself is non-nullable, so normalize before appending.
299- key_builder. append_scalar ( & key. cast ( & key_dtype) ?) ?;
300- let mut buffer = Vec :: with_capacity ( bitmap. serialized_size ( ) ) ;
301- bitmap
302- . serialize_into ( & mut buffer)
303- . map_err ( |err| vortex_err ! ( "Failed to serialize postings: {err}" ) ) ?;
304- lists. push ( buffer) ;
336+ keys. append_scalar ( & key. cast ( & key_dtype) ?) ?;
337+ bitmaps. push ( bitmap) ;
305338 }
306339
307- let len = entries. len ( ) ;
308- let array = StructArray :: try_new_with_dtype (
309- vec ! [
310- key_builder. finish( ) ,
311- VarBinViewArray :: from_iter_bin( lists) . into_array( ) ,
312- ] ,
313- index_fields ( key_dtype) ,
314- len,
315- Validity :: NonNullable ,
316- ) ?;
317-
318- Ok ( Some ( ( array. into_array ( ) . to_array_stream ( ) . boxed ( ) , vec ! [ ] ) ) )
340+ Ok ( Some ( (
341+ vec ! [ Entries {
342+ keys: keys. finish( ) ,
343+ postings: bitmaps,
344+ } ] ,
345+ ( ) ,
346+ ) ) )
319347 }
320348
321349 fn buffered_bytes ( & self ) -> u64 {
0 commit comments