Skip to content

Commit 9aa382e

Browse files
committed
fix from_iter impls in vectors
Signed-off-by: Connor Tsui <[email protected]>
1 parent e570ee4 commit 9aa382e

File tree

2 files changed

+24
-16
lines changed

2 files changed

+24
-16
lines changed

vortex-vector/src/bool/from_iter.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,31 @@ impl FromIterator<Option<bool>> for BoolVectorMut {
2626
I: IntoIterator<Item = Option<bool>>,
2727
{
2828
let iter = iter.into_iter();
29-
let (lower_bound, _) = iter.size_hint();
29+
// Since we do not know the length of the iterator, we can only guess how much memory we
30+
// need to reserve. Note that these hints may be inaccurate.
31+
let (lower_bound, upper_bound_opt) = iter.size_hint();
3032

31-
let mut bits = Vec::with_capacity(lower_bound);
32-
let mut validity = MaskMut::with_capacity(lower_bound);
33+
// In the case that the upper bound is adversarial, we put a hard limit on the amount of
34+
// memory we reserve (and the OS should handle the rest with zero pages).
35+
let reserve_amount = upper_bound_opt.unwrap_or(lower_bound);
36+
37+
let mut bits = BitBufferMut::with_capacity(reserve_amount);
38+
let mut validity = MaskMut::with_capacity(reserve_amount);
3339

3440
for opt_val in iter {
3541
match opt_val {
3642
Some(val) => {
37-
bits.push(val);
43+
bits.append(val);
3844
validity.append_n(true, 1);
3945
}
4046
None => {
41-
bits.push(false); // Value doesn't matter for invalid entries.
47+
bits.append(false); // Value doesn't matter for invalid entries.
4248
validity.append_n(false, 1);
4349
}
4450
}
4551
}
4652

47-
BoolVectorMut {
48-
bits: BitBufferMut::from_iter(bits),
49-
validity,
50-
}
53+
BoolVectorMut { bits, validity }
5154
}
5255
}
5356

vortex-vector/src/primitive/from_iter.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,18 @@ impl<T: NativePType> FromIterator<Option<T>> for PVectorMut<T> {
2727
I: IntoIterator<Item = Option<T>>,
2828
{
2929
let iter = iter.into_iter();
30-
let (lower_bound, _) = iter.size_hint();
30+
// Since we do not know the length of the iterator, we can only guess how much memory we
31+
// need to reserve. Note that these hints may be inaccurate.
32+
let (lower_bound, upper_bound_opt) = iter.size_hint();
3133

32-
let mut elements = Vec::with_capacity(lower_bound);
33-
let mut validity = MaskMut::with_capacity(lower_bound);
34+
// In the case that the upper bound is adversarial, we put a hard limit on the amount of
35+
// memory we reserve (and the OS should handle the rest with zero pages).
36+
let reserve_amount = upper_bound_opt
37+
.unwrap_or(lower_bound)
38+
.min(i32::MAX as usize);
39+
40+
let mut elements = BufferMut::with_capacity(reserve_amount);
41+
let mut validity = MaskMut::with_capacity(reserve_amount);
3442

3543
for opt_val in iter {
3644
match opt_val {
@@ -45,10 +53,7 @@ impl<T: NativePType> FromIterator<Option<T>> for PVectorMut<T> {
4553
}
4654
}
4755

48-
PVectorMut {
49-
elements: BufferMut::from_iter(elements),
50-
validity,
51-
}
56+
PVectorMut { elements, validity }
5257
}
5358
}
5459

0 commit comments

Comments
 (0)