Skip to content

Commit 88f2b03

Browse files
committed
add view vector take stubs
Signed-off-by: Connor Tsui <[email protected]>
1 parent 2189db3 commit 88f2b03

File tree

5 files changed

+422
-57
lines changed

5 files changed

+422
-57
lines changed

vortex-compute/src/take/bit_buffer.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,29 @@ fn take_bool<I: UnsignedPType>(bools: &BitBuffer, indices: &[I]) -> BitBuffer {
5858
get_bit(buffer, offset + bool_idx)
5959
})
6060
}
61+
62+
#[cfg(test)]
63+
mod tests {
64+
use crate::take::Take;
65+
66+
#[test]
67+
fn test_bit_buffer_take_small_and_large() {
68+
use vortex_buffer::BitBuffer;
69+
70+
// Small buffer (uses take_byte_bool path).
71+
let small: BitBuffer = [true, false, true, true, false, true, false, false]
72+
.into_iter()
73+
.collect();
74+
let result = (&small).take(&[7u32, 0, 2, 5, 1][..]);
75+
76+
let values: Vec<bool> = (0..result.len()).map(|i| result.value(i)).collect();
77+
assert_eq!(values, vec![false, true, true, true, false]);
78+
79+
// Large buffer (uses take_bool path, len > 4096).
80+
let large: BitBuffer = (0..5000).map(|i| i % 3 == 0).collect();
81+
let result = (&large).take(&[4999u32, 0, 1, 2, 3, 4998][..]);
82+
83+
let values: Vec<bool> = (0..result.len()).map(|i| result.value(i)).collect();
84+
assert_eq!(values, vec![false, true, false, false, true, true]);
85+
}
86+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3+
4+
// use std::ops::Deref;
5+
6+
// use num_traits::AsPrimitive;
7+
// use vortex_buffer::Buffer;
8+
use vortex_dtype::UnsignedPType;
9+
use vortex_vector::VectorOps;
10+
// use vortex_vector::binaryview::BinaryView;
11+
use vortex_vector::binaryview::BinaryViewType;
12+
use vortex_vector::binaryview::BinaryViewVector;
13+
use vortex_vector::primitive::PVector;
14+
15+
use crate::take::Take;
16+
17+
impl<T: BinaryViewType, I: UnsignedPType> Take<PVector<I>> for &BinaryViewVector<T> {
18+
type Output = BinaryViewVector<T>;
19+
20+
fn take(self, indices: &PVector<I>) -> BinaryViewVector<T> {
21+
if indices.validity().all_true() {
22+
self.take(indices.elements().as_slice())
23+
} else {
24+
take_nullable(self, indices)
25+
}
26+
}
27+
}
28+
29+
impl<T: BinaryViewType, I: UnsignedPType> Take<[I]> for &BinaryViewVector<T> {
30+
type Output = BinaryViewVector<T>;
31+
32+
fn take(self, _indices: &[I]) -> BinaryViewVector<T> {
33+
todo!("TODO(connor): Implement `take` for `BinaryViewVector` and figure out rebuilding");
34+
35+
/*
36+
37+
let taken_views = take_views(self.views(), indices);
38+
let taken_validity = self.validity().take(indices);
39+
40+
debug_assert_eq!(taken_views.len(), taken_validity.len());
41+
42+
// SAFETY: We called take on views and validity with the same indices, so the new components
43+
// must have the same length. The views still point into the same buffers which we clone via
44+
// Arc, so all view references remain valid.
45+
unsafe {
46+
BinaryViewVector::new_unchecked(taken_views, self.buffers().clone(), taken_validity)
47+
}
48+
49+
*/
50+
}
51+
}
52+
53+
fn take_nullable<T: BinaryViewType, I: UnsignedPType>(
54+
_bvector: &BinaryViewVector<T>,
55+
_indices: &PVector<I>,
56+
) -> BinaryViewVector<T> {
57+
todo!("TODO(connor): Implement `take` for `BinaryViewVector` and figure out rebuilding");
58+
59+
/*
60+
61+
// We ignore nullability when taking the views since we can let the `Mask` implementation
62+
// determine which elements are null.
63+
let taken_views = take_views(bvector.views(), indices.elements().as_slice());
64+
let taken_validity = bvector.validity().take(indices);
65+
66+
debug_assert_eq!(taken_views.len(), taken_validity.len());
67+
68+
// SAFETY: We used the same indices to take from both components, so they should still have the
69+
// same length. The views still point into the same buffers which we clone via Arc, so all view
70+
// references remain valid.
71+
unsafe {
72+
BinaryViewVector::new_unchecked(taken_views, bvector.buffers().clone(), taken_validity)
73+
}
74+
75+
*/
76+
}
77+
78+
/*
79+
80+
/// Takes views at the given indices.
81+
fn take_views<I: AsPrimitive<usize>>(
82+
views: &Buffer<BinaryView>,
83+
indices: &[I],
84+
) -> Buffer<BinaryView> {
85+
let views_ref = views.deref();
86+
Buffer::<BinaryView>::from_trusted_len_iter(indices.iter().map(|i| views_ref[(*i).as_()]))
87+
}
88+
89+
*/
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3+
4+
use vortex_dtype::UnsignedPType;
5+
use vortex_vector::VectorOps;
6+
use vortex_vector::listview::ListViewVector;
7+
use vortex_vector::primitive::PVector;
8+
9+
use crate::take::Take;
10+
11+
impl<I: UnsignedPType> Take<PVector<I>> for &ListViewVector {
12+
type Output = ListViewVector;
13+
14+
fn take(self, indices: &PVector<I>) -> ListViewVector {
15+
if indices.validity().all_true() {
16+
self.take(indices.elements().as_slice())
17+
} else {
18+
take_nullable(self, indices)
19+
}
20+
}
21+
}
22+
23+
impl<I: UnsignedPType> Take<[I]> for &ListViewVector {
24+
type Output = ListViewVector;
25+
26+
fn take(self, _indices: &[I]) -> ListViewVector {
27+
todo!("TODO(connor): Implement `take` for `ListViewVector` and figure out rebuilding");
28+
29+
/*
30+
31+
let taken_offsets = self.offsets().take(indices);
32+
let taken_sizes = self.sizes().take(indices);
33+
let taken_validity = self.validity().take(indices);
34+
35+
debug_assert_eq!(taken_offsets.len(), taken_validity.len());
36+
debug_assert_eq!(taken_sizes.len(), taken_validity.len());
37+
38+
// SAFETY: We called take on offsets, sizes, and validity with the same indices, so the new
39+
// components must have the same length. The offsets and sizes still point into the same
40+
// elements array which we clone via Arc, so all view references remain valid.
41+
unsafe {
42+
ListViewVector::new_unchecked(
43+
self.elements().clone(),
44+
taken_offsets,
45+
taken_sizes,
46+
taken_validity,
47+
)
48+
}
49+
50+
*/
51+
}
52+
}
53+
54+
fn take_nullable<I: UnsignedPType>(
55+
_lvector: &ListViewVector,
56+
_indices: &PVector<I>,
57+
) -> ListViewVector {
58+
todo!("TODO(connor): Implement `take` for `ListViewVector` and figure out rebuilding");
59+
60+
/*
61+
62+
// We ignore nullability when taking the offsets and sizes since we can let the `Mask`
63+
// implementation determine which elements are null.
64+
let taken_offsets = lvector.offsets().take(indices.elements().as_slice());
65+
let taken_sizes = lvector.sizes().take(indices.elements().as_slice());
66+
let taken_validity = lvector.validity().take(indices);
67+
68+
debug_assert_eq!(taken_offsets.len(), taken_validity.len());
69+
debug_assert_eq!(taken_sizes.len(), taken_validity.len());
70+
71+
// SAFETY: We used the same indices to take from all components, so they should still have the
72+
// same length. The offsets and sizes still point into the same elements array which we clone
73+
// via Arc, so all view references remain valid.
74+
unsafe {
75+
ListViewVector::new_unchecked(
76+
lvector.elements().clone(),
77+
taken_offsets,
78+
taken_sizes,
79+
taken_validity,
80+
)
81+
}
82+
83+
*/
84+
}

vortex-compute/src/take/vector/mod.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,45 @@
11
// SPDX-License-Identifier: Apache-2.0
22
// SPDX-FileCopyrightText: Copyright the Vortex contributors
33

4+
use vortex_dtype::UnsignedPType;
5+
use vortex_vector::Vector;
46
use vortex_vector::match_each_unsigned_pvector;
7+
use vortex_vector::match_each_vector;
58
use vortex_vector::primitive::PVector;
69
use vortex_vector::primitive::PrimitiveVector;
710

811
use crate::take::Take;
912

13+
mod binaryview;
1014
mod bool;
15+
mod decimal;
16+
mod dvector;
17+
mod fixed_size_list;
18+
mod listview;
19+
mod null;
1120
mod primitive;
1221
mod pvector;
22+
mod struct_;
1323

1424
#[cfg(test)]
1525
mod tests;
1626

27+
impl<I: UnsignedPType> Take<PVector<I>> for &Vector {
28+
type Output = Vector;
29+
30+
fn take(self, indices: &PVector<I>) -> Vector {
31+
match_each_vector!(self, |v| { v.take(indices).into() })
32+
}
33+
}
34+
35+
impl<I: UnsignedPType> Take<[I]> for &Vector {
36+
type Output = Vector;
37+
38+
fn take(self, indices: &[I]) -> Vector {
39+
match_each_vector!(self, |v| { v.take(indices).into() })
40+
}
41+
}
42+
1743
impl<T> Take<PrimitiveVector> for &T
1844
where
1945
for<'a> &'a T: Take<PVector<u8>, Output = T>,

0 commit comments

Comments
 (0)