@@ -161,20 +161,10 @@ impl VTable for BitPacked {
161161 }
162162
163163 fn serialize (
164- array : ArrayView < ' _ , Self > ,
164+ _array : ArrayView < ' _ , Self > ,
165165 _session : & VortexSession ,
166166 ) -> VortexResult < Option < Vec < u8 > > > {
167- Ok ( Some (
168- BitPackedMetadata {
169- bit_width : array. bit_width ( ) as u32 ,
170- offset : array. offset ( ) as u32 ,
171- patches : array
172- . patches ( )
173- . map ( |p| p. to_metadata ( array. len ( ) , array. dtype ( ) ) )
174- . transpose ( ) ?,
175- }
176- . encode_to_vec ( ) ,
177- ) )
167+ vortex_bail ! ( "BitPacked serialization requires BitPackedPlugin" )
178168 }
179169
180170 fn deserialize (
@@ -187,71 +177,24 @@ impl VTable for BitPacked {
187177 _session : & VortexSession ,
188178 ) -> VortexResult < ArrayParts < Self > > {
189179 let metadata = BitPackedMetadata :: decode ( metadata) ?;
190- if buffers. len ( ) != 1 {
191- vortex_bail ! ( "Expected 1 buffer, got {}" , buffers. len( ) ) ;
192- }
193- let packed = buffers[ 0 ] . clone ( ) ;
194-
195- let load_validity = |child_idx : usize | {
196- if children. len ( ) == child_idx {
197- Ok ( Validity :: from ( dtype. nullability ( ) ) )
198- } else if children. len ( ) == child_idx + 1 {
199- let validity = children. get ( child_idx, & Validity :: DTYPE , len) ?;
200- Ok ( Validity :: Array ( validity) )
201- } else {
202- vortex_bail ! (
203- "Expected {} or {} children, got {}" ,
204- child_idx,
205- child_idx + 1 ,
206- children. len( )
207- ) ;
208- }
209- } ;
210-
211- let validity_idx = match & metadata. patches {
212- None => 0 ,
213- Some ( patches_meta) if patches_meta. chunk_offsets_dtype ( ) ?. is_some ( ) => 3 ,
214- Some ( _) => 2 ,
215- } ;
216-
217- let validity = load_validity ( validity_idx) ?;
218-
219- let patches = metadata
220- . patches
221- . map ( |p| {
222- let indices = children. get ( 0 , & p. indices_dtype ( ) ?, p. len ( ) ?) ?;
223- let values = children. get ( 1 , dtype, p. len ( ) ?) ?;
224- let chunk_offsets = p
225- . chunk_offsets_dtype ( ) ?
226- . map ( |dtype| children. get ( 2 , & dtype, p. chunk_offsets_len ( ) as usize ) )
227- . transpose ( ) ?;
228-
229- Patches :: new ( len, p. offset ( ) ?, indices, values, chunk_offsets)
230- } )
231- . transpose ( ) ?;
180+ let packed = single_buffer ( buffers) ?;
181+ let offset = offset_from_metadata ( metadata. offset ) ?;
182+ let bit_width = u8:: try_from ( metadata. bit_width ) . map_err ( |_| {
183+ vortex_err ! (
184+ "BitPackedMetadata bit_width {} does not fit in u8" ,
185+ metadata. bit_width
186+ )
187+ } ) ?;
188+ let ( patches, validity, _) =
189+ deserialize_children ( children, metadata. patches , dtype, len, 0 ) ?;
232190
233191 let slots = {
234- let mut s = ArraySlots :: with_capacity ( 4 ) ;
192+ let mut s = ArraySlots :: with_capacity ( BitPackedSlots :: COUNT ) ;
235193 PatchesData :: push_slots ( & mut s, patches. as_ref ( ) ) ;
236194 s. push ( validity_to_child ( & validity, len) ) ;
237195 s
238196 } ;
239- let data = BitPackedData :: try_new (
240- packed,
241- patches,
242- u8:: try_from ( metadata. bit_width ) . map_err ( |_| {
243- vortex_err ! (
244- "BitPackedMetadata bit_width {} does not fit in u8" ,
245- metadata. bit_width
246- )
247- } ) ?,
248- u16:: try_from ( metadata. offset ) . map_err ( |_| {
249- vortex_err ! (
250- "BitPackedMetadata offset {} does not fit in u16" ,
251- metadata. offset
252- )
253- } ) ?,
254- ) ?;
197+ let data = BitPackedData :: try_new ( packed, patches, bit_width, offset) ?;
255198 Ok ( ArrayParts :: new ( self . clone ( ) , dtype. clone ( ) , len, data) . with_slots ( slots) )
256199 }
257200
@@ -299,6 +242,71 @@ impl VTable for BitPacked {
299242 }
300243}
301244
245+ /// The single packed buffer of a serialized bit-packed array.
246+ pub ( crate ) fn single_buffer ( buffers : & [ BufferHandle ] ) -> VortexResult < BufferHandle > {
247+ vortex_ensure ! (
248+ buffers. len( ) == 1 ,
249+ "Expected 1 buffer, got {}" ,
250+ buffers. len( )
251+ ) ;
252+ Ok ( buffers[ 0 ] . clone ( ) )
253+ }
254+
255+ /// The offset into the first chunk, which the metadata stores as a `u32`.
256+ pub ( crate ) fn offset_from_metadata ( offset : u32 ) -> VortexResult < u16 > {
257+ u16:: try_from ( offset)
258+ . map_err ( |_| vortex_err ! ( "BitPackedMetadata offset {offset} does not fit in u16" ) )
259+ }
260+
261+ /// Read the patches and validity children that both wire formats share.
262+ ///
263+ /// Children run: the patches, then a validity bitmap if there is one, then `trailing` children
264+ /// the caller reads itself. Returns the index of the first trailing child.
265+ pub ( crate ) fn deserialize_children (
266+ children : & dyn ArrayChildren ,
267+ patches : Option < PatchesMetadata > ,
268+ dtype : & DType ,
269+ len : usize ,
270+ trailing : usize ,
271+ ) -> VortexResult < ( Option < Patches > , Validity , usize ) > {
272+ let num_patch_children = match & patches {
273+ None => 0 ,
274+ Some ( patches_meta) if patches_meta. chunk_offsets_dtype ( ) ?. is_some ( ) => 3 ,
275+ Some ( _) => 2 ,
276+ } ;
277+ let num_fixed = num_patch_children + trailing;
278+ let has_validity = match children. len ( ) . checked_sub ( num_fixed) {
279+ Some ( 0 ) => false ,
280+ Some ( 1 ) => true ,
281+ _ => vortex_bail ! (
282+ "Expected {num_fixed} or {} children, got {}" ,
283+ num_fixed + 1 ,
284+ children. len( )
285+ ) ,
286+ } ;
287+ let validity = if has_validity {
288+ Validity :: Array ( children. get ( num_patch_children, & Validity :: DTYPE , len) ?)
289+ } else {
290+ Validity :: from ( dtype. nullability ( ) )
291+ } ;
292+ let patches = patches
293+ . map ( |p| {
294+ let indices = children. get ( 0 , & p. indices_dtype ( ) ?, p. len ( ) ?) ?;
295+ let values = children. get ( 1 , dtype, p. len ( ) ?) ?;
296+ let chunk_offsets = p
297+ . chunk_offsets_dtype ( ) ?
298+ . map ( |dtype| children. get ( 2 , & dtype, p. chunk_offsets_len ( ) as usize ) )
299+ . transpose ( ) ?;
300+ Patches :: new ( len, p. offset ( ) ?, indices, values, chunk_offsets)
301+ } )
302+ . transpose ( ) ?;
303+ Ok ( (
304+ patches,
305+ validity,
306+ num_patch_children + usize:: from ( has_validity) ,
307+ ) )
308+ }
309+
302310#[ derive( Clone , Debug ) ]
303311pub struct BitPacked ;
304312
0 commit comments