vortex_array/builders/
mod.rs1mod bool;
2mod extension;
3mod lazy_validity_builder;
4mod list;
5mod null;
6mod primitive;
7mod struct_;
8mod varbinview;
9
10use std::any::Any;
11
12pub use bool::*;
13pub use extension::*;
14pub use list::*;
15pub use null::*;
16pub use primitive::*;
17pub use varbinview::*;
18use vortex_dtype::{DType, match_each_native_ptype};
19use vortex_error::{VortexResult, vortex_bail, vortex_err};
20use vortex_mask::Mask;
21use vortex_scalar::{
22 BinaryScalar, BoolScalar, ExtScalar, ListScalar, PrimitiveScalar, Scalar, ScalarValue,
23 StructScalar, Utf8Scalar,
24};
25
26use crate::builders::struct_::StructBuilder;
27use crate::{Array, ArrayRef};
28
29pub trait ArrayBuilder: Send {
30 fn as_any(&self) -> &dyn Any;
31
32 fn as_any_mut(&mut self) -> &mut dyn Any;
33
34 fn dtype(&self) -> &DType;
35
36 fn len(&self) -> usize;
37
38 fn is_empty(&self) -> bool {
39 self.len() == 0
40 }
41
42 fn append_zero(&mut self) {
44 self.append_zeros(1)
45 }
46
47 fn append_zeros(&mut self, n: usize);
49
50 fn append_null(&mut self) {
52 self.append_nulls(1)
53 }
54
55 fn append_nulls(&mut self, n: usize);
57
58 fn extend_from_array(&mut self, array: &dyn Array) -> VortexResult<()>;
60
61 fn ensure_capacity(&mut self, capacity: usize);
63
64 fn set_validity(&mut self, validity: Mask);
66
67 fn finish(&mut self) -> ArrayRef;
77}
78
79pub fn builder_with_capacity(dtype: &DType, capacity: usize) -> Box<dyn ArrayBuilder> {
80 match dtype {
81 DType::Null => Box::new(NullBuilder::new()),
82 DType::Bool(n) => Box::new(BoolBuilder::with_capacity(*n, capacity)),
83 DType::Primitive(ptype, n) => {
84 match_each_native_ptype!(ptype, |$P| {
85 Box::new(PrimitiveBuilder::<$P>::with_capacity(*n, capacity))
86 })
87 }
88 DType::Utf8(n) => Box::new(VarBinViewBuilder::with_capacity(DType::Utf8(*n), capacity)),
89 DType::Binary(n) => Box::new(VarBinViewBuilder::with_capacity(
90 DType::Binary(*n),
91 capacity,
92 )),
93 DType::Struct(struct_dtype, n) => Box::new(StructBuilder::with_capacity(
94 struct_dtype.clone(),
95 *n,
96 capacity,
97 )),
98 DType::List(dtype, n) => Box::new(ListBuilder::<u64>::with_capacity(
99 dtype.clone(),
100 *n,
101 capacity,
102 )),
103 DType::Extension(ext_dtype) => {
104 Box::new(ExtensionBuilder::with_capacity(ext_dtype.clone(), capacity))
105 }
106 }
107}
108
109pub trait ArrayBuilderExt: ArrayBuilder {
110 fn append_scalar_value(&mut self, value: ScalarValue) -> VortexResult<()> {
112 if value.is_null() {
113 self.append_null();
114 Ok(())
115 } else {
116 self.append_scalar(&Scalar::new(self.dtype().clone(), value))
117 }
118 }
119
120 fn append_scalar(&mut self, scalar: &Scalar) -> VortexResult<()> {
122 if scalar.dtype() != self.dtype() {
123 vortex_bail!(
124 "Builder has dtype {:?}, scalar has {:?}",
125 self.dtype(),
126 scalar.dtype()
127 )
128 }
129 match scalar.dtype() {
130 DType::Null => self
131 .as_any_mut()
132 .downcast_mut::<NullBuilder>()
133 .ok_or_else(|| vortex_err!("Cannot append null scalar to non-null builder"))?
134 .append_null(),
135 DType::Bool(_) => self
136 .as_any_mut()
137 .downcast_mut::<BoolBuilder>()
138 .ok_or_else(|| vortex_err!("Cannot append bool scalar to non-bool builder"))?
139 .append_option(BoolScalar::try_from(scalar)?.value()),
140 DType::Primitive(ptype, ..) => {
141 match_each_native_ptype!(ptype, |$P| {
142 self
143 .as_any_mut()
144 .downcast_mut::<PrimitiveBuilder<$P>>()
145 .ok_or_else(|| {
146 vortex_err!("Cannot append primitive scalar to non-primitive builder")
147 })?
148 .append_option(PrimitiveScalar::try_from(scalar)?.typed_value::<$P>())
149 })
150 }
151 DType::Utf8(_) => self
152 .as_any_mut()
153 .downcast_mut::<VarBinViewBuilder>()
154 .ok_or_else(|| vortex_err!("Cannot append utf8 scalar to non-utf8 builder"))?
155 .append_option(Utf8Scalar::try_from(scalar)?.value()),
156 DType::Binary(_) => self
157 .as_any_mut()
158 .downcast_mut::<VarBinViewBuilder>()
159 .ok_or_else(|| vortex_err!("Cannot append binary scalar to non-binary builder"))?
160 .append_option(BinaryScalar::try_from(scalar)?.value()),
161 DType::Struct(..) => self
162 .as_any_mut()
163 .downcast_mut::<StructBuilder>()
164 .ok_or_else(|| vortex_err!("Cannot append struct scalar to non-struct builder"))?
165 .append_value(StructScalar::try_from(scalar)?)?,
166 DType::List(..) => self
167 .as_any_mut()
168 .downcast_mut::<ListBuilder<u64>>()
169 .ok_or_else(|| vortex_err!("Cannot append list scalar to non-list builder"))?
170 .append_value(ListScalar::try_from(scalar)?)?,
171 DType::Extension(..) => self
172 .as_any_mut()
173 .downcast_mut::<ExtensionBuilder>()
174 .ok_or_else(|| {
175 vortex_err!("Cannot append extension scalar to non-extension builder")
176 })?
177 .append_value(ExtScalar::try_from(scalar)?)?,
178 }
179 Ok(())
180 }
181}
182
183impl<T: ?Sized + ArrayBuilder> ArrayBuilderExt for T {}