Skip to content

Commit 9f76879

Browse files
committed
refactor(array): propagate allocators through builders
Signed-off-by: Nicholas Gates <nick@nickgates.com>
1 parent ea37874 commit 9f76879

16 files changed

Lines changed: 394 additions & 70 deletions

File tree

vortex-array/src/builders/bool.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::any::Any;
55
use std::mem;
66

77
use vortex_buffer::BitBufferMut;
8+
use vortex_buffer::BufferAllocatorRef;
89
use vortex_error::VortexResult;
910
use vortex_error::vortex_ensure;
1011

@@ -33,9 +34,22 @@ impl BoolBuilder {
3334
}
3435

3536
pub fn with_capacity(nullability: Nullability, capacity: usize) -> Self {
37+
Self::with_capacity_in(
38+
nullability,
39+
capacity,
40+
BufferAllocatorRef::statically_allocated(),
41+
)
42+
}
43+
44+
/// Creates a builder with the given capacity and allocator.
45+
pub fn with_capacity_in(
46+
nullability: Nullability,
47+
capacity: usize,
48+
allocator: BufferAllocatorRef,
49+
) -> Self {
3650
Self {
37-
inner: BitBufferMut::with_capacity(capacity),
38-
nulls: LazyBitBufferBuilder::new(capacity),
51+
inner: BitBufferMut::with_capacity_in(capacity, allocator.clone()),
52+
nulls: LazyBitBufferBuilder::new_in(capacity, allocator),
3953
dtype: DType::Bool(nullability),
4054
}
4155
}
@@ -61,8 +75,10 @@ impl BoolBuilder {
6175
"Null count and value count should match when calling BoolBuilder::finish."
6276
);
6377

78+
let allocator = self.inner.allocator().clone();
79+
let inner = mem::replace(&mut self.inner, BitBufferMut::empty_in(allocator)).freeze();
6480
BoolArray::new(
65-
mem::take(&mut self.inner).freeze(),
81+
inner,
6682
self.nulls.finish_with_nullability(self.dtype.nullability()),
6783
)
6884
}

vortex-array/src/builders/child.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: Apache-2.0
22
// SPDX-FileCopyrightText: Copyright the Vortex contributors
33

4+
use vortex_buffer::BufferAllocatorRef;
45
use vortex_error::VortexResult;
56
use vortex_error::vortex_ensure;
67

@@ -9,7 +10,7 @@ use crate::ExecutionCtx;
910
use crate::IntoArray;
1011
use crate::arrays::ChunkedArray;
1112
use crate::builders::ArrayBuilder;
12-
use crate::builders::builder_with_capacity;
13+
use crate::builders::builder_with_capacity_in;
1314
use crate::dtype::DType;
1415
use crate::scalar::Scalar;
1516

@@ -42,12 +43,18 @@ pub struct ChildBuilder {
4243

4344
impl ChildBuilder {
4445
/// Creates a new `ChildBuilder` whose scalar builder is pre-allocated for `capacity` values.
46+
#[cfg(test)]
4547
pub fn with_capacity(dtype: &DType, capacity: usize) -> Self {
48+
Self::with_capacity_in(BufferAllocatorRef::statically_allocated(), dtype, capacity)
49+
}
50+
51+
/// Creates a child builder with the provided allocator.
52+
pub fn with_capacity_in(allocator: BufferAllocatorRef, dtype: &DType, capacity: usize) -> Self {
4653
Self {
4754
dtype: dtype.clone(),
4855
chunks: Vec::new(),
4956
chunks_len: 0,
50-
pending: builder_with_capacity(dtype, capacity),
57+
pending: builder_with_capacity_in(allocator, dtype, capacity),
5158
}
5259
}
5360

vortex-array/src/builders/decimal.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use std::any::Any;
55

6+
use vortex_buffer::BufferAllocatorRef;
67
use vortex_buffer::BufferMut;
78
use vortex_error::VortexExpect;
89
use vortex_error::VortexResult;
@@ -103,13 +104,31 @@ impl DecimalBuilder {
103104
capacity: usize,
104105
decimal: DecimalDType,
105106
nullability: Nullability,
107+
) -> Self {
108+
Self::with_capacity_in::<T>(
109+
capacity,
110+
decimal,
111+
nullability,
112+
BufferAllocatorRef::statically_allocated(),
113+
)
114+
}
115+
116+
/// Creates a decimal builder with the given capacity and allocator.
117+
pub fn with_capacity_in<T: NativeDecimalType>(
118+
capacity: usize,
119+
decimal: DecimalDType,
120+
nullability: Nullability,
121+
allocator: BufferAllocatorRef,
106122
) -> Self {
107123
Self {
108124
dtype: DType::Decimal(decimal, nullability),
109125
values: match_each_decimal_value_type!(T::DECIMAL_TYPE, |D| {
110-
DecimalBuffer::from(BufferMut::<D>::with_capacity(capacity))
126+
DecimalBuffer::from(BufferMut::<D>::with_capacity_in(
127+
capacity,
128+
allocator.clone(),
129+
))
111130
}),
112-
nulls: LazyBitBufferBuilder::new(capacity),
131+
nulls: LazyBitBufferBuilder::new_in(capacity, allocator),
113132
}
114133
}
115134

@@ -153,7 +172,7 @@ impl DecimalBuilder {
153172

154173
let decimal_dtype = *self.decimal_dtype();
155174

156-
delegate_fn!(std::mem::take(&mut self.values), |T, values| {
175+
delegate_fn!(self.values.take(), |T, values| {
157176
DecimalArray::new::<T>(values.freeze(), decimal_dtype, validity)
158177
})
159178
}
@@ -228,6 +247,13 @@ impl ArrayBuilder for DecimalBuilder {
228247
}
229248

230249
impl DecimalBuffer {
250+
fn take(&mut self) -> Self {
251+
delegate_fn!(self, |T, buffer| {
252+
let allocator = buffer.allocator();
253+
DecimalBuffer::from(std::mem::replace(buffer, allocator.with_capacity(0)))
254+
})
255+
}
256+
231257
fn push<V: NativeDecimalType>(&mut self, value: V) {
232258
delegate_fn!(self, |T, buffer| {
233259
buffer.push(
@@ -291,12 +317,6 @@ impl_from_buffer!(i64, I64);
291317
impl_from_buffer!(i128, I128);
292318
impl_from_buffer!(i256, I256);
293319

294-
impl Default for DecimalBuffer {
295-
fn default() -> Self {
296-
Self::I8(BufferMut::<i8>::empty())
297-
}
298-
}
299-
300320
#[cfg(test)]
301321
mod tests {
302322
use crate::VortexSessionExecute;

vortex-array/src/builders/extension.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use std::any::Any;
55

6+
use vortex_buffer::BufferAllocatorRef;
67
use vortex_error::VortexResult;
78
use vortex_error::vortex_ensure;
89

@@ -34,8 +35,21 @@ impl ExtensionBuilder {
3435

3536
/// Creates a new `ExtensionBuilder` with the given `capacity`.
3637
pub fn with_capacity(ext_dtype: ExtDTypeRef, capacity: usize) -> Self {
38+
Self::with_capacity_in(
39+
ext_dtype,
40+
capacity,
41+
BufferAllocatorRef::statically_allocated(),
42+
)
43+
}
44+
45+
/// Creates an extension builder with the provided allocator.
46+
pub fn with_capacity_in(
47+
ext_dtype: ExtDTypeRef,
48+
capacity: usize,
49+
allocator: BufferAllocatorRef,
50+
) -> Self {
3751
Self {
38-
storage: ChildBuilder::with_capacity(ext_dtype.storage_dtype(), capacity),
52+
storage: ChildBuilder::with_capacity_in(allocator, ext_dtype.storage_dtype(), capacity),
3953
dtype: DType::Extension(ext_dtype),
4054
}
4155
}

vortex-array/src/builders/fixed_size_list.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use std::any::Any;
55
use std::sync::Arc;
66

7+
use vortex_buffer::BufferAllocatorRef;
78
use vortex_error::VortexExpect;
89
use vortex_error::VortexResult;
910
use vortex_error::vortex_bail;
@@ -59,12 +60,30 @@ impl FixedSizeListBuilder {
5960
list_size: u32,
6061
nullability: Nullability,
6162
capacity: usize,
63+
) -> Self {
64+
Self::with_capacity_in(
65+
element_dtype,
66+
list_size,
67+
nullability,
68+
capacity,
69+
BufferAllocatorRef::statically_allocated(),
70+
)
71+
}
72+
73+
/// Creates a fixed-size-list builder with the provided allocator.
74+
pub fn with_capacity_in(
75+
element_dtype: Arc<DType>,
76+
list_size: u32,
77+
nullability: Nullability,
78+
capacity: usize,
79+
allocator: BufferAllocatorRef,
6280
) -> Self {
6381
let elements_capacity = capacity * list_size as usize;
6482

65-
let elements_builder = ChildBuilder::with_capacity(&element_dtype, elements_capacity);
83+
let elements_builder =
84+
ChildBuilder::with_capacity_in(allocator.clone(), &element_dtype, elements_capacity);
6685
let fsl_dtype = DType::FixedSizeList(element_dtype, list_size, nullability);
67-
let nulls = ValidityBuilder::new(capacity);
86+
let nulls = ValidityBuilder::new_in(capacity, allocator);
6887

6988
Self {
7089
dtype: fsl_dtype,

vortex-array/src/builders/lazy_null_builder.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use vortex_buffer::BitBuffer;
55
use vortex_buffer::BitBufferMut;
6+
use vortex_buffer::BufferAllocatorRef;
67
use vortex_error::VortexExpect;
78
use vortex_error::vortex_panic;
89
use vortex_mask::Mask;
@@ -18,16 +19,23 @@ pub struct LazyBitBufferBuilder {
1819
inner: Option<BitBufferMut>,
1920
len: usize,
2021
capacity: usize,
22+
allocator: BufferAllocatorRef,
2123
}
2224

2325
impl LazyBitBufferBuilder {
2426
/// Creates a new empty builder.
2527
/// `capacity` is the number of bits in the null buffer.
2628
pub fn new(capacity: usize) -> Self {
29+
Self::new_in(capacity, BufferAllocatorRef::statically_allocated())
30+
}
31+
32+
/// Creates a new empty builder with the provided allocator.
33+
pub fn new_in(capacity: usize, allocator: BufferAllocatorRef) -> Self {
2734
Self {
2835
inner: None,
2936
len: 0,
3037
capacity,
38+
allocator,
3139
}
3240
}
3341

@@ -148,7 +156,8 @@ impl LazyBitBufferBuilder {
148156
#[inline(never)]
149157
fn materialize(&mut self) {
150158
if self.inner.is_none() {
151-
let mut bit_mut = BitBufferMut::with_capacity(self.len.max(self.capacity));
159+
let mut bit_mut =
160+
BitBufferMut::with_capacity_in(self.len.max(self.capacity), self.allocator.clone());
152161
bit_mut.append_n(true, self.len);
153162
self.inner = Some(bit_mut);
154163
}

vortex-array/src/builders/list.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::any::Any;
55
use std::sync::Arc;
66

77
use num_traits::AsPrimitive;
8+
use vortex_buffer::BufferAllocatorRef;
89
use vortex_error::VortexExpect;
910
use vortex_error::VortexResult;
1011
use vortex_error::vortex_bail;
@@ -80,16 +81,38 @@ impl<O: OffsetBuilderPType> ListBuilder<O> {
8081
elements_capacity: usize,
8182
capacity: usize,
8283
) -> Self {
83-
let elements_builder = ChildBuilder::with_capacity(value_dtype.as_ref(), elements_capacity);
84-
let mut offsets_builder = PrimitiveBuilder::<O>::with_capacity(NonNullable, capacity + 1);
84+
Self::with_capacity_in(
85+
value_dtype,
86+
nullability,
87+
elements_capacity,
88+
capacity,
89+
BufferAllocatorRef::statically_allocated(),
90+
)
91+
}
92+
93+
/// Creates a list builder with the provided allocator.
94+
pub fn with_capacity_in(
95+
value_dtype: Arc<DType>,
96+
nullability: Nullability,
97+
elements_capacity: usize,
98+
capacity: usize,
99+
allocator: BufferAllocatorRef,
100+
) -> Self {
101+
let elements_builder = ChildBuilder::with_capacity_in(
102+
allocator.clone(),
103+
value_dtype.as_ref(),
104+
elements_capacity,
105+
);
106+
let mut offsets_builder =
107+
PrimitiveBuilder::<O>::with_capacity_in(NonNullable, capacity + 1, allocator.clone());
85108

86109
// The first offset is always 0 and represents an empty list.
87110
offsets_builder.append_zero();
88111

89112
Self {
90113
elements_builder,
91114
offsets_builder,
92-
nulls: ValidityBuilder::new(capacity),
115+
nulls: ValidityBuilder::new_in(capacity, allocator),
93116
dtype: DType::List(value_dtype, nullability),
94117
}
95118
}

vortex-array/src/builders/listview.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use std::sync::Arc;
1414

1515
use num_traits::ToPrimitive;
16+
use vortex_buffer::BufferAllocatorRef;
1617
use vortex_error::VortexExpect;
1718
use vortex_error::VortexResult;
1819
use vortex_error::vortex_ensure;
@@ -104,14 +105,38 @@ impl<O: OffsetBuilderPType, S: OffsetBuilderPType> ListViewBuilder<O, S> {
104105
elements_capacity: usize,
105106
capacity: usize,
106107
) -> Self {
107-
let elements_builder = ChildBuilder::with_capacity(&element_dtype, elements_capacity);
108+
Self::with_capacity_in(
109+
element_dtype,
110+
nullability,
111+
elements_capacity,
112+
capacity,
113+
BufferAllocatorRef::statically_allocated(),
114+
)
115+
}
116+
117+
/// Creates a list-view builder with the provided allocator.
118+
pub fn with_capacity_in(
119+
element_dtype: Arc<DType>,
120+
nullability: Nullability,
121+
elements_capacity: usize,
122+
capacity: usize,
123+
allocator: BufferAllocatorRef,
124+
) -> Self {
125+
let elements_builder =
126+
ChildBuilder::with_capacity_in(allocator.clone(), &element_dtype, elements_capacity);
108127

109-
let offsets_builder =
110-
PrimitiveBuilder::<O>::with_capacity(Nullability::NonNullable, capacity);
111-
let sizes_builder =
112-
PrimitiveBuilder::<S>::with_capacity(Nullability::NonNullable, capacity);
128+
let offsets_builder = PrimitiveBuilder::<O>::with_capacity_in(
129+
Nullability::NonNullable,
130+
capacity,
131+
allocator.clone(),
132+
);
133+
let sizes_builder = PrimitiveBuilder::<S>::with_capacity_in(
134+
Nullability::NonNullable,
135+
capacity,
136+
allocator.clone(),
137+
);
113138

114-
let nulls = ValidityBuilder::new(capacity);
139+
let nulls = ValidityBuilder::new_in(capacity, allocator);
115140

116141
Self {
117142
dtype: DType::List(element_dtype, nullability),

0 commit comments

Comments
 (0)