Skip to content

Commit 9aa8735

Browse files
authored
RowMask uses ConstantArray for all valid and all invalid selections and remove unsafe RowMask constructor (#1495)
fix #1452
1 parent e452cbf commit 9aa8735

File tree

3 files changed

+40
-52
lines changed

3 files changed

+40
-52
lines changed

vortex-file/src/read/layouts/chunked.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ impl ChunkedLayoutReader {
215215
.zip(in_progress_range)
216216
.filter(|(_, cr)| !cr.finished())
217217
{
218-
let layout_selection = mask.slice(*begin, *end).shift(*begin)?;
218+
let layout_selection = mask.slice(*begin, *end)?.shift(*begin)?;
219219
if let Some(rr) = layout.read_selection(&layout_selection)? {
220220
match rr {
221221
BatchRead::ReadMore(m) => {

vortex-file/src/read/mask.rs

Lines changed: 29 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
use std::cmp::{max, min};
22
use std::fmt::{Display, Formatter};
33

4-
use arrow_buffer::BooleanBuffer;
5-
use vortex_array::array::{BoolArray, PrimitiveArray, SparseArray};
4+
use vortex_array::array::{BoolArray, ConstantArray, PrimitiveArray, SparseArray};
65
use vortex_array::compute::{and, filter, slice, take, try_cast, FilterMask, TakeOptions};
76
use vortex_array::stats::ArrayStatistics;
87
use vortex_array::validity::{ArrayValidity, LogicalValidity};
98
use vortex_array::{ArrayDType, ArrayData, IntoArrayData, IntoArrayVariant};
109
use vortex_dtype::Nullability::NonNullable;
1110
use vortex_dtype::{DType, PType};
12-
use vortex_error::{vortex_bail, VortexExpect, VortexResult};
11+
use vortex_error::{vortex_bail, VortexExpect, VortexResult, VortexUnwrap};
1312

1413
const PREFER_TAKE_TO_FILTER_DENSITY: f64 = 1.0 / 1024.0;
1514

@@ -73,37 +72,22 @@ impl RowMask {
7372

7473
/// Construct a RowMask which is valid in the given range.
7574
pub fn new_valid_between(begin: usize, end: usize) -> Self {
76-
unsafe {
77-
RowMask::new_unchecked(
78-
BoolArray::from(BooleanBuffer::new_set(end - begin)).into_array(),
79-
begin,
80-
end,
81-
)
82-
}
75+
RowMask::try_new(
76+
ConstantArray::new(true, end - begin).into_array(),
77+
begin,
78+
end,
79+
)
80+
.vortex_unwrap()
8381
}
8482

8583
/// Construct a RowMask which is invalid everywhere in the given range.
8684
pub fn new_invalid_between(begin: usize, end: usize) -> Self {
87-
unsafe {
88-
RowMask::new_unchecked(
89-
BoolArray::from(BooleanBuffer::new_unset(end - begin)).into_array(),
90-
begin,
91-
end,
92-
)
93-
}
94-
}
95-
96-
/// Construct a RowMask from given bitmask, begin and end.
97-
///
98-
/// # Safety
99-
///
100-
/// The bitmask must be of a nonnullable bool array and length of end - begin
101-
pub unsafe fn new_unchecked(bitmask: ArrayData, begin: usize, end: usize) -> Self {
102-
Self {
103-
bitmask,
85+
RowMask::try_new(
86+
ConstantArray::new(false, end - begin).into_array(),
10487
begin,
10588
end,
106-
}
89+
)
90+
.vortex_unwrap()
10791
}
10892

10993
/// Construct a RowMask from a Boolean typed array.
@@ -185,25 +169,22 @@ impl RowMask {
185169
}
186170

187171
/// Limit mask to [begin..end) range
188-
pub fn slice(&self, begin: usize, end: usize) -> Self {
172+
pub fn slice(&self, begin: usize, end: usize) -> VortexResult<Self> {
189173
let range_begin = max(self.begin, begin);
190174
let range_end = min(self.end, end);
191-
unsafe {
192-
RowMask::new_unchecked(
193-
if range_begin == self.begin && range_end == self.end {
194-
self.bitmask.clone()
195-
} else {
196-
slice(
197-
&self.bitmask,
198-
range_begin - self.begin,
199-
range_end - self.begin,
200-
)
201-
.vortex_expect("Must be a valid slice")
202-
},
203-
range_begin,
204-
range_end,
205-
)
206-
}
175+
RowMask::try_new(
176+
if range_begin == self.begin && range_end == self.end {
177+
self.bitmask.clone()
178+
} else {
179+
slice(
180+
&self.bitmask,
181+
range_begin - self.begin,
182+
range_end - self.begin,
183+
)?
184+
},
185+
range_begin,
186+
range_end,
187+
)
207188
}
208189

209190
/// Filter array with this `RowMask`.
@@ -262,7 +243,7 @@ impl RowMask {
262243
self.begin
263244
)
264245
}
265-
Ok(unsafe { RowMask::new_unchecked(self.bitmask, self.begin - offset, self.end - offset) })
246+
RowMask::try_new(self.bitmask, self.begin - offset, self.end - offset)
266247
}
267248
}
268249

@@ -273,6 +254,7 @@ mod tests {
273254
use vortex_array::array::{BoolArray, PrimitiveArray};
274255
use vortex_array::{IntoArrayData, IntoArrayVariant};
275256
use vortex_dtype::Nullability;
257+
use vortex_error::VortexUnwrap;
276258

277259
use crate::read::mask::RowMask;
278260

@@ -299,7 +281,7 @@ mod tests {
299281
RowMask::try_new(BoolArray::from_iter([false, true]).into_array(), 3, 5).unwrap())]
300282
#[cfg_attr(miri, ignore)]
301283
fn slice(#[case] first: RowMask, #[case] range: (usize, usize), #[case] expected: RowMask) {
302-
assert_eq!(first.slice(range.0, range.1), expected);
284+
assert_eq!(first.slice(range.0, range.1).vortex_unwrap(), expected);
303285
}
304286

305287
#[test]

vortex-file/src/read/splits.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,12 @@ impl PruningSplitIterator {
103103
};
104104

105105
// we masked everything out, so move on
106-
if row_mask.slice(begin, end).is_empty() {
106+
let sliced = row_mask.slice(begin, end)?;
107+
if sliced.is_empty() {
107108
continue;
108109
}
109110

110-
return self.read_mask(row_mask.slice(begin, end));
111+
return self.read_mask(sliced);
111112
}
112113

113114
Ok(None)
@@ -197,10 +198,15 @@ impl Iterator for FixedSplitIterator {
197198
// Find next range that's not filtered out by supplied row_mask
198199
for (begin, end) in ranges {
199200
return if let Some(ref row_mask) = self.row_mask {
200-
if row_mask.slice(begin, end).is_empty() {
201+
let sliced = match row_mask.slice(begin, end) {
202+
Ok(s) => s,
203+
Err(e) => return Some(Err(e)),
204+
};
205+
206+
if sliced.is_empty() {
201207
continue;
202208
}
203-
Some(Ok(SplitMask::Mask(row_mask.slice(begin, end))))
209+
Some(Ok(SplitMask::Mask(sliced)))
204210
} else {
205211
Some(Ok(SplitMask::Mask(RowMask::new_valid_between(begin, end))))
206212
};

0 commit comments

Comments
 (0)