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