Skip to content

Commit 198192d

Browse files
committed
Faster pipelines
Signed-off-by: Nicholas Gates <[email protected]>
1 parent 217c1b8 commit 198192d

File tree

2 files changed

+50
-27
lines changed

2 files changed

+50
-27
lines changed

vortex-array/src/pipeline/filter/buffer.rs

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,60 @@ use crate::pipeline::bit_view::BitView;
55
use crate::pipeline::N;
66
use vortex_compute::filter::Filter;
77

8-
impl<'a, T> Filter<BitView<'a>> for &'a mut [T] {
8+
impl<'a, T: Copy> Filter<BitView<'a>> for &'a mut [T] {
99
type Output = ();
1010

1111
fn filter(self, selection: &BitView<'a>) -> Self::Output {
12-
// High density: use iter_zeros to compact by removing gaps
13-
let mut write_idx = 0;
14-
let mut read_idx = 0;
12+
match selection.true_count() {
13+
0 => {
14+
// If the mask has no true bits, we set the length to 0.
15+
}
16+
N => {
17+
// If the mask has N true bits, we copy all elements.
18+
}
19+
n if n > 3 * N / 4 => {
20+
// High density: use iter_zeros to compact by removing gaps
21+
let mut write_idx = 0;
22+
let mut read_idx = 0;
1523

16-
selection.iter_zeros(|zero_idx| {
17-
// Copy elements from read_idx to zero_idx (exclusive) to write_idx
18-
let count = zero_idx - read_idx;
19-
unsafe {
20-
// SAFETY: We assume that the elements are of type E and that the view is valid.
21-
// Using memmove for potentially overlapping regions
22-
std::ptr::copy(
23-
self.as_ptr().add(read_idx),
24-
self.as_mut_ptr().add(write_idx),
25-
count,
26-
);
27-
write_idx += count;
24+
selection.iter_zeros(|zero_idx| {
25+
// Copy elements from read_idx to zero_idx (exclusive) to write_idx
26+
let count = zero_idx - read_idx;
27+
unsafe {
28+
// SAFETY: We assume that the elements are of type E and that the view is valid.
29+
// Using memmove for potentially overlapping regions
30+
std::ptr::copy(
31+
self.as_ptr().add(read_idx),
32+
self.as_mut_ptr().add(write_idx),
33+
count,
34+
);
35+
write_idx += count;
36+
}
37+
read_idx = zero_idx + 1;
38+
});
39+
40+
// Copy any remaining elements after the last zero
41+
unsafe {
42+
std::ptr::copy(
43+
self.as_ptr().add(read_idx),
44+
self.as_mut_ptr().add(write_idx),
45+
N - read_idx,
46+
);
47+
}
2848
}
29-
read_idx = zero_idx + 1;
30-
});
49+
_ => {
50+
let mut offset = 0;
51+
selection.iter_ones(|idx| {
52+
unsafe {
53+
// SAFETY: We assume that the elements are of type E and that the view is valid.
54+
let value = *self.get_unchecked(idx);
55+
// TODO(joe): use ptr increment (not offset).
56+
*self.get_unchecked_mut(offset) = value;
3157

32-
// Copy any remaining elements after the last zero
33-
unsafe {
34-
std::ptr::copy(
35-
self.as_ptr().add(read_idx),
36-
self.as_mut_ptr().add(write_idx),
37-
N - read_idx,
38-
);
58+
offset += 1;
59+
}
60+
});
61+
}
3962
}
4063
}
4164
}

vortex-array/src/pipeline/filter/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod buffer;
55

66
use crate::pipeline::bit_view::BitView;
77
use vortex_compute::filter::Filter;
8+
use vortex_dtype::NativePType;
89
use vortex_mask::MaskMut;
910
use vortex_vector::primitive::{PVectorMut, PrimitiveVectorMut};
1011
use vortex_vector::{match_each_pvector_mut, VectorMut, VectorMutOps};
@@ -37,11 +38,10 @@ impl Filter<BitView<'_>> for &mut PrimitiveVectorMut {
3738
}
3839
}
3940

40-
impl<T> Filter<BitView<'_>> for &mut PVectorMut<T> {
41+
impl<T: NativePType> Filter<BitView<'_>> for &mut PVectorMut<T> {
4142
type Output = ();
4243

4344
fn filter(self, selection: &BitView<'_>) -> Self::Output {
44-
println!("SEL(): {:?}", selection);
4545
unsafe { self.elements_mut() }.as_mut().filter(selection);
4646
// FIXME(ngates): filter the validity...
4747
*unsafe { self.validity_mut() } = MaskMut::new_true(selection.true_count());

0 commit comments

Comments
 (0)