Skip to content

Commit

Permalink
Fix slicing an already sliced BitPackedArray (#778)
Browse files Browse the repository at this point in the history
  • Loading branch information
robert3005 committed Sep 10, 2024
1 parent dbaf477 commit 8176a88
Showing 1 changed file with 36 additions and 4 deletions.
40 changes: 36 additions & 4 deletions encodings/fastlanes/src/bitpacking/compute/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ use crate::BitPackedArray;

impl SliceFn for BitPackedArray {
fn slice(&self, start: usize, stop: usize) -> VortexResult<Array> {
let offset = start % 1024;
let block_start = max(0, start - offset);
let block_stop = ((stop + 1023) / 1024) * 1024;
let offset_start = start + self.offset();
let offset_stop = stop + self.offset();
let offset = offset_start % 1024;
let block_start = max(0, offset_start - offset);
let block_stop = ((offset_stop + 1023) / 1024) * 1024;

let encoded_start = (block_start / 8) * self.bit_width() / self.ptype().byte_width();
let encoded_stop = (block_stop / 8) * self.bit_width() / self.ptype().byte_width();
Expand All @@ -19,7 +21,7 @@ impl SliceFn for BitPackedArray {
self.validity().slice(start, stop)?,
self.patches().map(|p| slice(&p, start, stop)).transpose()?,
self.bit_width(),
stop - start,
offset_stop - offset_start,
offset,
)
.map(|a| a.into_array())
Expand Down Expand Up @@ -108,4 +110,34 @@ mod test {
((9215 % 63) as u8).into()
);
}

#[test]
fn double_slice_within_block() {
let arr = BitPackedArray::encode(
PrimitiveArray::from((0u32..2048).map(|v| v % 64).collect::<Vec<_>>()).array(),
6,
)
.unwrap()
.into_array();
let sliced = BitPackedArray::try_from(slice(&arr, 512, 1434).unwrap()).unwrap();
assert_eq!(scalar_at(sliced.array(), 0).unwrap(), (512u32 % 64).into());
assert_eq!(
scalar_at(sliced.array(), 921).unwrap(),
(1433u32 % 64).into()
);
assert_eq!(sliced.offset(), 512);
assert_eq!(sliced.len(), 922);
let doubly_sliced =
BitPackedArray::try_from(slice(sliced.array(), 127, 911).unwrap()).unwrap();
assert_eq!(
scalar_at(doubly_sliced.array(), 0).unwrap(),
((512u32 + 127) % 64).into()
);
assert_eq!(
scalar_at(doubly_sliced.array(), 783).unwrap(),
((512u32 + 910) % 64).into()
);
assert_eq!(doubly_sliced.offset(), 639);
assert_eq!(doubly_sliced.len(), 784);
}
}

0 comments on commit 8176a88

Please sign in to comment.