@@ -19,8 +19,6 @@ mod validity;
1919mod varbinview;
2020mod vector;
2121
22- use bitvec:: prelude:: Lsb0 ;
23- use bitvec:: view:: BitView ;
2422pub use cache:: ConversionCache ;
2523pub use decimal:: precision_to_duckdb_storage_size;
2624use vortex:: array:: ArrayRef ;
@@ -32,6 +30,7 @@ use vortex::array::arrays::List;
3230use vortex:: array:: arrays:: StructArray ;
3331use vortex:: array:: arrays:: TemporalArray ;
3432use vortex:: array:: arrays:: struct_:: StructArrayExt ;
33+ use vortex:: buffer:: BitChunks ;
3534use vortex:: encodings:: runend:: RunEnd ;
3635use vortex:: encodings:: sequence:: Sequence ;
3736use vortex:: error:: VortexResult ;
@@ -187,17 +186,33 @@ fn new_array_exporter_with_flatten(
187186 }
188187}
189188
190- /// Copy the sliced bits from source into target.
189+ /// Copy the sliced bits from source into target, returning whether all copied bits are zero,
190+ /// all are one, or mixed.
191191///
192- /// Offset and length are a _bit_ offset and a _bit_ length into source.
192+ /// offset and len are a _bit_ offset and a _bit_ length into ` source` .
193193///
194- /// `target.len()` must equal `len`.
195- fn copy_from_slice ( target : & mut [ u64 ] , source : & [ u8 ] , offset : usize , len : usize ) {
196- let ( start, middle, end) = unsafe { target. align_to_mut :: < u8 > ( ) } ;
197- assert ! ( start. is_empty( ) ) ;
198- assert ! ( end. is_empty( ) ) ;
199- let target = & mut middle. view_bits_mut :: < Lsb0 > ( ) [ ..len] ;
200- target. copy_from_bitslice ( & source. view_bits ( ) [ offset..] [ ..len] ) ;
194+ /// target must have at least len.div_ceil(64) elements.
195+ /// Returns the number of ones in copied slice.
196+ fn copy_from_slice ( target : & mut [ u64 ] , source : & [ u8 ] , offset : usize , len : usize ) -> usize {
197+ if len == 0 {
198+ return 0 ;
199+ }
200+
201+ let mut ones = 0usize ;
202+ let chunks = BitChunks :: new ( source, offset, len) ;
203+ let chunk_len = chunks. chunk_len ( ) ;
204+ let remainder_len = chunks. remainder_len ( ) ;
205+ let remainder = chunks. remainder_bits ( ) ;
206+ for ( slot, chunk) in target. iter_mut ( ) . zip ( chunks) {
207+ * slot = chunk;
208+ ones += chunk. count_ones ( ) as usize ;
209+ }
210+
211+ if remainder_len > 0 {
212+ target[ chunk_len] = remainder;
213+ ones += remainder. count_ones ( ) as usize ;
214+ }
215+ ones
201216}
202217
203218#[ cfg( test) ]
@@ -359,44 +374,51 @@ mod tests {
359374 fn test_copy_from_slice_empty_to_empty ( ) {
360375 let target = & mut [ ] ;
361376 let source = Vec :: < u8 > :: new ( ) ;
362- copy_from_slice ( target, & source, 0 , 0 ) ;
377+ assert_eq ! ( copy_from_slice( target, & source, 0 , 0 ) , 0 ) ;
363378 }
364379
365380 #[ test]
366381 fn test_copy_from_slice_64_to_empty ( ) {
367382 let target = & mut [ ] ;
368383 let source = [ 1u8 , 2 , 3 , 50 , 51 , 52 , 100 , 101 ] ;
369- copy_from_slice ( target, & source, 0 , 0 ) ;
370- copy_from_slice ( target, & source, 5 , 0 ) ;
371- copy_from_slice ( target, & source, 8 , 0 ) ;
384+ assert_eq ! ( copy_from_slice( target, & source, 0 , 0 ) , 0 ) ;
385+ assert_eq ! ( copy_from_slice( target, & source, 5 , 0 ) , 0 ) ;
386+ assert_eq ! ( copy_from_slice( target, & source, 8 , 0 ) , 0 ) ;
372387 }
373388
374389 #[ test]
375390 fn test_copy_from_slice_64_to_64 ( ) {
376391 let mut target = vec ! [ 0u64 ] ;
377392 let source = [ 1u8 , 2 , 3 , 50 , 51 , 52 , 100 , 101 ] ;
378- copy_from_slice ( & mut target, & source, 0 , 64 ) ;
393+ assert_eq ! ( copy_from_slice( & mut target, & source, 0 , 64 ) , 21 ) ;
379394 assert_eq ! (
380395 target[ 0 ] , 0x65_64_34_33_32_03_02_01_u64 ,
381396 "{:#08x} == {:#08x}" ,
382397 target[ 0 ] , 0x65_64_34_33_32_03_02_01_u64 ,
383398 ) ;
384399 }
385400
401+ #[ test]
402+ fn test_copy_from_slice_64_ones ( ) {
403+ let mut target = [ 0u64 ] ;
404+ let source = [ u8:: MAX ; 8 ] ;
405+ assert_eq ! ( copy_from_slice( & mut target, & source, 0 , 64 ) , 64 ) ;
406+ }
407+
386408 #[ test]
387409 fn test_copy_from_slice_80_to_0 ( ) {
388410 let target = & mut [ ] ;
389411 let source = [ 1u8 , 2 , 3 , 50 , 51 , 52 , 100 , 101 , 254 , 255 ] ;
390- copy_from_slice ( target, & source, 0 , 0 ) ;
391- copy_from_slice ( target, & source, 8 , 0 ) ;
392- copy_from_slice ( target, & source, 10 , 0 ) ;
412+ assert_eq ! ( copy_from_slice( target, & source, 0 , 0 ) , 0 ) ;
413+ assert_eq ! ( copy_from_slice( target, & source, 8 , 0 ) , 0 ) ;
414+ assert_eq ! ( copy_from_slice( target, & source, 10 , 0 ) , 0 , ) ;
393415 }
394416
395417 #[ test]
396418 fn test_copy_from_slice_80_to_64_case_1 ( ) {
397419 let mut target = [ 0u64 ] ;
398420 let source = [ 1u8 , 2 , 3 , 50 , 51 , 52 , 100 , 101 , 254 , 255 ] ;
399- copy_from_slice ( & mut target, & source, 16 , 64 ) ;
421+ assert_eq ! ( copy_from_slice( & mut target, & source, 16 , 64 ) , 34 ) ;
400422 assert_eq ! (
401423 target[ 0 ] , 0xff_fe_65_64_34_33_32_03_u64 ,
402424 "{:#08x} == {:#08x}" ,
@@ -408,7 +430,7 @@ mod tests {
408430 fn test_copy_from_slice_80_to_64_case_2 ( ) {
409431 let mut target = [ 0u64 ] ;
410432 let source = [ 1u8 , 2 , 3 , 50 , 51 , 52 , 100 , 101 , 254 , 255 ] ;
411- copy_from_slice ( & mut target, & source, 8 , 64 ) ;
433+ assert_eq ! ( copy_from_slice( & mut target, & source, 8 , 64 ) , 27 ) ;
412434 assert_eq ! (
413435 target[ 0 ] , 0xfe_65_64_34_33_32_03_02_u64 ,
414436 "{:#08x} == {:#08x}" ,
@@ -420,7 +442,7 @@ mod tests {
420442 fn test_copy_from_slice_80_to_64_case_3 ( ) {
421443 let mut target = [ 0u64 ] ;
422444 let source = [ 1u8 , 2 , 3 , 50 , 51 , 52 , 100 , 101 , 254 , 255 ] ;
423- copy_from_slice ( & mut target, & source, 0 , 64 ) ;
445+ assert_eq ! ( copy_from_slice( & mut target, & source, 0 , 64 ) , 21 , ) ;
424446 assert_eq ! (
425447 target[ 0 ] , 0x65_64_34_33_32_03_02_01_u64 ,
426448 "{:#08x} == {:#08x}" ,
@@ -432,7 +454,7 @@ mod tests {
432454 fn test_copy_from_slice_80_to_64_case_4 ( ) {
433455 let mut target = [ 0u64 ] ;
434456 let source = [ 1u8 , 2 , 3 , 50 , 51 , 52 , 100 , 101 , 254 , 255 ] ;
435- copy_from_slice ( & mut target, & source, 10 , 64 ) ;
457+ assert_eq ! ( copy_from_slice( & mut target, & source, 10 , 64 ) , 28 , ) ;
436458 assert_eq ! (
437459 target[ 0 ] ,
438460 0xff_99_59_0d_0c_cc_80_c0_u64 , // Python: hex(0xff_fe_65_64_34_33_32_03_02 >> 2), then remove the high two hexits
@@ -454,7 +476,7 @@ mod tests {
454476 let ( _, middle, _) = unsafe { source. align_to :: < u64 > ( ) } ;
455477 assert ! ( !middle. is_empty( ) ) ;
456478
457- copy_from_slice ( & mut target, & source, 0 , 128 ) ;
479+ assert_eq ! ( copy_from_slice( & mut target, & source, 0 , 128 ) , 66 , ) ;
458480 assert_eq ! (
459481 target[ 0 ] , 0xfc_fd_fe_ff_04_03_02_01_u64 ,
460482 "{:#08x} == {:#08x}" ,
@@ -466,7 +488,7 @@ mod tests {
466488 target[ 1 ] , 0xf9_fa_fb_fc_08_07_06_05_u64 ,
467489 ) ;
468490
469- copy_from_slice ( & mut target, & source, 8 , 128 ) ;
491+ assert_eq ! ( copy_from_slice( & mut target, & source, 8 , 128 ) , 66 ) ;
470492 assert_eq ! (
471493 target[ 0 ] , 0x05_fc_fd_fe_ff_04_03_02_u64 ,
472494 "{:#08x} == {:#08x}" ,
@@ -478,7 +500,7 @@ mod tests {
478500 target[ 1 ] , 0x01_f9_fa_fb_fc_08_07_06_u64 ,
479501 ) ;
480502
481- copy_from_slice ( & mut target, & source, 8 * 8 , 128 ) ;
503+ assert_eq ! ( copy_from_slice( & mut target, & source, 8 * 8 , 128 ) , 66 , ) ;
482504 assert_eq ! (
483505 target[ 0 ] , 0xf9_fa_fb_fc_08_07_06_05_u64 ,
484506 "{:#08x} == {:#08x}" ,
@@ -490,7 +512,7 @@ mod tests {
490512 target[ 1 ] , 0xfc_fd_fe_ff_04_03_02_01_u64 ,
491513 ) ;
492514
493- copy_from_slice ( & mut target, & source, 8 * 12 , 128 ) ;
515+ assert_eq ! ( copy_from_slice( & mut target, & source, 8 * 12 , 128 ) , 66 , ) ;
494516 assert_eq ! (
495517 target[ 0 ] , 0x04_03_02_01_f9_fa_fb_fc_u64 ,
496518 "{:#08x} == {:#08x}" ,
@@ -502,7 +524,7 @@ mod tests {
502524 target[ 1 ] , 0x08_07_06_05_fc_fd_fe_ff_u64 ,
503525 ) ;
504526
505- copy_from_slice ( & mut target, & source, 8 * 12 + 4 , 128 ) ;
527+ assert_eq ! ( copy_from_slice( & mut target, & source, 8 * 12 + 4 , 128 ) , 66 , ) ;
506528 // Find the 12th byte, skip the first hexit, take the next 32 hexits (i.e. 16 bytesor 128
507529 // bits).
508530 assert_eq ! (
@@ -517,7 +539,10 @@ mod tests {
517539 ) ;
518540
519541 // Take the above and shift one bit towards the right-hand-side.
520- copy_from_slice ( & mut target, & source, 8 * 12 + 4 + 1 , 128 ) ;
542+ assert_eq ! (
543+ copy_from_slice( & mut target, & source, 8 * 12 + 4 + 1 , 128 ) ,
544+ 66 ,
545+ ) ;
521546 assert_eq ! (
522547 target[ 0 ] , 0xf8_20_18_10_0f_cf_d7_df_u64 ,
523548 "{:#08x} == {:#08x}" ,
0 commit comments