vortex_array/builders/
mod.rs1mod bool;
32mod decimal;
33mod extension;
34mod lazy_validity_builder;
35mod list;
36mod null;
37mod primitive;
38mod struct_;
39mod varbinview;
40
41use std::any::Any;
42
43pub use bool::*;
44pub use decimal::*;
45pub use extension::*;
46pub use list::*;
47pub use null::*;
48pub use primitive::*;
49pub use struct_::*;
50pub use varbinview::*;
51use vortex_dtype::{DType, match_each_native_ptype};
52use vortex_error::{VortexResult, vortex_bail, vortex_err};
53use vortex_mask::Mask;
54use vortex_scalar::{
55 BinaryScalar, BoolScalar, DecimalValue, ExtScalar, ListScalar, PrimitiveScalar, Scalar,
56 ScalarValue, StructScalar, Utf8Scalar, match_each_decimal_value, match_each_decimal_value_type,
57};
58
59use crate::arrays::smallest_storage_type;
60use crate::{Array, ArrayRef};
61
62pub trait ArrayBuilder: Send {
63 fn as_any(&self) -> &dyn Any;
64
65 fn as_any_mut(&mut self) -> &mut dyn Any;
66
67 fn dtype(&self) -> &DType;
68
69 fn len(&self) -> usize;
70
71 fn is_empty(&self) -> bool {
72 self.len() == 0
73 }
74
75 fn append_zero(&mut self) {
77 self.append_zeros(1)
78 }
79
80 fn append_zeros(&mut self, n: usize);
82
83 fn append_null(&mut self) {
85 self.append_nulls(1)
86 }
87
88 fn append_nulls(&mut self, n: usize);
90
91 fn extend_from_array(&mut self, array: &dyn Array) -> VortexResult<()>;
93
94 fn ensure_capacity(&mut self, capacity: usize);
96
97 fn set_validity(&mut self, validity: Mask);
99
100 fn finish(&mut self) -> ArrayRef;
110}
111
112pub fn builder_with_capacity(dtype: &DType, capacity: usize) -> Box<dyn ArrayBuilder> {
137 match dtype {
138 DType::Null => Box::new(NullBuilder::new()),
139 DType::Bool(n) => Box::new(BoolBuilder::with_capacity(*n, capacity)),
140 DType::Primitive(ptype, n) => {
141 match_each_native_ptype!(ptype, |P| {
142 Box::new(PrimitiveBuilder::<P>::with_capacity(*n, capacity))
143 })
144 }
145 DType::Decimal(decimal_type, n) => {
146 match_each_decimal_value_type!(smallest_storage_type(decimal_type), |D| {
147 Box::new(DecimalBuilder::with_capacity::<D>(
148 capacity,
149 *decimal_type,
150 *n,
151 ))
152 })
153 }
154 DType::Utf8(n) => Box::new(VarBinViewBuilder::with_capacity(DType::Utf8(*n), capacity)),
155 DType::Binary(n) => Box::new(VarBinViewBuilder::with_capacity(
156 DType::Binary(*n),
157 capacity,
158 )),
159 DType::Struct(struct_dtype, n) => Box::new(StructBuilder::with_capacity(
160 struct_dtype.clone(),
161 *n,
162 capacity,
163 )),
164 DType::List(dtype, n) => Box::new(ListBuilder::<u64>::with_capacity(
165 dtype.clone(),
166 *n,
167 capacity,
168 )),
169 DType::Extension(ext_dtype) => {
170 Box::new(ExtensionBuilder::with_capacity(ext_dtype.clone(), capacity))
171 }
172 }
173}
174
175pub trait ArrayBuilderExt: ArrayBuilder {
176 fn append_scalar_value(&mut self, value: ScalarValue) -> VortexResult<()> {
178 if value.is_null() {
179 self.append_null();
180 Ok(())
181 } else {
182 self.append_scalar(&Scalar::new(self.dtype().clone(), value))
183 }
184 }
185
186 fn append_scalar(&mut self, scalar: &Scalar) -> VortexResult<()> {
188 if scalar.dtype() != self.dtype() {
189 vortex_bail!(
190 "Builder has dtype {:?}, scalar has {:?}",
191 self.dtype(),
192 scalar.dtype()
193 )
194 }
195 match scalar.dtype() {
196 DType::Null => self
197 .as_any_mut()
198 .downcast_mut::<NullBuilder>()
199 .ok_or_else(|| vortex_err!("Cannot append null scalar to non-null builder"))?
200 .append_null(),
201 DType::Bool(_) => self
202 .as_any_mut()
203 .downcast_mut::<BoolBuilder>()
204 .ok_or_else(|| vortex_err!("Cannot append bool scalar to non-bool builder"))?
205 .append_option(BoolScalar::try_from(scalar)?.value()),
206 DType::Primitive(ptype, ..) => {
207 match_each_native_ptype!(ptype, |P| {
208 self.as_any_mut()
209 .downcast_mut::<PrimitiveBuilder<P>>()
210 .ok_or_else(|| {
211 vortex_err!("Cannot append primitive scalar to non-primitive builder")
212 })?
213 .append_option(PrimitiveScalar::try_from(scalar)?.typed_value::<P>())
214 })
215 }
216 DType::Decimal(..) => {
217 let builder = self
218 .as_any_mut()
219 .downcast_mut::<DecimalBuilder>()
220 .ok_or_else(|| {
221 vortex_err!("Cannot append decimal scalar to non-decimal builder")
222 })?;
223 match scalar.as_decimal().decimal_value() {
224 None => builder.append_null(),
225 Some(v) => match_each_decimal_value!(v, |dec_val| {
226 builder.append_value(dec_val);
227 }),
228 }
229 }
230 DType::Utf8(_) => self
231 .as_any_mut()
232 .downcast_mut::<VarBinViewBuilder>()
233 .ok_or_else(|| vortex_err!("Cannot append utf8 scalar to non-utf8 builder"))?
234 .append_option(Utf8Scalar::try_from(scalar)?.value()),
235 DType::Binary(_) => self
236 .as_any_mut()
237 .downcast_mut::<VarBinViewBuilder>()
238 .ok_or_else(|| vortex_err!("Cannot append binary scalar to non-binary builder"))?
239 .append_option(BinaryScalar::try_from(scalar)?.value()),
240 DType::Struct(..) => self
241 .as_any_mut()
242 .downcast_mut::<StructBuilder>()
243 .ok_or_else(|| vortex_err!("Cannot append struct scalar to non-struct builder"))?
244 .append_value(StructScalar::try_from(scalar)?)?,
245 DType::List(..) => self
246 .as_any_mut()
247 .downcast_mut::<ListBuilder<u64>>()
248 .ok_or_else(|| vortex_err!("Cannot append list scalar to non-list builder"))?
249 .append_value(ListScalar::try_from(scalar)?)?,
250 DType::Extension(..) => self
251 .as_any_mut()
252 .downcast_mut::<ExtensionBuilder>()
253 .ok_or_else(|| {
254 vortex_err!("Cannot append extension scalar to non-extension builder")
255 })?
256 .append_value(ExtScalar::try_from(scalar)?)?,
257 }
258 Ok(())
259 }
260}
261
262impl<T: ?Sized + ArrayBuilder> ArrayBuilderExt for T {}