1use crate::types::bytes::ByteArrayNativeType;
6use std::{any::Any, sync::Arc};
7
8use crate::{
9 ArrayRef, ArrowPrimitiveType, RunArray,
10 types::{BinaryType, ByteArrayType, LargeBinaryType, LargeUtf8Type, RunEndIndexType, Utf8Type},
11};
12
13use super::{ArrayBuilder, GenericByteBuilder, PrimitiveBuilder};
14
15use arrow_buffer::ArrowNativeType;
16
17#[derive(Debug)]
52pub struct GenericByteRunBuilder<R, V>
53where
54 R: ArrowPrimitiveType,
55 V: ByteArrayType,
56{
57 run_ends_builder: PrimitiveBuilder<R>,
58 values_builder: GenericByteBuilder<V>,
59 current_value: Vec<u8>,
60 has_current_value: bool,
61 current_run_end_index: usize,
62 prev_run_end_index: usize,
63}
64
65impl<R, V> Default for GenericByteRunBuilder<R, V>
66where
67 R: ArrowPrimitiveType,
68 V: ByteArrayType,
69{
70 fn default() -> Self {
71 Self::new()
72 }
73}
74
75impl<R, V> GenericByteRunBuilder<R, V>
76where
77 R: ArrowPrimitiveType,
78 V: ByteArrayType,
79{
80 pub fn new() -> Self {
82 Self {
83 run_ends_builder: PrimitiveBuilder::new(),
84 values_builder: GenericByteBuilder::<V>::new(),
85 current_value: Vec::new(),
86 has_current_value: false,
87 current_run_end_index: 0,
88 prev_run_end_index: 0,
89 }
90 }
91
92 pub fn with_capacity(capacity: usize, data_capacity: usize) -> Self {
97 Self {
98 run_ends_builder: PrimitiveBuilder::with_capacity(capacity),
99 values_builder: GenericByteBuilder::<V>::with_capacity(capacity, data_capacity),
100 current_value: Vec::new(),
101 has_current_value: false,
102 current_run_end_index: 0,
103 prev_run_end_index: 0,
104 }
105 }
106}
107
108impl<R, V> ArrayBuilder for GenericByteRunBuilder<R, V>
109where
110 R: RunEndIndexType,
111 V: ByteArrayType,
112{
113 fn as_any(&self) -> &dyn Any {
115 self
116 }
117
118 fn as_any_mut(&mut self) -> &mut dyn Any {
120 self
121 }
122
123 fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
125 self
126 }
127
128 fn len(&self) -> usize {
131 self.current_run_end_index
132 }
133
134 fn finish(&mut self) -> ArrayRef {
136 Arc::new(self.finish())
137 }
138
139 fn finish_cloned(&self) -> ArrayRef {
141 Arc::new(self.finish_cloned())
142 }
143}
144
145impl<R, V> GenericByteRunBuilder<R, V>
146where
147 R: RunEndIndexType,
148 V: ByteArrayType,
149{
150 pub fn append_option(&mut self, input_value: Option<impl AsRef<V::Native>>) {
152 match input_value {
153 Some(value) => self.append_value(value),
154 None => self.append_null(),
155 }
156 }
157
158 pub fn append_value(&mut self, input_value: impl AsRef<V::Native>) {
160 let value: &[u8] = input_value.as_ref().as_ref();
161 if !self.has_current_value {
162 self.append_run_end();
163 self.current_value.extend_from_slice(value);
164 self.has_current_value = true;
165 } else if self.current_value.as_slice() != value {
166 self.append_run_end();
167 self.current_value.clear();
168 self.current_value.extend_from_slice(value);
169 }
170 self.current_run_end_index += 1;
171 }
172
173 pub fn append_null(&mut self) {
175 if self.has_current_value {
176 self.append_run_end();
177 self.current_value.clear();
178 self.has_current_value = false;
179 }
180 self.current_run_end_index += 1;
181 }
182
183 pub fn finish(&mut self) -> RunArray<R> {
189 self.append_run_end();
191
192 self.current_value.clear();
194 self.has_current_value = false;
195 self.current_run_end_index = 0;
196 self.prev_run_end_index = 0;
197
198 let run_ends_array = self.run_ends_builder.finish();
200 let values_array = self.values_builder.finish();
201 RunArray::<R>::try_new(&run_ends_array, &values_array).unwrap()
202 }
203
204 pub fn finish_cloned(&self) -> RunArray<R> {
210 let mut run_ends_array = self.run_ends_builder.finish_cloned();
211 let mut values_array = self.values_builder.finish_cloned();
212
213 if self.prev_run_end_index != self.current_run_end_index {
215 let mut run_end_builder = run_ends_array.into_builder().unwrap();
216 let mut values_builder = values_array.into_builder().unwrap();
217 self.append_run_end_with_builders(&mut run_end_builder, &mut values_builder);
218 run_ends_array = run_end_builder.finish();
219 values_array = values_builder.finish();
220 }
221
222 RunArray::<R>::try_new(&run_ends_array, &values_array).unwrap()
223 }
224
225 fn append_run_end(&mut self) {
227 if self.prev_run_end_index == self.current_run_end_index {
229 return;
230 }
231 let run_end_index = self.run_end_index_as_native();
232 self.run_ends_builder.append_value(run_end_index);
233 if self.has_current_value {
234 let slice = self.current_value.as_slice();
235 let native = unsafe {
236 V::Native::from_bytes_unchecked(slice)
240 };
241 self.values_builder.append_value(native);
242 } else {
243 self.values_builder.append_null();
244 }
245 self.prev_run_end_index = self.current_run_end_index;
246 }
247
248 fn append_run_end_with_builders(
251 &self,
252 run_ends_builder: &mut PrimitiveBuilder<R>,
253 values_builder: &mut GenericByteBuilder<V>,
254 ) {
255 let run_end_index = self.run_end_index_as_native();
256 run_ends_builder.append_value(run_end_index);
257 if self.has_current_value {
258 let slice = self.current_value.as_slice();
259 let native = unsafe {
260 V::Native::from_bytes_unchecked(slice)
264 };
265 values_builder.append_value(native);
266 } else {
267 values_builder.append_null();
268 }
269 }
270
271 fn run_end_index_as_native(&self) -> R::Native {
272 R::Native::from_usize(self.current_run_end_index).unwrap_or_else(|| {
273 panic!(
274 "Cannot convert the value {} from `usize` to native form of arrow datatype {}",
275 self.current_run_end_index,
276 R::DATA_TYPE
277 )
278 })
279 }
280}
281
282impl<R, V, S> Extend<Option<S>> for GenericByteRunBuilder<R, V>
283where
284 R: RunEndIndexType,
285 V: ByteArrayType,
286 S: AsRef<V::Native>,
287{
288 fn extend<T: IntoIterator<Item = Option<S>>>(&mut self, iter: T) {
289 for elem in iter {
290 self.append_option(elem);
291 }
292 }
293}
294
295pub type StringRunBuilder<K> = GenericByteRunBuilder<K, Utf8Type>;
327
328pub type LargeStringRunBuilder<K> = GenericByteRunBuilder<K, LargeUtf8Type>;
330
331pub type BinaryRunBuilder<K> = GenericByteRunBuilder<K, BinaryType>;
363
364pub type LargeBinaryRunBuilder<K> = GenericByteRunBuilder<K, LargeBinaryType>;
366
367#[cfg(test)]
368mod tests {
369 use super::*;
370
371 use crate::GenericByteArray;
372 use crate::Int16RunArray;
373 use crate::array::Array;
374 use crate::cast::AsArray;
375 use crate::types::{Int16Type, Int32Type};
376
377 fn test_bytes_run_builder<T>(values: Vec<&T::Native>)
378 where
379 T: ByteArrayType,
380 <T as ByteArrayType>::Native: PartialEq,
381 <T as ByteArrayType>::Native: AsRef<<T as ByteArrayType>::Native>,
382 {
383 let mut builder = GenericByteRunBuilder::<Int16Type, T>::new();
384 builder.append_value(values[0]);
385 builder.append_value(values[0]);
386 builder.append_value(values[0]);
387 builder.append_null();
388 builder.append_null();
389 builder.append_value(values[1]);
390 builder.append_value(values[1]);
391 builder.append_value(values[2]);
392 builder.append_value(values[2]);
393 builder.append_value(values[2]);
394 builder.append_value(values[2]);
395 let array = builder.finish();
396
397 assert_eq!(array.len(), 11);
398 assert_eq!(array.null_count(), 0);
399 assert_eq!(array.logical_null_count(), 2);
400
401 assert_eq!(array.run_ends().values(), &[3, 5, 7, 11]);
402
403 let av = array.values();
405 let ava: &GenericByteArray<T> = av.as_any().downcast_ref::<GenericByteArray<T>>().unwrap();
406
407 assert_eq!(*ava.value(0), *values[0]);
408 assert!(ava.is_null(1));
409 assert_eq!(*ava.value(2), *values[1]);
410 assert_eq!(*ava.value(3), *values[2]);
411 }
412
413 #[test]
414 fn test_string_run_builder() {
415 test_bytes_run_builder::<Utf8Type>(vec!["abc", "def", "ghi"]);
416 }
417
418 #[test]
419 fn test_string_run_builder_with_empty_strings() {
420 test_bytes_run_builder::<Utf8Type>(vec!["abc", "", "ghi"]);
421 }
422
423 #[test]
424 fn test_binary_run_builder() {
425 test_bytes_run_builder::<BinaryType>(vec![b"abc", b"def", b"ghi"]);
426 }
427
428 fn test_bytes_run_builder_finish_cloned<T>(values: Vec<&T::Native>)
429 where
430 T: ByteArrayType,
431 <T as ByteArrayType>::Native: PartialEq,
432 <T as ByteArrayType>::Native: AsRef<<T as ByteArrayType>::Native>,
433 {
434 let mut builder = GenericByteRunBuilder::<Int16Type, T>::new();
435
436 builder.append_value(values[0]);
437 builder.append_null();
438 builder.append_value(values[1]);
439 builder.append_value(values[1]);
440 builder.append_value(values[0]);
441 let mut array: Int16RunArray = builder.finish_cloned();
442
443 assert_eq!(array.len(), 5);
444 assert_eq!(array.null_count(), 0);
445 assert_eq!(array.logical_null_count(), 1);
446
447 assert_eq!(array.run_ends().values(), &[1, 2, 4, 5]);
448
449 let av = array.values();
451 let ava: &GenericByteArray<T> = av.as_any().downcast_ref::<GenericByteArray<T>>().unwrap();
452
453 assert_eq!(ava.value(0), values[0]);
454 assert!(ava.is_null(1));
455 assert_eq!(ava.value(2), values[1]);
456 assert_eq!(ava.value(3), values[0]);
457
458 builder.append_value(values[0]);
461 builder.append_value(values[0]);
462 builder.append_value(values[1]);
463 array = builder.finish();
464
465 assert_eq!(array.len(), 8);
466 assert_eq!(array.null_count(), 0);
467 assert_eq!(array.logical_null_count(), 1);
468
469 assert_eq!(array.run_ends().values(), &[1, 2, 4, 7, 8]);
470
471 let av2 = array.values();
473 let ava2: &GenericByteArray<T> =
474 av2.as_any().downcast_ref::<GenericByteArray<T>>().unwrap();
475
476 assert_eq!(ava2.value(0), values[0]);
477 assert!(ava2.is_null(1));
478 assert_eq!(ava2.value(2), values[1]);
479 assert_eq!(ava2.value(3), values[0]);
481 assert_eq!(ava2.value(4), values[1]);
482 }
483
484 #[test]
485 fn test_string_run_builder_finish_cloned() {
486 test_bytes_run_builder_finish_cloned::<Utf8Type>(vec!["abc", "def", "ghi"]);
487 }
488
489 #[test]
490 fn test_binary_run_builder_finish_cloned() {
491 test_bytes_run_builder_finish_cloned::<BinaryType>(vec![b"abc", b"def", b"ghi"]);
492 }
493
494 #[test]
495 fn test_extend() {
496 let mut builder = StringRunBuilder::<Int32Type>::new();
497 builder.extend(["a", "a", "a", "", "", "b", "b"].into_iter().map(Some));
498 builder.extend(["b", "cupcakes", "cupcakes"].into_iter().map(Some));
499 let array = builder.finish();
500
501 assert_eq!(array.len(), 10);
502 assert_eq!(array.run_ends().values(), &[3, 5, 8, 10]);
503
504 let str_array = array.values().as_string::<i32>();
505 assert_eq!(str_array.value(0), "a");
506 assert_eq!(str_array.value(1), "");
507 assert_eq!(str_array.value(2), "b");
508 assert_eq!(str_array.value(3), "cupcakes");
509 }
510}