1use std::{any::Any, sync::Arc};
19
20use crate::{ArrayRef, ArrowPrimitiveType, RunArray, types::RunEndIndexType};
21
22use super::{ArrayBuilder, PrimitiveBuilder};
23
24use arrow_buffer::ArrowNativeType;
25
26#[derive(Debug)]
61pub struct PrimitiveRunBuilder<R, V>
62where
63 R: RunEndIndexType,
64 V: ArrowPrimitiveType,
65{
66 run_ends_builder: PrimitiveBuilder<R>,
67 values_builder: PrimitiveBuilder<V>,
68 current_value: Option<V::Native>,
69 current_run_end_index: usize,
70 prev_run_end_index: usize,
71}
72
73impl<R, V> Default for PrimitiveRunBuilder<R, V>
74where
75 R: RunEndIndexType,
76 V: ArrowPrimitiveType,
77{
78 fn default() -> Self {
79 Self::new()
80 }
81}
82
83impl<R, V> PrimitiveRunBuilder<R, V>
84where
85 R: RunEndIndexType,
86 V: ArrowPrimitiveType,
87{
88 pub fn new() -> Self {
90 Self {
91 run_ends_builder: PrimitiveBuilder::new(),
92 values_builder: PrimitiveBuilder::new(),
93 current_value: None,
94 current_run_end_index: 0,
95 prev_run_end_index: 0,
96 }
97 }
98
99 pub fn with_capacity(capacity: usize) -> Self {
103 Self {
104 run_ends_builder: PrimitiveBuilder::with_capacity(capacity),
105 values_builder: PrimitiveBuilder::with_capacity(capacity),
106 current_value: None,
107 current_run_end_index: 0,
108 prev_run_end_index: 0,
109 }
110 }
111
112 pub fn with_data_type(mut self, data_type: arrow_schema::DataType) -> Self {
122 self.values_builder = self.values_builder.with_data_type(data_type);
123 self
124 }
125}
126
127impl<R, V> ArrayBuilder for PrimitiveRunBuilder<R, V>
128where
129 R: RunEndIndexType,
130 V: ArrowPrimitiveType,
131{
132 fn as_any(&self) -> &dyn Any {
134 self
135 }
136
137 fn as_any_mut(&mut self) -> &mut dyn Any {
139 self
140 }
141
142 fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
144 self
145 }
146
147 fn len(&self) -> usize {
150 self.current_run_end_index
151 }
152
153 fn finish(&mut self) -> ArrayRef {
155 Arc::new(self.finish())
156 }
157
158 fn finish_cloned(&self) -> ArrayRef {
160 Arc::new(self.finish_cloned())
161 }
162}
163
164impl<R, V> PrimitiveRunBuilder<R, V>
165where
166 R: RunEndIndexType,
167 V: ArrowPrimitiveType,
168{
169 pub fn append_option(&mut self, value: Option<V::Native>) {
171 if self.current_run_end_index == 0 {
172 self.current_run_end_index = 1;
173 self.current_value = value;
174 return;
175 }
176 if self.current_value != value {
177 self.append_run_end();
178 self.current_value = value;
179 }
180
181 self.current_run_end_index += 1;
182 }
183
184 pub fn append_value(&mut self, value: V::Native) {
186 self.append_option(Some(value))
187 }
188
189 pub fn append_null(&mut self) {
191 self.append_option(None)
192 }
193
194 pub fn finish(&mut self) -> RunArray<R> {
197 self.append_run_end();
199
200 self.current_value = None;
202 self.current_run_end_index = 0;
203 self.prev_run_end_index = 0;
204
205 let run_ends_array = self.run_ends_builder.finish();
207 let values_array = self.values_builder.finish();
208 RunArray::<R>::try_new(&run_ends_array, &values_array).unwrap()
209 }
210
211 pub fn finish_cloned(&self) -> RunArray<R> {
214 let mut run_ends_array = self.run_ends_builder.finish_cloned();
215 let mut values_array = self.values_builder.finish_cloned();
216
217 if self.prev_run_end_index != self.current_run_end_index {
219 let mut run_end_builder = run_ends_array.into_builder().unwrap();
220 let mut values_builder = values_array.into_builder().unwrap();
221 self.append_run_end_with_builders(&mut run_end_builder, &mut values_builder);
222 run_ends_array = run_end_builder.finish();
223 values_array = values_builder.finish();
224 }
225
226 RunArray::try_new(&run_ends_array, &values_array).unwrap()
227 }
228
229 fn append_run_end(&mut self) {
231 if self.prev_run_end_index == self.current_run_end_index {
233 return;
234 }
235 let run_end_index = self.run_end_index_as_native();
236 self.run_ends_builder.append_value(run_end_index);
237 self.values_builder.append_option(self.current_value);
238 self.prev_run_end_index = self.current_run_end_index;
239 }
240
241 fn append_run_end_with_builders(
244 &self,
245 run_ends_builder: &mut PrimitiveBuilder<R>,
246 values_builder: &mut PrimitiveBuilder<V>,
247 ) {
248 let run_end_index = self.run_end_index_as_native();
249 run_ends_builder.append_value(run_end_index);
250 values_builder.append_option(self.current_value);
251 }
252
253 fn run_end_index_as_native(&self) -> R::Native {
254 R::Native::from_usize(self.current_run_end_index)
255 .unwrap_or_else(|| panic!(
256 "Cannot convert `current_run_end_index` {} from `usize` to native form of arrow datatype {}",
257 self.current_run_end_index,
258 R::DATA_TYPE
259 ))
260 }
261}
262
263impl<R, V> Extend<Option<V::Native>> for PrimitiveRunBuilder<R, V>
264where
265 R: RunEndIndexType,
266 V: ArrowPrimitiveType,
267{
268 fn extend<T: IntoIterator<Item = Option<V::Native>>>(&mut self, iter: T) {
269 for elem in iter {
270 self.append_option(elem);
271 }
272 }
273}
274
275#[cfg(test)]
276mod tests {
277 use arrow_schema::DataType;
278
279 use crate::builder::PrimitiveRunBuilder;
280 use crate::cast::AsArray;
281 use crate::types::{Decimal128Type, Int16Type, TimestampMicrosecondType, UInt32Type};
282 use crate::{Array, Decimal128Array, TimestampMicrosecondArray, UInt32Array};
283
284 #[test]
285 fn test_primitive_ree_array_builder() {
286 let mut builder = PrimitiveRunBuilder::<Int16Type, UInt32Type>::new();
287 builder.append_value(1234);
288 builder.append_value(1234);
289 builder.append_value(1234);
290 builder.append_null();
291 builder.append_value(5678);
292 builder.append_value(5678);
293
294 let array = builder.finish();
295
296 assert_eq!(array.null_count(), 0);
297 assert_eq!(array.logical_null_count(), 1);
298 assert_eq!(array.len(), 6);
299
300 assert_eq!(array.run_ends().values(), &[3, 4, 6]);
301
302 let av = array.values();
303
304 assert!(!av.is_null(0));
305 assert!(av.is_null(1));
306 assert!(!av.is_null(2));
307
308 let ava: &UInt32Array = av.as_primitive::<UInt32Type>();
310
311 assert_eq!(ava, &UInt32Array::from(vec![Some(1234), None, Some(5678)]));
312 }
313
314 #[test]
315 fn test_extend() {
316 let mut builder = PrimitiveRunBuilder::<Int16Type, Int16Type>::new();
317 builder.extend([1, 2, 2, 5, 5, 4, 4].into_iter().map(Some));
318 builder.extend([4, 4, 6, 2].into_iter().map(Some));
319 let array = builder.finish();
320
321 assert_eq!(array.len(), 11);
322 assert_eq!(array.null_count(), 0);
323 assert_eq!(array.logical_null_count(), 0);
324 assert_eq!(array.run_ends().values(), &[1, 3, 5, 9, 10, 11]);
325 assert_eq!(
326 array.values().as_primitive::<Int16Type>().values(),
327 &[1, 2, 5, 4, 6, 2]
328 );
329 }
330
331 #[test]
332 fn test_reuse_after_finish() {
333 let mut builder = PrimitiveRunBuilder::<Int16Type, Int16Type>::new();
334 builder.extend([1, 2, 3].into_iter().map(Some));
335 builder.finish();
336
337 builder.extend([7, 7, 7].into_iter().map(Some));
339 let array = builder.finish();
340 assert_eq!(array.len(), 3);
341 assert_eq!(array.run_ends().values(), &[3]);
342 assert_eq!(array.values().as_primitive::<Int16Type>().values(), &[7]);
343
344 assert_eq!(builder.finish().len(), 0);
346 }
347
348 #[test]
349 #[should_panic]
350 fn test_override_data_type_invalid() {
351 PrimitiveRunBuilder::<Int16Type, UInt32Type>::new().with_data_type(DataType::UInt64);
352 }
353
354 #[test]
355 fn test_override_data_type() {
356 PrimitiveRunBuilder::<Int16Type, UInt32Type>::new().with_data_type(DataType::UInt32);
358
359 let mut builder = PrimitiveRunBuilder::<Int16Type, Decimal128Type>::new()
361 .with_data_type(DataType::Decimal128(1, 2));
362 builder.append_value(123);
363 let array = builder.finish();
364 let array = array.downcast::<Decimal128Array>().unwrap();
365 let values = array.values();
366 assert_eq!(values.precision(), 1);
367 assert_eq!(values.scale(), 2);
368
369 let mut builder = PrimitiveRunBuilder::<Int16Type, TimestampMicrosecondType>::new()
371 .with_data_type(DataType::Timestamp(
372 arrow_schema::TimeUnit::Microsecond,
373 Some("Europe/Paris".into()),
374 ));
375 builder.append_value(1);
376 let array = builder.finish();
377 let array = array.downcast::<TimestampMicrosecondArray>().unwrap();
378 let values = array.values();
379 assert_eq!(values.timezone(), Some("Europe/Paris"));
380 }
381
382 #[test]
383 fn test_finish_cloned_keeps_data_type() {
384 let data_type = DataType::Decimal128(5, 2);
385 let mut builder = PrimitiveRunBuilder::<Int16Type, Decimal128Type>::new()
386 .with_data_type(data_type.clone());
387 builder.append_value(123);
389 let array = builder.finish_cloned();
390 assert_eq!(array.values().data_type(), &data_type);
391 }
392}