vortex_array/builders/
map.rs1use std::any::Any;
5use std::sync::Arc;
6
7use vortex_error::VortexResult;
8use vortex_error::vortex_ensure;
9
10use crate::ArrayRef;
11use crate::Canonical;
12use crate::ExecutionCtx;
13use crate::IntoArray;
14use crate::array::ArrayView;
15use crate::arrays::ListView;
16use crate::arrays::Map;
17use crate::arrays::MapArray;
18use crate::arrays::map::MapArraySlotsExt;
19use crate::builders::ArrayBuilder;
20use crate::builders::DEFAULT_BUILDER_CAPACITY;
21use crate::builders::ListViewBuilder;
22use crate::dtype::DType;
23use crate::dtype::MapDType;
24use crate::dtype::Nullability;
25use crate::dtype::OffsetBuilderPType;
26use crate::scalar::MapScalar;
27use crate::scalar::Scalar;
28
29pub struct MapBuilder<O: OffsetBuilderPType, S: OffsetBuilderPType> {
35 dtype: DType,
36 map_dtype: MapDType,
37 entries_builder: ListViewBuilder<O, S>,
38}
39
40impl<O: OffsetBuilderPType, S: OffsetBuilderPType> MapBuilder<O, S> {
41 pub fn new(map_dtype: MapDType, nullability: Nullability) -> Self {
43 Self::with_capacity(map_dtype, nullability, DEFAULT_BUILDER_CAPACITY)
44 }
45
46 pub fn with_capacity(map_dtype: MapDType, nullability: Nullability, capacity: usize) -> Self {
48 let entries_builder = ListViewBuilder::with_capacity(
49 Arc::new(map_dtype.entries_dtype()),
50 nullability,
51 capacity.saturating_mul(2),
52 capacity,
53 );
54 let dtype = DType::Map(map_dtype.clone(), nullability);
55 Self {
56 dtype,
57 map_dtype,
58 entries_builder,
59 }
60 }
61
62 pub fn append_value(&mut self, value: MapScalar<'_>) -> VortexResult<()> {
64 vortex_ensure!(
65 value.dtype() == &self.dtype,
66 "MapBuilder expected map scalar with dtype {}, got {}",
67 self.dtype,
68 value.dtype()
69 );
70
71 if value.is_null() {
72 self.entries_builder.append_null();
73 return Ok(());
74 }
75
76 let entry_dtype = self.map_dtype.entries_dtype();
77 let entries = value
78 .entries()
79 .map(|(key, value)| Scalar::struct_(entry_dtype.clone(), vec![key, value]))
80 .collect();
81 let entries = Scalar::list(Arc::new(entry_dtype), entries, self.dtype.nullability());
82 self.entries_builder.append_value(entries.as_list())
83 }
84
85 pub fn finish_into_map(&mut self) -> MapArray {
87 MapArray::new(
88 self.map_dtype.clone(),
89 self.entries_builder.finish_into_listview(),
90 )
91 }
92
93 pub fn append_map_array(
95 &mut self,
96 array: ArrayView<'_, Map>,
97 ctx: &mut ExecutionCtx,
98 ) -> VortexResult<()> {
99 vortex_ensure!(
100 array.dtype() == self.dtype(),
101 "MapBuilder expected map array with dtype {}, got {}",
102 self.dtype(),
103 array.dtype()
104 );
105 self.entries_builder
106 .append_listview_array(array.entries().as_::<ListView>(), ctx)
107 }
108}
109
110impl<O: OffsetBuilderPType, S: OffsetBuilderPType> ArrayBuilder for MapBuilder<O, S> {
111 fn as_any(&self) -> &dyn Any {
112 self
113 }
114
115 fn as_any_mut(&mut self) -> &mut dyn Any {
116 self
117 }
118
119 fn dtype(&self) -> &DType {
120 &self.dtype
121 }
122
123 fn len(&self) -> usize {
124 self.entries_builder.len()
125 }
126
127 fn append_zeros(&mut self, n: usize) {
128 self.entries_builder.append_zeros(n);
129 }
130
131 unsafe fn append_nulls_unchecked(&mut self, n: usize) {
132 unsafe { self.entries_builder.append_nulls_unchecked(n) };
133 }
134
135 fn append_scalar(&mut self, scalar: &Scalar) -> VortexResult<()> {
136 vortex_ensure!(
137 scalar.dtype() == self.dtype(),
138 "MapBuilder expected scalar with dtype {}, got {}",
139 self.dtype(),
140 scalar.dtype()
141 );
142 self.append_value(scalar.as_map())
143 }
144
145 fn reserve_exact(&mut self, additional: usize) {
146 self.entries_builder.reserve_exact(additional);
147 }
148
149 fn finish(&mut self) -> ArrayRef {
150 self.finish_into_map().into_array()
151 }
152
153 fn finish_into_canonical(&mut self, _ctx: &mut ExecutionCtx) -> Canonical {
154 Canonical::Map(self.finish_into_map())
155 }
156}