Skip to content

Commit bc21219

Browse files
committed
BoolArray::new
Signed-off-by: Nicholas Gates <[email protected]>
1 parent ba0e97a commit bc21219

File tree

2 files changed

+51
-65
lines changed

2 files changed

+51
-65
lines changed

vortex-array/src/arrays/bool/array.rs

Lines changed: 49 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,17 @@
44
use arrow_array::BooleanArray;
55
use vortex_buffer::BitBuffer;
66
use vortex_buffer::BitBufferMut;
7-
use vortex_buffer::ByteBuffer;
87
use vortex_dtype::DType;
8+
use vortex_error::vortex_ensure;
99
use vortex_error::VortexExpect;
1010
use vortex_error::VortexResult;
11-
use vortex_error::vortex_ensure;
1211
use vortex_mask::Mask;
1312

14-
use crate::ArrayRef;
15-
use crate::IntoArray;
1613
use crate::arrays::bool;
1714
use crate::stats::ArrayStats;
1815
use crate::validity::Validity;
16+
use crate::ArrayRef;
17+
use crate::IntoArray;
1918

2019
/// A boolean array that stores true/false values in a compact bit-packed format.
2120
///
@@ -49,12 +48,21 @@ use crate::validity::Validity;
4948
#[derive(Clone, Debug)]
5049
pub struct BoolArray {
5150
pub(super) dtype: DType,
52-
pub(super) buffer: BitBuffer,
51+
pub(super) bits: BitBuffer,
5352
pub(super) validity: Validity,
5453
pub(super) stats_set: ArrayStats,
5554
}
5655

5756
impl BoolArray {
57+
/// Constructs a new `BoolArray`.
58+
///
59+
/// # Panics
60+
///
61+
/// Panics if the validity length is not equal to the bit buffer length.
62+
pub fn new(bits: BitBuffer, validity: Validity) -> Self {
63+
Self::try_new(bits, validity).vortex_expect("Failed to create BoolArray")
64+
}
65+
5866
/// Constructs a new `BoolArray`.
5967
///
6068
/// See [`BoolArray::new_unchecked`] for more information.
@@ -63,16 +71,15 @@ impl BoolArray {
6371
///
6472
/// Returns an error if the provided components do not satisfy the invariants documented in
6573
/// [`BoolArray::new_unchecked`].
66-
pub fn try_new(
67-
buffer: ByteBuffer,
68-
offset: usize,
69-
len: usize,
70-
validity: Validity,
71-
) -> VortexResult<Self> {
72-
Self::validate(&buffer, offset, len, &validity)?;
73-
74-
// SAFETY: validate ensures all invariants are met.
75-
Ok(unsafe { Self::new_unchecked(buffer, offset, len, validity) })
74+
pub fn try_new(bits: BitBuffer, validity: Validity) -> VortexResult<Self> {
75+
let bits = bits.shrink_offset();
76+
Self::validate(&bits, &validity)?;
77+
Ok(Self {
78+
dtype: DType::Bool(validity.nullability()),
79+
bits,
80+
validity,
81+
stats_set: ArrayStats::default(),
82+
})
7683
}
7784

7885
/// Creates a new [`BoolArray`] without validation from these components:
@@ -90,53 +97,35 @@ impl BoolArray {
9097
/// - `buffer` must contain at least `(offset + len).div_ceil(8)` bytes.
9198
/// - `offset` must be less than 8 (it represents the bit offset within the first byte).
9299
/// - If `validity` is `Validity::Array`, its length must exactly equal `len`.
93-
pub unsafe fn new_unchecked(
94-
buffer: ByteBuffer,
95-
offset: usize,
96-
len: usize,
97-
validity: Validity,
98-
) -> Self {
99-
#[cfg(debug_assertions)]
100-
Self::validate(&buffer, offset, len, &validity)
101-
.vortex_expect("[Debug Assertion]: Invalid `BoolArray` parameters");
102-
103-
let buffer = BitBuffer::new_with_offset(buffer, len, offset);
104-
let buffer = buffer.shrink_offset();
105-
Self {
106-
dtype: DType::Bool(validity.nullability()),
107-
buffer,
108-
validity,
109-
stats_set: ArrayStats::default(),
100+
pub unsafe fn new_unchecked(bits: BitBuffer, validity: Validity) -> Self {
101+
if cfg!(debug_assertions) {
102+
Self::new(bits, validity)
103+
} else {
104+
Self {
105+
dtype: DType::Bool(validity.nullability()),
106+
bits,
107+
validity,
108+
stats_set: ArrayStats::default(),
109+
}
110110
}
111111
}
112112

113113
/// Validates the components that would be used to create a [`BoolArray`].
114114
///
115115
/// This function checks all the invariants required by [`BoolArray::new_unchecked`].
116-
pub fn validate(
117-
buffer: &ByteBuffer,
118-
offset: usize,
119-
len: usize,
120-
validity: &Validity,
121-
) -> VortexResult<()> {
122-
vortex_ensure!(
123-
offset < 8,
124-
"offset must be less than whole byte, was {offset} bits"
125-
);
126-
127-
// Validate the buffer is large enough to hold all the bits
128-
let required_bytes = offset.saturating_add(len).div_ceil(8);
116+
pub fn validate(bits: &BitBuffer, validity: &Validity) -> VortexResult<()> {
129117
vortex_ensure!(
130-
buffer.len() >= required_bytes,
131-
"BoolArray with offset={offset} len={len} cannot be built from buffer of size {}",
132-
buffer.len()
118+
bits.offset() < 8,
119+
"BitBuffer offset must be <8, got {}",
120+
bits.offset()
133121
);
134122

135123
// Validate validity
136124
if let Some(validity_len) = validity.maybe_len() {
137125
vortex_ensure!(
138-
validity_len == len,
139-
"BoolArray of size {len} cannot be built with validity of size {validity_len}"
126+
validity_len == bits.len(),
127+
"BoolArray of size {} cannot be built with validity of size {validity_len}",
128+
bits.len()
140129
);
141130
}
142131

@@ -157,7 +146,7 @@ impl BoolArray {
157146
let buffer = buffer.shrink_offset();
158147
Self {
159148
dtype: DType::Bool(validity.nullability()),
160-
buffer,
149+
bits: buffer,
161150
validity,
162151
stats_set: ArrayStats::default(),
163152
}
@@ -179,16 +168,16 @@ impl BoolArray {
179168
/// Returns the underlying [`BitBuffer`] of the array.
180169
pub fn bit_buffer(&self) -> &BitBuffer {
181170
assert!(
182-
self.buffer.offset() < 8,
171+
self.bits.offset() < 8,
183172
"Offset must be <8, did we forget to call shrink_offset? Found {}",
184-
self.buffer.offset()
173+
self.bits.offset()
185174
);
186-
&self.buffer
175+
&self.bits
187176
}
188177

189178
/// Returns the underlying [`BitBuffer`] ofthe array
190179
pub fn into_bit_buffer(self) -> BitBuffer {
191-
self.buffer
180+
self.bits
192181
}
193182

194183
pub fn to_mask(&self) -> Mask {
@@ -247,10 +236,7 @@ impl FromIterator<Option<bool>> for BoolArray {
247236

248237
impl IntoArray for BitBuffer {
249238
fn into_array(self) -> ArrayRef {
250-
let (offset, len, buffer) = self.into_inner();
251-
BoolArray::try_new(buffer, offset, len, Validity::NonNullable)
252-
.vortex_expect("known correct")
253-
.into_array()
239+
BoolArray::new(self, Validity::NonNullable).into_array()
254240
}
255241
}
256242

@@ -262,18 +248,18 @@ impl IntoArray for BitBufferMut {
262248

263249
#[cfg(test)]
264250
mod tests {
251+
use vortex_buffer::buffer;
265252
use vortex_buffer::BitBuffer;
266253
use vortex_buffer::BitBufferMut;
267-
use vortex_buffer::buffer;
268254

269-
use crate::Array;
270-
use crate::IntoArray;
271-
use crate::ToCanonical;
272255
use crate::arrays::BoolArray;
273256
use crate::arrays::PrimitiveArray;
274257
use crate::patches::Patches;
275258
use crate::validity::Validity;
276259
use crate::vtable::ValidityHelper;
260+
use crate::Array;
261+
use crate::IntoArray;
262+
use crate::ToCanonical;
277263

278264
#[test]
279265
fn bool_array() {

vortex-array/src/arrays/bool/vtable/array.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ use std::hash::Hash;
55

66
use vortex_dtype::DType;
77

8-
use crate::Precision;
98
use crate::arrays::BoolArray;
109
use crate::arrays::BoolVTable;
1110
use crate::hash::ArrayEq;
1211
use crate::hash::ArrayHash;
1312
use crate::stats::StatsSetRef;
1413
use crate::vtable::BaseArrayVTable;
14+
use crate::Precision;
1515

1616
impl BaseArrayVTable<BoolVTable> for BoolVTable {
1717
fn len(array: &BoolArray) -> usize {
18-
array.buffer.len()
18+
array.bits.len()
1919
}
2020

2121
fn dtype(array: &BoolArray) -> &DType {

0 commit comments

Comments
 (0)