Skip to content

Commit

Permalink
Split out of decimal_builder (apache#1843)
Browse files Browse the repository at this point in the history
  • Loading branch information
tustvold committed Jun 23, 2022
1 parent 2b34eb3 commit 787117d
Show file tree
Hide file tree
Showing 5 changed files with 319 additions and 309 deletions.
318 changes: 33 additions & 285 deletions arrow/src/array/builder/decimal_builder.rs
Expand Up @@ -18,19 +18,13 @@
use std::any::Any;
use std::sync::Arc;

use crate::array::ArrayBuilder;
use crate::array::ArrayRef;
use crate::array::DecimalArray;
use crate::array::FixedSizeBinaryArray;
use crate::array::OffsetSizeTrait;
use crate::array::UInt8Builder;
use crate::array::{GenericBinaryArray, GenericStringArray};
use crate::array::{ArrayBuilder, FixedSizeListBuilder};

use crate::error::{ArrowError, Result};

use super::{FixedSizeBinaryBuilder, FixedSizeListBuilder};
use super::{GenericBinaryBuilder, GenericListBuilder, GenericStringBuilder};

use crate::datatypes::validate_decimal_precision;

/// Array Builder for [`DecimalArray`]
Expand All @@ -48,284 +42,6 @@ pub struct DecimalBuilder {
value_validation: bool,
}

impl<OffsetSize: OffsetSizeTrait> ArrayBuilder for GenericBinaryBuilder<OffsetSize> {
/// Returns the builder as a non-mutable `Any` reference.
fn as_any(&self) -> &dyn Any {
self
}

/// Returns the builder as a mutable `Any` reference.
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}

/// Returns the boxed builder as a box of `Any`.
fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
self
}

/// Returns the number of array slots in the builder
fn len(&self) -> usize {
self.builder.len()
}

/// Returns whether the number of array slots is zero
fn is_empty(&self) -> bool {
self.builder.is_empty()
}

/// Builds the array and reset this builder.
fn finish(&mut self) -> ArrayRef {
Arc::new(self.finish())
}
}

impl<OffsetSize: OffsetSizeTrait> ArrayBuilder for GenericStringBuilder<OffsetSize> {
/// Returns the builder as a non-mutable `Any` reference.
fn as_any(&self) -> &dyn Any {
self
}

/// Returns the builder as a mutable `Any` reference.
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}

/// Returns the boxed builder as a box of `Any`.
fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
self
}

/// Returns the number of array slots in the builder
fn len(&self) -> usize {
self.builder.len()
}

/// Returns whether the number of array slots is zero
fn is_empty(&self) -> bool {
self.builder.is_empty()
}

/// Builds the array and reset this builder.
fn finish(&mut self) -> ArrayRef {
let a = GenericStringBuilder::<OffsetSize>::finish(self);
Arc::new(a)
}
}

impl ArrayBuilder for FixedSizeBinaryBuilder {
/// Returns the builder as a non-mutable `Any` reference.
fn as_any(&self) -> &dyn Any {
self
}

/// Returns the builder as a mutable `Any` reference.
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}

/// Returns the boxed builder as a box of `Any`.
fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
self
}

/// Returns the number of array slots in the builder
fn len(&self) -> usize {
self.builder.len()
}

/// Returns whether the number of array slots is zero
fn is_empty(&self) -> bool {
self.builder.is_empty()
}

/// Builds the array and reset this builder.
fn finish(&mut self) -> ArrayRef {
Arc::new(self.finish())
}
}

impl ArrayBuilder for DecimalBuilder {
/// Returns the builder as a non-mutable `Any` reference.
fn as_any(&self) -> &dyn Any {
self
}

/// Returns the builder as a mutable `Any` reference.
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}

/// Returns the boxed builder as a box of `Any`.
fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
self
}

/// Returns the number of array slots in the builder
fn len(&self) -> usize {
self.builder.len()
}

/// Returns whether the number of array slots is zero
fn is_empty(&self) -> bool {
self.builder.is_empty()
}

/// Builds the array and reset this builder.
fn finish(&mut self) -> ArrayRef {
Arc::new(self.finish())
}
}

impl<OffsetSize: OffsetSizeTrait> GenericBinaryBuilder<OffsetSize> {
/// Creates a new `GenericBinaryBuilder`, `capacity` is the number of bytes in the values
/// array
pub fn new(capacity: usize) -> Self {
let values_builder = UInt8Builder::new(capacity);
Self {
builder: GenericListBuilder::new(values_builder),
}
}

/// Appends a single byte value into the builder's values array.
///
/// Note, when appending individual byte values you must call `append` to delimit each
/// distinct list value.
#[inline]
pub fn append_byte(&mut self, value: u8) -> Result<()> {
self.builder.values().append_value(value)?;
Ok(())
}

/// Appends a byte slice into the builder.
///
/// Automatically calls the `append` method to delimit the slice appended in as a
/// distinct array element.
#[inline]
pub fn append_value(&mut self, value: impl AsRef<[u8]>) -> Result<()> {
self.builder.values().append_slice(value.as_ref())?;
self.builder.append(true)?;
Ok(())
}

/// Finish the current variable-length list array slot.
#[inline]
pub fn append(&mut self, is_valid: bool) -> Result<()> {
self.builder.append(is_valid)
}

/// Append a null value to the array.
#[inline]
pub fn append_null(&mut self) -> Result<()> {
self.append(false)
}

/// Builds the `BinaryArray` and reset this builder.
pub fn finish(&mut self) -> GenericBinaryArray<OffsetSize> {
GenericBinaryArray::<OffsetSize>::from(self.builder.finish())
}
}

impl<OffsetSize: OffsetSizeTrait> GenericStringBuilder<OffsetSize> {
/// Creates a new `StringBuilder`,
/// `capacity` is the number of bytes of string data to pre-allocate space for in this builder
pub fn new(capacity: usize) -> Self {
let values_builder = UInt8Builder::new(capacity);
Self {
builder: GenericListBuilder::new(values_builder),
}
}

/// Creates a new `StringBuilder`,
/// `data_capacity` is the number of bytes of string data to pre-allocate space for in this builder
/// `item_capacity` is the number of items to pre-allocate space for in this builder
pub fn with_capacity(item_capacity: usize, data_capacity: usize) -> Self {
let values_builder = UInt8Builder::new(data_capacity);
Self {
builder: GenericListBuilder::with_capacity(values_builder, item_capacity),
}
}

/// Appends a string into the builder.
///
/// Automatically calls the `append` method to delimit the string appended in as a
/// distinct array element.
#[inline]
pub fn append_value(&mut self, value: impl AsRef<str>) -> Result<()> {
self.builder
.values()
.append_slice(value.as_ref().as_bytes())?;
self.builder.append(true)?;
Ok(())
}

/// Finish the current variable-length list array slot.
#[inline]
pub fn append(&mut self, is_valid: bool) -> Result<()> {
self.builder.append(is_valid)
}

/// Append a null value to the array.
#[inline]
pub fn append_null(&mut self) -> Result<()> {
self.append(false)
}

/// Append an `Option` value to the array.
#[inline]
pub fn append_option(&mut self, value: Option<impl AsRef<str>>) -> Result<()> {
match value {
None => self.append_null()?,
Some(v) => self.append_value(v)?,
};
Ok(())
}

/// Builds the `StringArray` and reset this builder.
pub fn finish(&mut self) -> GenericStringArray<OffsetSize> {
GenericStringArray::<OffsetSize>::from(self.builder.finish())
}
}

impl FixedSizeBinaryBuilder {
/// Creates a new `BinaryBuilder`, `capacity` is the number of bytes in the values
/// array
pub fn new(capacity: usize, byte_width: i32) -> Self {
let values_builder = UInt8Builder::new(capacity);
Self {
builder: FixedSizeListBuilder::new(values_builder, byte_width),
}
}

/// Appends a byte slice into the builder.
///
/// Automatically calls the `append` method to delimit the slice appended in as a
/// distinct array element.
#[inline]
pub fn append_value(&mut self, value: impl AsRef<[u8]>) -> Result<()> {
if self.builder.value_length() != value.as_ref().len() as i32 {
return Err(ArrowError::InvalidArgumentError(
"Byte slice does not have the same length as FixedSizeBinaryBuilder value lengths".to_string()
));
}
self.builder.values().append_slice(value.as_ref())?;
self.builder.append(true)
}

/// Append a null value to the array.
#[inline]
pub fn append_null(&mut self) -> Result<()> {
let length: usize = self.builder.value_length() as usize;
self.builder.values().append_slice(&vec![0u8; length][..])?;
self.builder.append(false)
}

/// Builds the `FixedSizeBinaryArray` and reset this builder.
pub fn finish(&mut self) -> FixedSizeBinaryArray {
FixedSizeBinaryArray::from(self.builder.finish())
}
}

impl DecimalBuilder {
/// Creates a new `BinaryBuilder`, `capacity` is the number of bytes in the values
/// array
Expand Down Expand Up @@ -406,6 +122,38 @@ impl DecimalBuilder {
}
}

impl ArrayBuilder for DecimalBuilder {
/// Returns the builder as a non-mutable `Any` reference.
fn as_any(&self) -> &dyn Any {
self
}

/// Returns the builder as a mutable `Any` reference.
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}

/// Returns the boxed builder as a box of `Any`.
fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
self
}

/// Returns the number of array slots in the builder
fn len(&self) -> usize {
self.builder.len()
}

/// Returns whether the number of array slots is zero
fn is_empty(&self) -> bool {
self.builder.is_empty()
}

/// Builds the array and reset this builder.
fn finish(&mut self) -> ArrayRef {
Arc::new(self.finish())
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit 787117d

Please sign in to comment.