Skip to content

Commit 6cab3ed

Browse files
committed
fix: BitView slice filter
I wrote the unit test, it failed, stepped through it in debugger, noticed that span was always zero. We always clear the lowest bit and then check for trailing_ones, so we never copied anything. Fixes the logic to actually copy runs of values. Test passes now. Signed-off-by: Andrew Duffy <[email protected]>
1 parent e269163 commit 6cab3ed

File tree

2 files changed

+55
-8
lines changed

2 files changed

+55
-8
lines changed

encodings/fastlanes/src/bitpacking/array/bitpack_pipeline.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,15 @@ impl<BP: PhysicalPType<Physical: BitPacking>> Kernel for AlignedBitPackedKernel<
203203

204204
#[cfg(test)]
205205
mod tests {
206+
use itertools::Itertools;
207+
use vortex_array::IntoArray;
206208
use vortex_array::arrays::PrimitiveArray;
207-
use vortex_dtype::PTypeDowncast;
209+
use vortex_dtype::{PTypeDowncast, PTypeDowncastExt};
208210
use vortex_mask::Mask;
209211
use vortex_vector::VectorOps;
210212

211213
use crate::BitPackedArray;
214+
use crate::bitpack_compress::bitpack_encode;
212215

213216
#[test]
214217
fn test_bitpack_pipeline_basic() {
@@ -408,4 +411,24 @@ mod tests {
408411
}
409412
}
410413
}
414+
415+
#[test]
416+
fn test_pipeline() {
417+
let array = PrimitiveArray::from_iter(0u64..2048u64);
418+
let packed = bitpack_encode(&array, 12, None).unwrap().into_array();
419+
420+
// Only select odd numbered elements
421+
let select_indices = (0..2048).filter(|i| i % 2 == 1).collect_vec();
422+
let selection = Mask::from_indices(2048, select_indices);
423+
424+
let result = packed.execute_with_selection(&selection).unwrap();
425+
assert_eq!(result.len(), 1024);
426+
427+
let result = result.into_primitive().downcast::<u64>();
428+
429+
let slice = result.as_ref();
430+
for i in 0..1024 {
431+
assert_eq!(slice[i], (2 * i + 1) as u64);
432+
}
433+
}
411434
}

vortex-compute/src/filter/slice_mut.rs

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,41 @@ impl<'a, const NB: usize, T: Copy> Filter<BitView<'a, NB>> for &mut [T] {
108108
}
109109
}
110110
_ => {
111+
// Iterate the bits in a word, attempting to copy contiguous runs of values.
112+
let mut read_pos = 0;
113+
let mut write_pos = 0;
111114
while word != 0 {
112-
let bit_pos = word.trailing_zeros();
113-
word &= word - 1; // Clear the bit at `bit_pos`
114-
let span = word.trailing_ones();
115-
word >>= span;
115+
let tz = word.trailing_zeros();
116+
if tz > 0 {
117+
// shift off the trailing zeros since they are unselected.
118+
// this advances the read head, but not the write head.
119+
read_pos += tz;
120+
word >>= tz;
121+
continue;
122+
}
123+
124+
// copy the next several values to our out pointer.
125+
let extent = word.trailing_ones();
116126
unsafe {
117-
ptr::copy(read_ptr.add(bit_pos as usize), write_ptr, span as usize);
118-
write_ptr = write_ptr.add(span as usize);
127+
ptr::copy(
128+
read_ptr.add(read_pos as usize),
129+
write_ptr.add(write_pos as usize),
130+
extent as usize,
131+
);
119132
}
133+
// Advance the reader and writer by the number of values
134+
// we just copied.
135+
read_pos += extent;
136+
write_pos += extent;
137+
138+
// shift off the low bits of the word so we can copy the next run.
139+
word >>= extent;
120140
}
121-
unsafe { read_ptr = read_ptr.add(usize::BITS as usize) };
141+
142+
unsafe {
143+
read_ptr = read_ptr.add(usize::BITS as usize);
144+
write_ptr = write_ptr.add(write_pos as usize);
145+
};
122146
}
123147
}
124148
}

0 commit comments

Comments
 (0)