@@ -243,20 +243,26 @@ pub mod serialization_neu {
243243 }
244244
245245 /// Decodes an encoded sequence of byte slices. Each result will be `u64` aligned.
246+ #[ inline( always) ]
246247 pub fn decode ( store : & [ u64 ] ) -> impl Iterator < Item =& [ u8 ] > {
247- assert ! ( store[ 0 ] % 8 == 0 ) ;
248- let slices = ( store[ 0 ] / 8 ) - 1 ;
249- ( 0 .. slices) . map ( |i| decode_index ( store, i) )
248+ let slices = store[ 0 ] as usize / 8 - 1 ;
249+ let index = & store[ ..slices + 1 ] ;
250+ let last = index[ slices] as usize ;
251+ let bytes: & [ u8 ] = & bytemuck:: cast_slice ( store) [ ..last] ;
252+ ( 0 .. slices) . map ( move |i| {
253+ let upper = ( index[ i + 1 ] as usize ) . min ( last) ;
254+ let lower = ( ( ( index[ i] as usize ) + 7 ) & !7 ) . min ( upper) ;
255+ & bytes[ lower .. upper]
256+ } )
250257 }
251258
252259 /// Decodes a specific byte slice by index. It will be `u64` aligned.
253260 #[ inline( always) ]
254261 pub fn decode_index ( store : & [ u64 ] , index : u64 ) -> & [ u8 ] {
255- debug_assert ! ( index + 1 < store[ 0 ] /8 ) ;
256- let index: usize = index. try_into ( ) . unwrap ( ) ;
257- let lower: usize = ( ( store[ index] + 7 ) & !7 ) . try_into ( ) . unwrap ( ) ;
258- let upper: usize = ( store[ index + 1 ] ) . try_into ( ) . unwrap ( ) ;
259- let bytes: & [ u8 ] = bytemuck:: try_cast_slice ( store) . expect ( "&[u64] should convert to &[u8]" ) ;
262+ let index = index as usize ;
263+ let bytes: & [ u8 ] = bytemuck:: cast_slice ( store) ;
264+ let upper = ( store[ index + 1 ] as usize ) . min ( bytes. len ( ) ) ;
265+ let lower = ( ( ( store[ index] as usize ) + 7 ) & !7 ) . min ( upper) ;
260266 & bytes[ lower .. upper]
261267 }
262268
@@ -433,5 +439,35 @@ mod test {
433439 assert_eq ! ( column3. get( 2 * i+0 ) , column2. get( 2 * i+0 ) ) ;
434440 assert_eq ! ( column3. get( 2 * i+1 ) , column2. get( 2 * i+1 ) ) ;
435441 }
442+
443+ // Test from_byte_slices round-trip.
444+ let byte_vec: Vec < & [ u8 ] > = column. borrow ( ) . as_bytes ( ) . map ( |( _, bytes) | bytes) . collect ( ) ;
445+ let column4 = crate :: Results :: < & [ u64 ] , & [ u64 ] , & [ u64 ] , & [ u64 ] , & u64 > :: from_byte_slices ( & byte_vec) ;
446+ for i in 0 ..100 {
447+ assert_eq ! ( column. get( 2 * i+0 ) , column4. get( 2 * i+0 ) . copied( ) . map_err( |e| * e) ) ;
448+ assert_eq ! ( column. get( 2 * i+1 ) , column4. get( 2 * i+1 ) . copied( ) . map_err( |e| * e) ) ;
449+ }
450+ }
451+
452+ /// Test from_byte_slices for tuples.
453+ #[ test]
454+ fn from_byte_slices_tuple ( ) {
455+ use crate :: common:: { Push , Index } ;
456+ use crate :: { Borrow , AsBytes , FromBytes , ContainerOf } ;
457+
458+ let mut column: ContainerOf < ( u64 , String , Vec < u32 > ) > = Default :: default ( ) ;
459+ for i in 0 ..50u64 {
460+ column. push ( & ( i, format ! ( "hello {i}" ) , vec ! [ i as u32 ; i as usize ] ) ) ;
461+ }
462+
463+ let byte_vec: Vec < & [ u8 ] > = column. borrow ( ) . as_bytes ( ) . map ( |( _, bytes) | bytes) . collect ( ) ;
464+ type Borrowed < ' a > = <ContainerOf < ( u64 , String , Vec < u32 > ) > as crate :: Borrow >:: Borrowed < ' a > ;
465+ let reconstructed = Borrowed :: from_byte_slices ( & byte_vec) ;
466+ for i in 0 ..50 {
467+ let ( a, b, _c) = reconstructed. get ( i) ;
468+ assert_eq ! ( * a, i as u64 ) ;
469+ assert_eq ! ( b, & * format!( "hello {i}" ) ) ;
470+ }
436471 }
472+
437473}
0 commit comments