Skip to content

Commit 5b91d07

Browse files
authored
Chore: Add match_vector_pair macro (#5123)
Note that the formatting is ugly because of this: rust-lang/rust#52234 (comment) Several of the match statements keep getting out of sync because we have to remember to add variants to match statements everywhere. Also fixes some of the macro imports since we're `macro_export`ing everything again. Also fixes an issue with the struct API (accidentally didn't return an `Arc`) (Note that this is quite important for the implementation of `FixedSizeList` and `ListView` vectors) otherwise there is way too much boilerplate --------- Signed-off-by: Connor Tsui <[email protected]>
1 parent e00961b commit 5b91d07

File tree

8 files changed

+142
-192
lines changed

8 files changed

+142
-192
lines changed

vortex-vector/src/macros.rs

Lines changed: 95 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -39,36 +39,16 @@
3939
macro_rules! match_each_vector {
4040
($self:expr, | $vec:ident | $body:block) => {{
4141
match $self {
42-
$crate::Vector::Null(v) => {
43-
let $vec = v;
44-
$body
45-
}
46-
$crate::Vector::Bool(v) => {
47-
let $vec = v;
48-
$body
49-
}
50-
$crate::Vector::Primitive(v) => {
51-
let $vec = v;
52-
$body
53-
}
54-
$crate::Vector::String(v) => {
55-
let $vec = v;
56-
$body
57-
}
58-
$crate::Vector::Binary(v) => {
59-
let $vec = v;
60-
$body
61-
}
62-
$crate::Vector::Struct(v) => {
63-
let $vec = v;
64-
$body
65-
}
42+
$crate::Vector::Null($vec) => $body,
43+
$crate::Vector::Bool($vec) => $body,
44+
$crate::Vector::Primitive($vec) => $body,
45+
$crate::Vector::String($vec) => $body,
46+
$crate::Vector::Binary($vec) => $body,
47+
$crate::Vector::Struct($vec) => $body,
6648
}
6749
}};
6850
}
6951

70-
pub(crate) use match_each_vector;
71-
7252
/// Matches on all variants of [`VectorMut`] and executes the same code for each variant branch.
7353
///
7454
/// This macro eliminates repetitive match statements when implementing operations that need to work
@@ -104,32 +84,96 @@ pub(crate) use match_each_vector;
10484
macro_rules! match_each_vector_mut {
10585
($self:expr, | $vec:ident | $body:block) => {{
10686
match $self {
107-
$crate::VectorMut::Null(v) => {
108-
let $vec = v;
109-
$body
110-
}
111-
$crate::VectorMut::Bool(v) => {
112-
let $vec = v;
113-
$body
114-
}
115-
$crate::VectorMut::Primitive(v) => {
116-
let $vec = v;
117-
$body
118-
}
119-
$crate::VectorMut::String(v) => {
120-
let $vec = v;
121-
$body
122-
}
123-
$crate::VectorMut::Binary(v) => {
124-
let $vec = v;
125-
$body
126-
}
127-
$crate::VectorMut::Struct(v) => {
128-
let $vec = v;
129-
$body
130-
}
87+
$crate::VectorMut::Null($vec) => $body,
88+
$crate::VectorMut::Bool($vec) => $body,
89+
$crate::VectorMut::Primitive($vec) => $body,
90+
$crate::VectorMut::String($vec) => $body,
91+
$crate::VectorMut::Binary($vec) => $body,
92+
$crate::VectorMut::Struct($vec) => $body,
93+
}
94+
}};
95+
}
96+
97+
/// Internal macro to generate match arms for vector pairs.
98+
#[doc(hidden)]
99+
#[macro_export]
100+
macro_rules! __match_vector_pair_arms {
101+
(
102+
$left:expr,
103+
$right:expr,
104+
$enum_left:ident,
105+
$enum_right:ident,
106+
$a:ident,
107+
$b:ident,
108+
$body:expr
109+
) => {{
110+
match ($left, $right) {
111+
($crate::$enum_left::Null($a), $crate::$enum_right::Null($b)) => $body,
112+
($crate::$enum_left::Bool($a), $crate::$enum_right::Bool($b)) => $body,
113+
($crate::$enum_left::Primitive($a), $crate::$enum_right::Primitive($b)) => $body,
114+
($crate::$enum_left::String($a), $crate::$enum_right::String($b)) => $body,
115+
($crate::$enum_left::Binary($a), $crate::$enum_right::Binary($b)) => $body,
116+
($crate::$enum_left::Struct($a), $crate::$enum_right::Struct($b)) => $body,
117+
_ => ::vortex_error::vortex_panic!("Mismatched vector types"),
131118
}
132119
}};
133120
}
134121

135-
pub(crate) use match_each_vector_mut;
122+
/// Matches on pairs of vector variants and executes the same code for matching variant pairs.
123+
///
124+
/// This macro eliminates repetitive match statements when implementing operations that need to work
125+
/// with pairs of vectors where the variants must match.
126+
///
127+
/// Specify the types of the left and right vectors (either `Vector` or `VectorMut`) and the macro
128+
/// generates the appropriate match arms.
129+
///
130+
/// The macro binds the matched inner values to identifiers in the closure that can be used in the
131+
/// body expression.
132+
///
133+
/// # Examples
134+
///
135+
/// ```
136+
/// use vortex_vector::{
137+
/// BoolVector, BoolVectorMut, Vector, VectorMut, VectorMutOps, match_vector_pair
138+
/// };
139+
///
140+
/// fn extend_vector(left: &mut VectorMut, right: &Vector) {
141+
/// match_vector_pair!(left, right, |a: VectorMut, b: Vector| {
142+
/// a.extend_from_vector(b);
143+
/// })
144+
/// }
145+
///
146+
/// let mut mut_vec: VectorMut = BoolVectorMut::from_iter([true, false, true]).into();
147+
/// let vec: Vector = BoolVectorMut::from_iter([false, true]).freeze().into();
148+
///
149+
/// extend_vector(&mut mut_vec, &vec);
150+
/// assert_eq!(mut_vec.len(), 5);
151+
/// ```
152+
///
153+
/// Note that the vectors can also be owned:
154+
///
155+
/// ```
156+
/// use vortex_vector::{
157+
/// BoolVector, BoolVectorMut, Vector, VectorMut, VectorMutOps, match_vector_pair
158+
/// };
159+
///
160+
/// fn extend_vector_owned(mut dest: VectorMut, src: Vector) -> VectorMut {
161+
/// match_vector_pair!(&mut dest, src, |a: VectorMut, b: Vector| {
162+
/// a.extend_from_vector(&b);
163+
/// dest
164+
/// })
165+
/// }
166+
///
167+
/// let mut_vec: VectorMut = BoolVectorMut::from_iter([true, false, true]).into();
168+
/// let vec: Vector = BoolVectorMut::from_iter([false, true]).freeze().into();
169+
///
170+
/// let new_bool_mut = extend_vector_owned(mut_vec, vec);
171+
/// assert_eq!(new_bool_mut.len(), 5);
172+
/// ```
173+
#[macro_export] // DO NOT ADD `#[rustfmt::skip]`!!! https://github.com/rust-lang/rust/pull/52234#issuecomment-903419099
174+
macro_rules! match_vector_pair {
175+
($left:expr, $right:expr, | $a:ident : Vector, $b:ident : Vector | $body:expr) => {{ $crate::__match_vector_pair_arms!($left, $right, Vector, Vector, $a, $b, $body) }};
176+
($left:expr, $right:expr, | $a:ident : Vector, $b:ident : VectorMut | $body:expr) => {{ $crate::__match_vector_pair_arms!($left, $right, Vector, VectorMut, $a, $b, $body) }};
177+
($left:expr, $right:expr, | $a:ident : VectorMut, $b:ident : Vector | $body:expr) => {{ $crate::__match_vector_pair_arms!($left, $right, VectorMut, Vector, $a, $b, $body) }};
178+
($left:expr, $right:expr, | $a:ident : VectorMut, $b:ident : VectorMut | $body:expr) => {{ $crate::__match_vector_pair_arms!($left, $right, VectorMut, VectorMut, $a, $b, $body) }};
179+
}

vortex-vector/src/primitive/macros.rs

Lines changed: 22 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -44,56 +44,21 @@
4444
macro_rules! match_each_pvector {
4545
($self:expr, | $vec:ident | $body:block) => {{
4646
match $self {
47-
$crate::PrimitiveVector::U8(v) => {
48-
let $vec = v;
49-
$body
50-
}
51-
$crate::PrimitiveVector::U16(v) => {
52-
let $vec = v;
53-
$body
54-
}
55-
$crate::PrimitiveVector::U32(v) => {
56-
let $vec = v;
57-
$body
58-
}
59-
$crate::PrimitiveVector::U64(v) => {
60-
let $vec = v;
61-
$body
62-
}
63-
$crate::PrimitiveVector::I8(v) => {
64-
let $vec = v;
65-
$body
66-
}
67-
$crate::PrimitiveVector::I16(v) => {
68-
let $vec = v;
69-
$body
70-
}
71-
$crate::PrimitiveVector::I32(v) => {
72-
let $vec = v;
73-
$body
74-
}
75-
$crate::PrimitiveVector::I64(v) => {
76-
let $vec = v;
77-
$body
78-
}
79-
$crate::PrimitiveVector::F16(v) => {
80-
let $vec = v;
81-
$body
82-
}
83-
$crate::PrimitiveVector::F32(v) => {
84-
let $vec = v;
85-
$body
86-
}
87-
$crate::PrimitiveVector::F64(v) => {
88-
let $vec = v;
89-
$body
90-
}
47+
$crate::PrimitiveVector::U8($vec) => $body,
48+
$crate::PrimitiveVector::U16($vec) => $body,
49+
$crate::PrimitiveVector::U32($vec) => $body,
50+
$crate::PrimitiveVector::U64($vec) => $body,
51+
$crate::PrimitiveVector::I8($vec) => $body,
52+
$crate::PrimitiveVector::I16($vec) => $body,
53+
$crate::PrimitiveVector::I32($vec) => $body,
54+
$crate::PrimitiveVector::I64($vec) => $body,
55+
$crate::PrimitiveVector::F16($vec) => $body,
56+
$crate::PrimitiveVector::F32($vec) => $body,
57+
$crate::PrimitiveVector::F64($vec) => $body,
9158
}
9259
}};
9360
}
9461

95-
pub(crate) use match_each_pvector;
96-
9762
/// Matches on all primitive type variants of [`PrimitiveVectorMut`] and executes the same code
9863
/// for each variant branch.
9964
///
@@ -129,52 +94,17 @@ pub(crate) use match_each_pvector;
12994
macro_rules! match_each_pvector_mut {
13095
($self:expr, | $vec:ident | $body:block) => {{
13196
match $self {
132-
$crate::PrimitiveVectorMut::U8(v) => {
133-
let $vec = v;
134-
$body
135-
}
136-
$crate::PrimitiveVectorMut::U16(v) => {
137-
let $vec = v;
138-
$body
139-
}
140-
$crate::PrimitiveVectorMut::U32(v) => {
141-
let $vec = v;
142-
$body
143-
}
144-
$crate::PrimitiveVectorMut::U64(v) => {
145-
let $vec = v;
146-
$body
147-
}
148-
$crate::PrimitiveVectorMut::I8(v) => {
149-
let $vec = v;
150-
$body
151-
}
152-
$crate::PrimitiveVectorMut::I16(v) => {
153-
let $vec = v;
154-
$body
155-
}
156-
$crate::PrimitiveVectorMut::I32(v) => {
157-
let $vec = v;
158-
$body
159-
}
160-
$crate::PrimitiveVectorMut::I64(v) => {
161-
let $vec = v;
162-
$body
163-
}
164-
$crate::PrimitiveVectorMut::F16(v) => {
165-
let $vec = v;
166-
$body
167-
}
168-
$crate::PrimitiveVectorMut::F32(v) => {
169-
let $vec = v;
170-
$body
171-
}
172-
$crate::PrimitiveVectorMut::F64(v) => {
173-
let $vec = v;
174-
$body
175-
}
97+
$crate::PrimitiveVectorMut::U8($vec) => $body,
98+
$crate::PrimitiveVectorMut::U16($vec) => $body,
99+
$crate::PrimitiveVectorMut::U32($vec) => $body,
100+
$crate::PrimitiveVectorMut::U64($vec) => $body,
101+
$crate::PrimitiveVectorMut::I8($vec) => $body,
102+
$crate::PrimitiveVectorMut::I16($vec) => $body,
103+
$crate::PrimitiveVectorMut::I32($vec) => $body,
104+
$crate::PrimitiveVectorMut::I64($vec) => $body,
105+
$crate::PrimitiveVectorMut::F16($vec) => $body,
106+
$crate::PrimitiveVectorMut::F32($vec) => $body,
107+
$crate::PrimitiveVectorMut::F64($vec) => $body,
176108
}
177109
}};
178110
}
179-
180-
pub(crate) use match_each_pvector_mut;

vortex-vector/src/primitive/vector.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ use vortex_dtype::half::f16;
77
use vortex_dtype::{NativePType, PType, PTypeDowncast, PTypeUpcast};
88
use vortex_error::vortex_panic;
99

10-
use super::macros::match_each_pvector;
11-
use crate::{PVector, PrimitiveVectorMut, VectorOps};
10+
use crate::{PVector, PrimitiveVectorMut, VectorOps, match_each_pvector};
1211

1312
/// An immutable vector of primitive values.
1413
///

vortex-vector/src/primitive/vector_mut.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ use vortex_dtype::half::f16;
77
use vortex_dtype::{NativePType, PType, PTypeDowncast, PTypeUpcast};
88
use vortex_error::vortex_panic;
99

10-
use super::macros::match_each_pvector_mut;
11-
use crate::{PVectorMut, PrimitiveVector, VectorMutOps};
10+
use crate::{PVectorMut, PrimitiveVector, VectorMutOps, match_each_pvector_mut};
1211

1312
/// A mutable vector of primitive values.
1413
///

vortex-vector/src/struct_/vector.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ pub struct StructVector {
3333

3434
/// The length of the vector (which is the same as all field vectors).
3535
///
36-
/// This is stored here as a convenience, and also helps in the case that the `StructVector` has
37-
/// no fields.
36+
/// This is stored here as a convenience, as the validity also tracks this information.
3837
pub(super) len: usize,
3938
}
4039

@@ -111,14 +110,14 @@ impl StructVector {
111110
}
112111
}
113112

114-
/// Decomposes the struct vector into its constituent parts (fields, validity, and length).
113+
/// Decomposes the struct vector into its constituent parts (fields and validity).
115114
pub fn into_parts(self) -> (Arc<Box<[Vector]>>, Mask) {
116115
(self.fields, self.validity)
117116
}
118117

119118
/// Returns the fields of the `StructVector`, each stored column-wise as a [`Vector`].
120-
pub fn fields(&self) -> &[Vector] {
121-
self.fields.as_ref()
119+
pub fn fields(&self) -> &Arc<Box<[Vector]>> {
120+
&self.fields
122121
}
123122
}
124123

0 commit comments

Comments
 (0)