use std::any::Any;
use std::sync::Arc;
use vortex_error::VortexResult;
use vortex_mask::Mask;
use crate::ArrayRef;
use crate::ExecutionCtx;
use crate::canonical::Canonical;
use crate::dtype::DType;
use crate::match_each_decimal_value_type;
use crate::match_each_native_ptype;
use crate::memory::HostAllocatorRef;
use crate::scalar::Scalar;
mod lazy_null_builder;
pub(crate) use lazy_null_builder::LazyBitBufferBuilder;
mod bool;
mod decimal;
pub mod dict;
mod extension;
mod fixed_size_list;
mod list;
mod listview;
mod map;
mod null;
mod primitive;
mod struct_;
mod varbinview;
pub use bool::*;
pub use decimal::*;
pub use extension::*;
pub use fixed_size_list::*;
pub use list::*;
pub use listview::*;
pub use map::*;
pub use null::*;
pub use primitive::*;
pub use struct_::*;
pub use varbinview::*;
pub use crate::arrays::varbin::builder::VarBinBuilder;
#[cfg(test)]
mod tests;
pub const DEFAULT_BUILDER_CAPACITY: usize = 1024;
pub trait ArrayBuilder: Send {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
fn dtype(&self) -> &DType;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn append_zero(&mut self) {
self.append_zeros(1)
}
fn append_zeros(&mut self, n: usize);
fn append_null(&mut self) {
self.append_nulls(1)
}
unsafe fn append_nulls_unchecked(&mut self, n: usize);
fn append_nulls(&mut self, n: usize) {
assert!(
self.dtype().is_nullable(),
"tried to append {n} nulls to a non-nullable array builder"
);
unsafe {
self.append_nulls_unchecked(n);
}
}
fn append_default(&mut self) {
self.append_defaults(1)
}
fn append_defaults(&mut self, n: usize) {
if self.dtype().is_nullable() {
self.append_nulls(n);
} else {
self.append_zeros(n);
}
}
fn append_scalar(&mut self, scalar: &Scalar) -> VortexResult<()>;
fn reserve_exact(&mut self, additional: usize);
fn set_validity(&mut self, validity: Mask) {
if !self.dtype().is_nullable() {
return;
}
assert_eq!(self.len(), validity.len());
unsafe { self.set_validity_unchecked(validity) }
}
unsafe fn set_validity_unchecked(&mut self, validity: Mask);
fn finish(&mut self) -> ArrayRef;
fn finish_into_canonical(&mut self, ctx: &mut ExecutionCtx) -> Canonical;
}
#[macro_export]
macro_rules! match_each_list_builder {
($dyn_builder:expr, | $builder:ident | $body:expr) => {{
let __dyn_builder: &mut dyn $crate::builders::ArrayBuilder = $dyn_builder;
match $crate::__match_each_list_builder!(
__dyn_builder,
$builder,
$body,
[u32, u64, i32, i64]
) {
::core::option::Option::Some(__result) => ::core::option::Option::Some(__result),
::core::option::Option::None => $crate::__match_each_listview_builder!(
__dyn_builder,
$builder,
$body,
[u32, u64, i32, i64]
),
}
}};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __match_each_list_builder {
($target:ident, $builder:ident, $body:expr, []) => {
::core::option::Option::None
};
($target:ident, $builder:ident, $body:expr, [$offset:ty $(, $rest:ty)*]) => {
if let ::core::option::Option::Some($builder) =
$crate::builders::ArrayBuilder::as_any_mut($target)
.downcast_mut::<$crate::builders::ListBuilder<$offset>>()
{
::core::option::Option::Some($body)
} else {
$crate::__match_each_list_builder!($target, $builder, $body, [$($rest),*])
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __match_each_listview_builder {
($target:ident, $builder:ident, $body:expr, []) => {
::core::option::Option::None
};
($target:ident, $builder:ident, $body:expr, [$offset:ty $(, $rest:ty)*]) => {
match $crate::__match_each_listview_builder_size!(
$target,
$builder,
$body,
$offset,
[u32, u64, i32, i64]
) {
::core::option::Option::Some(__result) => ::core::option::Option::Some(__result),
::core::option::Option::None => $crate::__match_each_listview_builder!(
$target,
$builder,
$body,
[$($rest),*]
),
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __match_each_listview_builder_size {
($target:ident, $builder:ident, $body:expr, $offset:ty, []) => {
::core::option::Option::None
};
($target:ident, $builder:ident, $body:expr, $offset:ty, [$size:ty $(, $rest:ty)*]) => {
if let ::core::option::Option::Some($builder) =
$crate::builders::ArrayBuilder::as_any_mut($target)
.downcast_mut::<$crate::builders::ListViewBuilder<$offset, $size>>()
{
::core::option::Option::Some($body)
} else {
$crate::__match_each_listview_builder_size!(
$target, $builder, $body, $offset, [$($rest),*]
)
}
};
}
#[macro_export]
macro_rules! match_each_map_builder {
($dyn_builder:expr, | $builder:ident | $body:expr) => {{
let __dyn_builder: &mut dyn $crate::builders::ArrayBuilder = $dyn_builder;
$crate::__match_each_map_builder!(__dyn_builder, $builder, $body, [u32, u64, i32, i64])
}};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __match_each_map_builder {
($target:ident, $builder:ident, $body:expr, []) => {
::core::option::Option::None
};
($target:ident, $builder:ident, $body:expr, [$offset:ty $(, $rest:ty)*]) => {
match $crate::__match_each_map_builder_size!(
$target,
$builder,
$body,
$offset,
[u32, u64, i32, i64]
) {
::core::option::Option::Some(__result) => ::core::option::Option::Some(__result),
::core::option::Option::None => $crate::__match_each_map_builder!(
$target,
$builder,
$body,
[$($rest),*]
),
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __match_each_map_builder_size {
($target:ident, $builder:ident, $body:expr, $offset:ty, []) => {
::core::option::Option::None
};
($target:ident, $builder:ident, $body:expr, $offset:ty, [$size:ty $(, $rest:ty)*]) => {
if let ::core::option::Option::Some($builder) =
$crate::builders::ArrayBuilder::as_any_mut($target)
.downcast_mut::<$crate::builders::MapBuilder<$offset, $size>>()
{
::core::option::Option::Some($body)
} else {
$crate::__match_each_map_builder_size!(
$target, $builder, $body, $offset, [$($rest),*]
)
}
};
}
pub fn builder_with_capacity(dtype: &DType, capacity: usize) -> Box<dyn ArrayBuilder> {
match dtype {
DType::Null => Box::new(NullBuilder::new()),
DType::Bool(n) => Box::new(BoolBuilder::with_capacity(*n, capacity)),
DType::Primitive(ptype, n) => {
match_each_native_ptype!(ptype, |P| {
Box::new(PrimitiveBuilder::<P>::with_capacity(*n, capacity))
})
}
DType::Decimal(decimal_type, n) => {
match_each_decimal_value_type!(
DecimalType::smallest_decimal_value_type(decimal_type),
|D| {
Box::new(DecimalBuilder::with_capacity::<D>(
capacity,
*decimal_type,
*n,
))
}
)
}
DType::Utf8(n) => Box::new(VarBinViewBuilder::with_capacity(DType::Utf8(*n), capacity)),
DType::Binary(n) => Box::new(VarBinViewBuilder::with_capacity(
DType::Binary(*n),
capacity,
)),
DType::List(dtype, n) => Box::new(ListViewBuilder::<u64, u64>::with_capacity(
Arc::clone(dtype),
*n,
2 * capacity, capacity,
)),
DType::Map(map_dtype, nullability) => Box::new(MapBuilder::<u64, u64>::with_capacity(
map_dtype.clone(),
*nullability,
capacity,
)),
DType::FixedSizeList(elem_dtype, list_size, null) => {
Box::new(FixedSizeListBuilder::with_capacity(
Arc::clone(elem_dtype),
*list_size,
*null,
capacity,
))
}
DType::Struct(struct_dtype, n) => Box::new(StructBuilder::with_capacity(
struct_dtype.clone(),
*n,
capacity,
)),
DType::Union(..) => todo!("TODO(connor)[Union]: unimplemented"),
DType::Variant(_) => {
unimplemented!()
}
DType::Extension(ext_dtype) => {
Box::new(ExtensionBuilder::with_capacity(ext_dtype.clone(), capacity))
}
}
}
pub fn builder_with_capacity_in(
allocator: HostAllocatorRef,
dtype: &DType,
capacity: usize,
) -> Box<dyn ArrayBuilder> {
let _allocator = allocator;
builder_with_capacity(dtype, capacity)
}