1use crate::types::bytes::ByteArrayNativeType;
19use std::{any::Any, sync::Arc};
20
21use crate::{
22 ArrayRef, ArrowPrimitiveType, RunArray,
23 types::{BinaryType, ByteArrayType, LargeBinaryType, LargeUtf8Type, RunEndIndexType, Utf8Type},
24};
25
26use super::{ArrayBuilder, GenericByteBuilder, PrimitiveBuilder};
27
28use arrow_buffer::ArrowNativeType;
29
30#[derive(Debug)]
65pub struct GenericByteRunBuilder<R, V>
66where
67 R: ArrowPrimitiveType,
68 V: ByteArrayType,
69{
70 run_ends_builder: PrimitiveBuilder<R>,
71 values_builder: GenericByteBuilder<V>,
72 current_value: Vec<u8>,
73 has_current_value: bool,
74 current_run_end_index: usize,
75 prev_run_end_index: usize,
76}
77
78impl<R, V> Default for GenericByteRunBuilder<R, V>
79where
80 R: ArrowPrimitiveType,
81 V: ByteArrayType,
82{
83 fn default() -> Self {
84 Self::new()
85 }
86}
87
88impl<R, V> GenericByteRunBuilder<R, V>
89where
90 R: ArrowPrimitiveType,
91 V: ByteArrayType,
92{
93 pub fn new() -> Self {
95 Self {
96 run_ends_builder: PrimitiveBuilder::new(),
97 values_builder: GenericByteBuilder::<V>::new(),
98 current_value: Vec::new(),
99 has_current_value: false,
100 current_run_end_index: 0,
101 prev_run_end_index: 0,
102 }
103 }
104
105 pub fn with_capacity(capacity: usize, data_capacity: usize) -> Self {
110 Self {
111 run_ends_builder: PrimitiveBuilder::with_capacity(capacity),
112 values_builder: GenericByteBuilder::<V>::with_capacity(capacity, data_capacity),
113 current_value: Vec::new(),
114 has_current_value: false,
115 current_run_end_index: 0,
116 prev_run_end_index: 0,
117 }
118 }
119}
120
121impl<R, V> ArrayBuilder for GenericByteRunBuilder<R, V>
122where
123 R: RunEndIndexType,
124 V: ByteArrayType,
125{
126 fn as_any(&self) -> &dyn Any {
128 self
129 }
130
131 fn as_any_mut(&mut self) -> &mut dyn Any {
133 self
134 }
135
136 fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
138 self
139 }
140
141 fn len(&self) -> usize {
144 self.current_run_end_index
145 }
146
147 fn finish(&mut self) -> ArrayRef {
149 Arc::new(self.finish())
150 }
151
152 fn finish_cloned(&self) -> ArrayRef {
154 Arc::new(self.finish_cloned())
155 }
156}
157
158impl<R, V> GenericByteRunBuilder<R, V>
159where
160 R: RunEndIndexType,
161 V: ByteArrayType,
162{
163 pub fn append_option(&mut self, input_value: Option<impl AsRef<V::Native>>) {
165 match input_value {
166 Some(value) => self.append_value(value),
167 None => self.append_null(),
168 }
169 }
170
171 pub fn append_value(&mut self, input_value: impl AsRef<V::Native>) {
173 let value: &[u8] = input_value.as_ref().as_ref();
174 if !self.has_current_value {
175 self.append_run_end();
176 self.current_value.extend_from_slice(value);
177 self.has_current_value = true;
178 } else if self.current_value.as_slice() != value {
179 self.append_run_end();
180 self.current_value.clear();
181 self.current_value.extend_from_slice(value);
182 }
183 self.current_run_end_index += 1;
184 }
185
186 pub fn append_null(&mut self) {
188 if self.has_current_value {
189 self.append_run_end();
190 self.current_value.clear();
191 self.has_current_value = false;
192 }
193 self.current_run_end_index += 1;
194 }
195
196 pub fn finish(&mut self) -> RunArray<R> {
202 self.append_run_end();
204
205 self.current_value.clear();
207 self.has_current_value = false;
208 self.current_run_end_index = 0;
209 self.prev_run_end_index = 0;
210
211 let run_ends_array = self.run_ends_builder.finish();
213 let values_array = self.values_builder.finish();
214 RunArray::<R>::try_new(&run_ends_array, &values_array).unwrap()
215 }
216
217 pub fn finish_cloned(&self) -> RunArray<R> {
223 let mut run_ends_array = self.run_ends_builder.finish_cloned();
224 let mut values_array = self.values_builder.finish_cloned();
225
226 if self.prev_run_end_index != self.current_run_end_index {
228 let mut run_end_builder = run_ends_array.into_builder().unwrap();
229 let mut values_builder = values_array.into_builder().unwrap();
230 self.append_run_end_with_builders(&mut run_end_builder, &mut values_builder);
231 run_ends_array = run_end_builder.finish();
232 values_array = values_builder.finish();
233 }
234
235 RunArray::<R>::try_new(&run_ends_array, &values_array).unwrap()
236 }
237
238 fn append_run_end(&mut self) {
240 if self.prev_run_end_index == self.current_run_end_index {
242 return;
243 }
244 let run_end_index = self.run_end_index_as_native();
245 self.run_ends_builder.append_value(run_end_index);
246 if self.has_current_value {
247 let slice = self.current_value.as_slice();
248 let native = unsafe {
249 V::Native::from_bytes_unchecked(slice)
253 };
254 self.values_builder.append_value(native);
255 } else {
256 self.values_builder.append_null();
257 }
258 self.prev_run_end_index = self.current_run_end_index;
259 }
260
261 fn append_run_end_with_builders(
264 &self,
265 run_ends_builder: &mut PrimitiveBuilder<R>,
266 values_builder: &mut GenericByteBuilder<V>,
267 ) {
268 let run_end_index = self.run_end_index_as_native();
269 run_ends_builder.append_value(run_end_index);
270 if self.has_current_value {
271 let slice = self.current_value.as_slice();
272 let native = unsafe {
273 V::Native::from_bytes_unchecked(slice)
277 };
278 values_builder.append_value(native);
279 } else {
280 values_builder.append_null();
281 }
282 }
283
284 fn run_end_index_as_native(&self) -> R::Native {
285 R::Native::from_usize(self.current_run_end_index).unwrap_or_else(|| {
286 panic!(
287 "Cannot convert the value {} from `usize` to native form of arrow datatype {}",
288 self.current_run_end_index,
289 R::DATA_TYPE
290 )
291 })
292 }
293}
294
295impl<R, V, S> Extend<Option<S>> for GenericByteRunBuilder<R, V>
296where
297 R: RunEndIndexType,
298 V: ByteArrayType,
299 S: AsRef<V::Native>,
300{
301 fn extend<T: IntoIterator<Item = Option<S>>>(&mut self, iter: T) {
302 for elem in iter {
303 self.append_option(elem);
304 }
305 }
306}
307
308pub type StringRunBuilder<K> = GenericByteRunBuilder<K, Utf8Type>;
340
341pub type LargeStringRunBuilder<K> = GenericByteRunBuilder<K, LargeUtf8Type>;
343
344pub type BinaryRunBuilder<K> = GenericByteRunBuilder<K, BinaryType>;
376
377pub type LargeBinaryRunBuilder<K> = GenericByteRunBuilder<K, LargeBinaryType>;
379
380#[cfg(test)]
381mod tests {
382 use super::*;
383
384 use crate::GenericByteArray;
385 use crate::Int16RunArray;
386 use crate::array::Array;
387 use crate::cast::AsArray;
388 use crate::types::{Int16Type, Int32Type};
389
390 fn test_bytes_run_builder<T>(values: Vec<&T::Native>)
391 where
392 T: ByteArrayType,
393 <T as ByteArrayType>::Native: PartialEq,
394 <T as ByteArrayType>::Native: AsRef<<T as ByteArrayType>::Native>,
395 {
396 let mut builder = GenericByteRunBuilder::<Int16Type, T>::new();
397 builder.append_value(values[0]);
398 builder.append_value(values[0]);
399 builder.append_value(values[0]);
400 builder.append_null();
401 builder.append_null();
402 builder.append_value(values[1]);
403 builder.append_value(values[1]);
404 builder.append_value(values[2]);
405 builder.append_value(values[2]);
406 builder.append_value(values[2]);
407 builder.append_value(values[2]);
408 let array = builder.finish();
409
410 assert_eq!(array.len(), 11);
411 assert_eq!(array.null_count(), 0);
412 assert_eq!(array.logical_null_count(), 2);
413
414 assert_eq!(array.run_ends().values(), &[3, 5, 7, 11]);
415
416 let av = array.values();
418 let ava: &GenericByteArray<T> = av.as_any().downcast_ref::<GenericByteArray<T>>().unwrap();
419
420 assert_eq!(*ava.value(0), *values[0]);
421 assert!(ava.is_null(1));
422 assert_eq!(*ava.value(2), *values[1]);
423 assert_eq!(*ava.value(3), *values[2]);
424 }
425
426 #[test]
427 fn test_string_run_builder() {
428 test_bytes_run_builder::<Utf8Type>(vec!["abc", "def", "ghi"]);
429 }
430
431 #[test]
432 fn test_string_run_builder_with_empty_strings() {
433 test_bytes_run_builder::<Utf8Type>(vec!["abc", "", "ghi"]);
434 }
435
436 #[test]
437 fn test_binary_run_builder() {
438 test_bytes_run_builder::<BinaryType>(vec![b"abc", b"def", b"ghi"]);
439 }
440
441 fn test_bytes_run_builder_finish_cloned<T>(values: Vec<&T::Native>)
442 where
443 T: ByteArrayType,
444 <T as ByteArrayType>::Native: PartialEq,
445 <T as ByteArrayType>::Native: AsRef<<T as ByteArrayType>::Native>,
446 {
447 let mut builder = GenericByteRunBuilder::<Int16Type, T>::new();
448
449 builder.append_value(values[0]);
450 builder.append_null();
451 builder.append_value(values[1]);
452 builder.append_value(values[1]);
453 builder.append_value(values[0]);
454 let mut array: Int16RunArray = builder.finish_cloned();
455
456 assert_eq!(array.len(), 5);
457 assert_eq!(array.null_count(), 0);
458 assert_eq!(array.logical_null_count(), 1);
459
460 assert_eq!(array.run_ends().values(), &[1, 2, 4, 5]);
461
462 let av = array.values();
464 let ava: &GenericByteArray<T> = av.as_any().downcast_ref::<GenericByteArray<T>>().unwrap();
465
466 assert_eq!(ava.value(0), values[0]);
467 assert!(ava.is_null(1));
468 assert_eq!(ava.value(2), values[1]);
469 assert_eq!(ava.value(3), values[0]);
470
471 builder.append_value(values[0]);
474 builder.append_value(values[0]);
475 builder.append_value(values[1]);
476 array = builder.finish();
477
478 assert_eq!(array.len(), 8);
479 assert_eq!(array.null_count(), 0);
480 assert_eq!(array.logical_null_count(), 1);
481
482 assert_eq!(array.run_ends().values(), &[1, 2, 4, 7, 8]);
483
484 let av2 = array.values();
486 let ava2: &GenericByteArray<T> =
487 av2.as_any().downcast_ref::<GenericByteArray<T>>().unwrap();
488
489 assert_eq!(ava2.value(0), values[0]);
490 assert!(ava2.is_null(1));
491 assert_eq!(ava2.value(2), values[1]);
492 assert_eq!(ava2.value(3), values[0]);
494 assert_eq!(ava2.value(4), values[1]);
495 }
496
497 #[test]
498 fn test_string_run_builder_finish_cloned() {
499 test_bytes_run_builder_finish_cloned::<Utf8Type>(vec!["abc", "def", "ghi"]);
500 }
501
502 #[test]
503 fn test_binary_run_builder_finish_cloned() {
504 test_bytes_run_builder_finish_cloned::<BinaryType>(vec![b"abc", b"def", b"ghi"]);
505 }
506
507 #[test]
508 fn test_extend() {
509 let mut builder = StringRunBuilder::<Int32Type>::new();
510 builder.extend(["a", "a", "a", "", "", "b", "b"].into_iter().map(Some));
511 builder.extend(["b", "cupcakes", "cupcakes"].into_iter().map(Some));
512 let array = builder.finish();
513
514 assert_eq!(array.len(), 10);
515 assert_eq!(array.run_ends().values(), &[3, 5, 8, 10]);
516
517 let str_array = array.values().as_string::<i32>();
518 assert_eq!(str_array.value(0), "a");
519 assert_eq!(str_array.value(1), "");
520 assert_eq!(str_array.value(2), "b");
521 assert_eq!(str_array.value(3), "cupcakes");
522 }
523}