Skip to content

Commit 369defb

Browse files
authored
Additions to vector API (#5045)
1 parent 2c76f24 commit 369defb

File tree

14 files changed

+325
-82
lines changed

14 files changed

+325
-82
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vortex-buffer/src/bit/buf.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,11 @@ impl BitOr for &BitBuffer {
322322
}
323323
}
324324

325-
impl BitOr for BitBuffer {
325+
impl BitOr<&BitBuffer> for BitBuffer {
326326
type Output = BitBuffer;
327327

328-
fn bitor(self, rhs: Self) -> Self::Output {
329-
(&self).bitor(&rhs)
328+
fn bitor(self, rhs: &BitBuffer) -> Self::Output {
329+
(&self).bitor(rhs)
330330
}
331331
}
332332

@@ -338,11 +338,11 @@ impl BitAnd for &BitBuffer {
338338
}
339339
}
340340

341-
impl BitAnd for BitBuffer {
341+
impl BitAnd<&BitBuffer> for BitBuffer {
342342
type Output = BitBuffer;
343343

344-
fn bitand(self, rhs: Self) -> Self::Output {
345-
(&self).bitand(&rhs)
344+
fn bitand(self, rhs: &BitBuffer) -> Self::Output {
345+
(&self).bitand(rhs)
346346
}
347347
}
348348

@@ -370,11 +370,21 @@ impl BitXor for &BitBuffer {
370370
}
371371
}
372372

373-
impl BitXor for BitBuffer {
373+
impl BitXor<&BitBuffer> for BitBuffer {
374374
type Output = BitBuffer;
375375

376-
fn bitxor(self, rhs: Self) -> Self::Output {
377-
(&self).bitxor(&rhs)
376+
fn bitxor(self, rhs: &BitBuffer) -> Self::Output {
377+
(&self).bitxor(rhs)
378+
}
379+
}
380+
381+
impl BitBuffer {
382+
/// Create a new BitBuffer by performing a bitwise AND NOT operation between two BitBuffers.
383+
///
384+
/// This operation is sufficiently common that we provide a dedicated method for it avoid
385+
/// making two passes over the data.
386+
pub fn bitand_not(&self, rhs: &BitBuffer) -> BitBuffer {
387+
bitwise_binary_op(self, rhs, |a, b| a & !b)
378388
}
379389
}
380390

vortex-buffer/src/bit/macros.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,18 @@
22
// SPDX-FileCopyrightText: Copyright the Vortex contributors
33

44
/// A macro for constructing bit-buffers akin to `vec![..]`.
5+
///
6+
/// Supports multiple syntaxes:
7+
/// - `bitbuffer![]` - empty buffer
8+
/// - `bitbuffer![value; count]` - fill with value
9+
/// - `bitbuffer![expr, expr, ...]` - comma-separated boolean expressions
10+
/// - `bitbuffer![0 1 0 1]` - space-separated bit literals (0s and 1s)
511
#[macro_export]
612
macro_rules! bitbuffer {
13+
// Internal rule to convert a single bit (0 or 1) to bool
14+
(@bit 0) => { false };
15+
(@bit 1) => { true };
16+
717
() => (
818
$crate::BitBuffer::empty()
919
);
@@ -13,11 +23,25 @@ macro_rules! bitbuffer {
1323
($($x:expr),+ $(,)?) => (
1424
$crate::BitBuffer::from_iter([$($x),+])
1525
);
26+
// Match space-separated bit literals (0 or 1)
27+
($($bit:tt)+) => {
28+
$crate::BitBuffer::from_iter([$( $crate::bitbuffer!(@bit $bit) ),+])
29+
};
1630
}
1731

1832
/// A macro for constructing bit-buffers akin to `vec![..]`.
33+
///
34+
/// Supports multiple syntaxes:
35+
/// - `bitbuffer_mut![]` - empty buffer
36+
/// - `bitbuffer_mut![value; count]` - fill with value
37+
/// - `bitbuffer_mut![expr, expr, ...]` - comma-separated boolean expressions
38+
/// - `bitbuffer_mut![0 1 0 1]` - space-separated bit literals (0s and 1s)
1939
#[macro_export]
2040
macro_rules! bitbuffer_mut {
41+
// Internal rule to convert a single bit (0 or 1) to bool
42+
(@bit 0) => { false };
43+
(@bit 1) => { true };
44+
2145
() => (
2246
$crate::BitBufferMut::empty()
2347
);
@@ -27,4 +51,8 @@ macro_rules! bitbuffer_mut {
2751
($($x:expr),+ $(,)?) => (
2852
$crate::BitBufferMut::from_iter([$($x),+])
2953
);
54+
// Match space-separated bit literals (0 or 1)
55+
($($bit:tt)+) => {
56+
$crate::BitBufferMut::from_iter([$( $crate::bitbuffer_mut!(@bit $bit) ),+])
57+
};
3058
}

vortex-dtype/src/ptype.rs

Lines changed: 19 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,7 @@ pub trait NativePType:
143143
fn is_eq(self, other: Self) -> bool;
144144

145145
/// Downcast the provided object to a type-specific instance.
146-
fn downcast<V: PTypeDowncast + ?Sized>(visitor: &V) -> V::Output<Self>;
147-
148-
/// Downcast the provided object to a type-specific instance.
149-
fn downcast_mut<V: PTypeDowncastMut + ?Sized>(visitor: &mut V) -> V::Output<Self>;
146+
fn downcast<V: PTypeDowncast>(visitor: V) -> V::Output<Self>;
150147

151148
/// Upcast a type-specific instance to a generic instance.
152149
fn upcast<V: PTypeUpcast>(input: V::Input<Self>) -> V;
@@ -157,65 +154,37 @@ pub trait NativePType:
157154
pub trait PTypeDowncast {
158155
type Output<T: NativePType>;
159156

160-
fn as_u8(&self) -> Self::Output<u8>;
161-
fn as_u16(&self) -> Self::Output<u16>;
162-
fn as_u32(&self) -> Self::Output<u32>;
163-
fn as_u64(&self) -> Self::Output<u64>;
164-
fn as_i8(&self) -> Self::Output<i8>;
165-
fn as_i16(&self) -> Self::Output<i16>;
166-
fn as_i32(&self) -> Self::Output<i32>;
167-
fn as_i64(&self) -> Self::Output<i64>;
168-
fn as_f16(&self) -> Self::Output<f16>;
169-
fn as_f32(&self) -> Self::Output<f32>;
170-
fn as_f64(&self) -> Self::Output<f64>;
157+
fn into_u8(self) -> Self::Output<u8>;
158+
fn into_u16(self) -> Self::Output<u16>;
159+
fn into_u32(self) -> Self::Output<u32>;
160+
fn into_u64(self) -> Self::Output<u64>;
161+
fn into_i8(self) -> Self::Output<i8>;
162+
fn into_i16(self) -> Self::Output<i16>;
163+
fn into_i32(self) -> Self::Output<i32>;
164+
fn into_i64(self) -> Self::Output<i64>;
165+
fn into_f16(self) -> Self::Output<f16>;
166+
fn into_f32(self) -> Self::Output<f32>;
167+
fn into_f64(self) -> Self::Output<f64>;
171168
}
172169

173170
/// Extension trait to provide generic downcasting for [`PTypeDowncast`].
174171
pub trait PTypeDowncastExt: PTypeDowncast {
175172
/// Downcast the object to a specific primitive type.
176-
fn as_primitive<T: NativePType>(&self) -> Self::Output<T> {
173+
fn into_primitive<T: NativePType>(self) -> Self::Output<T>
174+
where
175+
Self: Sized,
176+
{
177177
T::downcast(self)
178178
}
179179
}
180180

181-
impl<T: PTypeDowncast + ?Sized> PTypeDowncastExt for T {}
182-
183-
/// A visitor trait for converting a `NativePType` to another mutable parameterized type.
184-
#[allow(missing_docs)] // Kind of obvious..
185-
pub trait PTypeDowncastMut {
186-
type Output<T: NativePType>;
187-
188-
fn as_u8(&mut self) -> Self::Output<u8>;
189-
fn as_u16(&mut self) -> Self::Output<u16>;
190-
fn as_u32(&mut self) -> Self::Output<u32>;
191-
fn as_u64(&mut self) -> Self::Output<u64>;
192-
fn as_i8(&mut self) -> Self::Output<i8>;
193-
fn as_i16(&mut self) -> Self::Output<i16>;
194-
fn as_i32(&mut self) -> Self::Output<i32>;
195-
fn as_i64(&mut self) -> Self::Output<i64>;
196-
fn as_f16(&mut self) -> Self::Output<f16>;
197-
fn as_f32(&mut self) -> Self::Output<f32>;
198-
fn as_f64(&mut self) -> Self::Output<f64>;
199-
}
200-
201-
/// Extension trait to provide generic downcasting for [`PTypeDowncastMut`].
202-
pub trait PTypeDowncastMutExt: PTypeDowncastMut {
203-
/// Downcast the object to a specific primitive type.
204-
fn as_primitive_mut<T: NativePType>(&mut self) -> Self::Output<T> {
205-
T::downcast_mut(self)
206-
}
207-
}
181+
impl<T: PTypeDowncast> PTypeDowncastExt for T {}
208182

209183
macro_rules! impl_ptype_downcast {
210184
($T:ty) => {
211185
#[inline]
212-
fn downcast<V: PTypeDowncast + ?Sized>(visitor: &V) -> V::Output<Self> {
213-
paste::paste! { visitor.[<as_ $T>]() }
214-
}
215-
216-
#[inline]
217-
fn downcast_mut<V: PTypeDowncastMut + ?Sized>(visitor: &mut V) -> V::Output<Self> {
218-
paste::paste! { visitor.[<as_ $T>]() }
186+
fn downcast<V: PTypeDowncast>(visitor: V) -> V::Output<Self> {
187+
paste::paste! { visitor.[<into_ $T>]() }
219188
}
220189

221190
#[inline]
@@ -279,8 +248,6 @@ macro_rules! native_ptype {
279248
};
280249
}
281250

282-
impl<T: PTypeDowncastMut + ?Sized> PTypeDowncastMutExt for T {}
283-
284251
macro_rules! native_float_ptype {
285252
($T:ty, $ptype:tt) => {
286253
impl crate::NativeDType for $T {

vortex-mask/src/mask_mut.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ enum Inner {
2828
}
2929

3030
impl MaskMut {
31+
/// Creates a new empty mask.
32+
pub fn empty() -> Self {
33+
Self::with_capacity(0)
34+
}
35+
3136
/// Creates a new empty mask with the default capacity.
3237
pub fn with_capacity(capacity: usize) -> Self {
3338
Self(Inner::Empty { capacity })

vortex-vector/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,3 @@ vortex-buffer = { workspace = true }
2424
vortex-dtype = { workspace = true }
2525
vortex-error = { workspace = true }
2626
vortex-mask = { workspace = true }
27-
vortex-scalar = { workspace = true }

vortex-vector/src/bool/vector.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,32 @@ pub struct BoolVector {
2323
pub(super) validity: Mask,
2424
}
2525

26+
impl BoolVector {
27+
/// Creates a new [`BoolVector`] from the given bits and validity mask.
28+
///
29+
/// # Panics
30+
///
31+
/// Panics if the length of the validity mask does not match the length of the bits.
32+
pub fn new(bits: BitBuffer, validity: Mask) -> Self {
33+
assert_eq!(
34+
validity.len(),
35+
bits.len(),
36+
"BoolVector validity mask must have the same length as bits"
37+
);
38+
Self { bits, validity }
39+
}
40+
41+
/// Returns the bits buffer of the boolean vector.
42+
pub fn bits(&self) -> &BitBuffer {
43+
&self.bits
44+
}
45+
}
46+
2647
impl VectorOps for BoolVector {
2748
type Mutable = BoolVectorMut;
2849

2950
fn len(&self) -> usize {
3051
debug_assert!(self.validity.len() == self.bits.len());
31-
3252
self.bits.len()
3353
}
3454

vortex-vector/src/lib.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,18 @@
1111
#![deny(clippy::missing_panics_doc)]
1212
#![deny(clippy::missing_safety_doc)]
1313

14-
mod vector;
15-
pub use vector::Vector;
16-
17-
mod vector_mut;
18-
pub use vector_mut::VectorMut;
19-
20-
mod ops;
21-
pub use ops::{VectorMutOps, VectorOps};
22-
2314
mod bool;
15+
mod macros;
2416
mod null;
17+
mod ops;
2518
mod primitive;
19+
mod private;
20+
mod vector;
21+
mod vector_mut;
2622

2723
pub use bool::{BoolVector, BoolVectorMut};
2824
pub use null::{NullVector, NullVectorMut};
25+
pub use ops::{VectorMutOps, VectorOps};
2926
pub use primitive::{PVector, PVectorMut, PrimitiveVector, PrimitiveVectorMut};
30-
31-
mod macros;
32-
33-
mod private;
27+
pub use vector::Vector;
28+
pub use vector_mut::VectorMut;

vortex-vector/src/ops.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub trait VectorMutOps: private::Sealed + Into<VectorMut> {
7575
/// Appends `n` null elements to the vector.
7676
///
7777
/// Implementors should ensure that they correctly append "null" or garbage values to their
78-
/// elements in addition to adding nulls to their validity mask.s.
78+
/// elements in addition to adding nulls to their validity mask.
7979
fn append_nulls(&mut self, n: usize);
8080

8181
/// Converts `self` into an immutable vector.

0 commit comments

Comments
 (0)