Skip to content

Commit b3bbc1c

Browse files
committed
Introduce PrimitiveArrayBuilder::build(), avoid use of ArrayData
1 parent 06c411f commit b3bbc1c

File tree

2 files changed

+57
-16
lines changed

2 files changed

+57
-16
lines changed

arrow-array/src/array/primitive_array.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,22 @@ impl<T: ArrowPrimitiveType> PrimitiveArray<T> {
636636
Self::try_new(values, nulls).unwrap()
637637
}
638638

639+
/// Create a [`PrimitiveArray`] from the provided data type, values and nulls
640+
///
641+
/// panic's if the type is not compatible
642+
pub(crate) fn new_with_datatype(
643+
data_type: DataType,
644+
values: ScalarBuffer<T::Native>,
645+
nulls: Option<NullBuffer>,
646+
) -> Self {
647+
Self::assert_compatible(&data_type);
648+
Self {
649+
data_type,
650+
values,
651+
nulls,
652+
}
653+
}
654+
639655
/// Create a new [`PrimitiveArray`] of the given length where all values are null
640656
pub fn new_null(length: usize) -> Self {
641657
Self {

arrow-array/src/builder/primitive_builder.rs

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use crate::builder::ArrayBuilder;
1919
use crate::types::*;
2020
use crate::{Array, ArrayRef, PrimitiveArray};
2121
use arrow_buffer::{Buffer, MutableBuffer, NullBufferBuilder, ScalarBuffer};
22-
use arrow_data::ArrayData;
2322
use arrow_schema::{ArrowError, DataType};
2423
use std::any::Any;
2524
use std::sync::Arc;
@@ -300,30 +299,56 @@ impl<T: ArrowPrimitiveType> PrimitiveBuilder<T> {
300299
}
301300

302301
/// Builds the [`PrimitiveArray`] and reset this builder.
302+
///
303+
/// See [`Self::build`] to consume the builder, instead of resetting it.
303304
pub fn finish(&mut self) -> PrimitiveArray<T> {
304-
let len = self.len();
305+
let values_buffer = Buffer::from(std::mem::take(&mut self.values_builder));
305306
let nulls = self.null_buffer_builder.finish();
306-
let builder = ArrayData::builder(self.data_type.clone())
307-
.len(len)
308-
.add_buffer(std::mem::take(&mut self.values_builder).into())
309-
.nulls(nulls);
310-
311-
let array_data = unsafe { builder.build_unchecked() };
312-
PrimitiveArray::<T>::from(array_data)
307+
PrimitiveArray::<T>::new_with_datatype(
308+
self.data_type.clone(),
309+
ScalarBuffer::from(values_buffer),
310+
nulls,
311+
)
313312
}
314313

315314
/// Builds the [`PrimitiveArray`] without resetting the builder.
316315
pub fn finish_cloned(&self) -> PrimitiveArray<T> {
317-
let len = self.len();
318316
let nulls = self.null_buffer_builder.finish_cloned();
319317
let values_buffer = Buffer::from_slice_ref(self.values_builder.as_slice());
320-
let builder = ArrayData::builder(self.data_type.clone())
321-
.len(len)
322-
.add_buffer(values_buffer)
323-
.nulls(nulls);
318+
PrimitiveArray::<T>::new_with_datatype(
319+
self.data_type.clone(),
320+
ScalarBuffer::from(values_buffer),
321+
nulls,
322+
)
323+
}
324324

325-
let array_data = unsafe { builder.build_unchecked() };
326-
PrimitiveArray::<T>::from(array_data)
325+
/// Builds the [`PrimitiveArray`] , consuming this builder.
326+
///
327+
/// Use [`Self::finish`] to reuse the builder
328+
///
329+
/// # Example:
330+
///
331+
/// ```
332+
/// # use arrow_array::builder::UInt8Builder;
333+
/// use arrow_array::UInt8Array;
334+
/// let mut builder = UInt8Builder::with_capacity(5);
335+
/// builder.append_slice(&[42, 44, 46]);
336+
/// builder.append_nulls(2);
337+
/// let array = builder.build();
338+
/// assert_eq!(UInt8Array::from(vec![Some(42), Some(44), Some(46), None, None]), array);
339+
/// ```
340+
#[inline]
341+
pub fn build(self) -> PrimitiveArray<T> {
342+
let Self {
343+
values_builder,
344+
null_buffer_builder,
345+
data_type,
346+
} = self;
347+
PrimitiveArray::new_with_datatype(
348+
data_type, // reuse data_type to save a DataType::drop()
349+
ScalarBuffer::from(values_builder),
350+
null_buffer_builder.build(),
351+
)
327352
}
328353

329354
/// Returns the current values buffer as a slice

0 commit comments

Comments
 (0)