@@ -40,20 +40,11 @@ pub(super) fn canonicalize_fsst(
4040 } )
4141}
4242
43- pub ( crate ) fn fsst_decode_views (
43+ pub ( crate ) fn fsst_decode_bytes (
4444 fsst_array : ArrayView < ' _ , FSST > ,
45- start_buf_index : u32 ,
4645 ctx : & mut ExecutionCtx ,
47- ) -> VortexResult < ( Vec < ByteBuffer > , Buffer < BinaryView > ) > {
48- // FSSTArray has two child arrays:
49- // 1. A VarBinArray, which holds the string heap of the compressed codes.
50- // 2. An uncompressed_lengths primitive array, storing the length of each original
51- // string element.
52- // To speed up canonicalization, we can decompress the entire string-heap in a single
53- // call. We then turn our uncompressed_lengths into an offsets buffer
54- // necessary for a VarBinViewArray and construct the canonical array.
46+ ) -> VortexResult < ( ByteBufferMut , PrimitiveArray ) > {
5547 let bytes = fsst_array. codes ( ) . sliced_bytes ( ) ;
56-
5748 let uncompressed_lens_array = fsst_array
5849 . uncompressed_lengths ( )
5950 . clone ( )
@@ -68,14 +59,20 @@ pub(crate) fn fsst_decode_views(
6859 . sum( )
6960 } ) ;
7061
71- // Bulk-decompress the entire array.
7262 let decompressor = fsst_array. decompressor ( ) ;
7363 let mut uncompressed_bytes = ByteBufferMut :: with_capacity ( total_size + 7 ) ;
7464 let len =
7565 decompressor. decompress_into ( bytes. as_slice ( ) , uncompressed_bytes. spare_capacity_mut ( ) ) ;
7666 unsafe { uncompressed_bytes. set_len ( len) } ;
67+ Ok ( ( uncompressed_bytes, uncompressed_lens_array) )
68+ }
7769
78- // Directly create the binary views.
70+ pub ( crate ) fn fsst_decode_views (
71+ fsst_array : ArrayView < ' _ , FSST > ,
72+ start_buf_index : u32 ,
73+ ctx : & mut ExecutionCtx ,
74+ ) -> VortexResult < ( Vec < ByteBuffer > , Buffer < BinaryView > ) > {
75+ let ( uncompressed_bytes, uncompressed_lens_array) = fsst_decode_bytes ( fsst_array, ctx) ?;
7976 match_each_integer_ptype ! ( uncompressed_lens_array. ptype( ) , |P | {
8077 Ok ( build_views(
8178 start_buf_index,
@@ -99,7 +96,9 @@ mod tests {
9996 use vortex_array:: arrays:: ChunkedArray ;
10097 use vortex_array:: arrays:: VarBinArray ;
10198 use vortex_array:: arrays:: VarBinViewArray ;
99+ use vortex_array:: arrays:: varbin:: VarBinArrayExt ;
102100 use vortex_array:: builders:: ArrayBuilder ;
101+ use vortex_array:: builders:: OffsetVarBinBuilder ;
103102 use vortex_array:: builders:: VarBinViewBuilder ;
104103 use vortex_array:: dtype:: DType ;
105104 use vortex_array:: dtype:: Nullability ;
@@ -199,6 +198,20 @@ mod tests {
199198 . collect :: < Vec < _ > > ( ) ;
200199 assert_eq ! ( data, res2)
201200 } ;
201+
202+ {
203+ let mut builder =
204+ OffsetVarBinBuilder :: with_capacity ( chunked_arr. dtype ( ) . clone ( ) , false , data. len ( ) ) ;
205+ chunked_arr
206+ . into_array ( )
207+ . append_to_builder ( & mut builder, & mut ctx) ?;
208+ let arr = builder. finish_into_varbin ( ) ;
209+ let mask = arr. validity ( ) ?. execute_mask ( arr. len ( ) , & mut ctx) ?;
210+ let actual = ( 0 ..arr. len ( ) )
211+ . map ( |i| mask. value ( i) . then ( || arr. bytes_at ( i) . to_vec ( ) ) )
212+ . collect :: < Vec < _ > > ( ) ;
213+ assert_eq ! ( data, actual) ;
214+ }
202215 Ok ( ( ) )
203216 }
204217
0 commit comments