@@ -346,6 +346,12 @@ impl<T> LazyArray<T> {
346
346
let position = ( self . position . get ( ) as u64 ) . to_le_bytes ( ) ;
347
347
let len = ( self . num_elems as u64 ) . to_le_bytes ( ) ;
348
348
349
+ // Element width is selected at runtime on a per-table basis by omitting trailing
350
+ // zero bytes in table elements. This works very naturally when table elements are
351
+ // simple numbers but `LazyArray` is a pair of integers. If naively encoded, the second
352
+ // element would shield the trailing zeroes in the first. Interleaving the bytes
353
+ // of the position and length exposes trailing zeroes in both to the optimization.
354
+ // We encode length second because we generally expect it to be smaller.
349
355
for i in 0 ..8 {
350
356
b[ 2 * i] = position[ i] ;
351
357
b[ 2 * i + 1 ] = len[ i] ;
@@ -359,18 +365,26 @@ impl<T> LazyArray<T> {
359
365
}
360
366
}
361
367
368
+ // Decoding helper for the encoding scheme used by `LazyArray`.
369
+ // Interleaving the bytes of the two integers exposes trailing bytes in the first integer
370
+ // to the varint scheme that we use for tables.
371
+ #[ inline]
372
+ fn decode_interleaved ( encoded : & [ u8 ; 16 ] ) -> ( [ u8 ; 8 ] , [ u8 ; 8 ] ) {
373
+ let mut first = [ 0u8 ; 8 ] ;
374
+ let mut second = [ 0u8 ; 8 ] ;
375
+ for i in 0 ..8 {
376
+ first[ i] = encoded[ 2 * i] ;
377
+ second[ i] = encoded[ 2 * i + 1 ] ;
378
+ }
379
+ ( first, second)
380
+ }
381
+
362
382
impl < T > FixedSizeEncoding for LazyArray < T > {
363
383
type ByteArray = [ u8 ; 16 ] ;
364
384
365
385
#[ inline]
366
386
fn from_bytes ( b : & [ u8 ; 16 ] ) -> Self {
367
- let mut position = [ 0u8 ; 8 ] ;
368
- let mut meta = [ 0u8 ; 8 ] ;
369
-
370
- for i in 0 ..8 {
371
- position[ i] = b[ 2 * i] ;
372
- meta[ i] = b[ 2 * i + 1 ] ;
373
- }
387
+ let ( position, meta) = decode_interleaved ( b) ;
374
388
375
389
if meta == [ 0 ; 8 ] {
376
390
return Default :: default ( ) ;
@@ -390,13 +404,7 @@ impl<T> FixedSizeEncoding for Option<LazyArray<T>> {
390
404
391
405
#[ inline]
392
406
fn from_bytes ( b : & [ u8 ; 16 ] ) -> Self {
393
- let mut position = [ 0u8 ; 8 ] ;
394
- let mut meta = [ 0u8 ; 8 ] ;
395
-
396
- for i in 0 ..8 {
397
- position[ i] = b[ 2 * i] ;
398
- meta[ i] = b[ 2 * i + 1 ] ;
399
- }
407
+ let ( position, meta) = decode_interleaved ( b) ;
400
408
401
409
LazyArray :: from_bytes_impl ( & position, & meta)
402
410
}
0 commit comments