1use crate::builder::ArrayBuilder;
19use crate::{ArrayRef, GenericListViewArray, OffsetSizeTrait};
20use arrow_buffer::{Buffer, NullBufferBuilder, ScalarBuffer};
21use arrow_schema::{Field, FieldRef};
22use std::any::Any;
23use std::sync::Arc;
24
25#[derive(Debug)]
27pub struct GenericListViewBuilder<OffsetSize: OffsetSizeTrait, T: ArrayBuilder> {
28 offsets_builder: Vec<OffsetSize>,
29 sizes_builder: Vec<OffsetSize>,
30 null_buffer_builder: NullBufferBuilder,
31 values_builder: T,
32 field: Option<FieldRef>,
33 current_offset: OffsetSize,
34}
35
36impl<O: OffsetSizeTrait, T: ArrayBuilder + Default> Default for GenericListViewBuilder<O, T> {
37 fn default() -> Self {
38 Self::new(T::default())
39 }
40}
41
42impl<OffsetSize: OffsetSizeTrait, T: ArrayBuilder> ArrayBuilder
43 for GenericListViewBuilder<OffsetSize, T>
44{
45 fn as_any(&self) -> &dyn Any {
47 self
48 }
49
50 fn as_any_mut(&mut self) -> &mut dyn Any {
52 self
53 }
54
55 fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
57 self
58 }
59
60 fn len(&self) -> usize {
62 self.null_buffer_builder.len()
63 }
64
65 fn finish(&mut self) -> ArrayRef {
67 Arc::new(self.finish())
68 }
69
70 fn finish_cloned(&self) -> ArrayRef {
72 Arc::new(self.finish_cloned())
73 }
74
75 fn finish_preserve_values(&mut self) -> ArrayRef {
76 Arc::new(self.finish_preserve_values())
77 }
78}
79
80impl<OffsetSize: OffsetSizeTrait, T: ArrayBuilder> GenericListViewBuilder<OffsetSize, T> {
81 pub fn new(values_builder: T) -> Self {
83 let capacity = values_builder.len();
84 Self::with_capacity(values_builder, capacity)
85 }
86
87 pub fn with_capacity(values_builder: T, capacity: usize) -> Self {
90 let offsets_builder = Vec::with_capacity(capacity);
91 let sizes_builder = Vec::with_capacity(capacity);
92 Self {
93 offsets_builder,
94 null_buffer_builder: NullBufferBuilder::new(capacity),
95 values_builder,
96 sizes_builder,
97 field: None,
98 current_offset: OffsetSize::zero(),
99 }
100 }
101
102 pub fn with_field(self, field: impl Into<FieldRef>) -> Self {
108 Self {
109 field: Some(field.into()),
110 ..self
111 }
112 }
113}
114
115impl<OffsetSize: OffsetSizeTrait, T: ArrayBuilder> GenericListViewBuilder<OffsetSize, T>
116where
117 T: 'static,
118{
119 pub fn values(&mut self) -> &mut T {
124 &mut self.values_builder
125 }
126
127 pub fn values_ref(&self) -> &T {
129 &self.values_builder
130 }
131
132 #[inline]
138 pub fn append(&mut self, is_valid: bool) {
139 self.offsets_builder.push(self.current_offset);
140 self.sizes_builder.push(
141 OffsetSize::from_usize(
142 self.values_builder.len() - self.current_offset.to_usize().unwrap(),
143 )
144 .unwrap(),
145 );
146 self.null_buffer_builder.append(is_valid);
147 self.current_offset = OffsetSize::from_usize(self.values_builder.len()).unwrap();
148 }
149
150 #[inline]
152 pub fn append_value<I, V>(&mut self, i: I)
153 where
154 T: Extend<Option<V>>,
155 I: IntoIterator<Item = Option<V>>,
156 {
157 self.extend(std::iter::once(Some(i)))
158 }
159
160 #[inline]
164 pub fn append_null(&mut self) {
165 self.offsets_builder.push(self.current_offset);
166 self.sizes_builder.push(OffsetSize::from_usize(0).unwrap());
167 self.null_buffer_builder.append_null();
168 }
169
170 #[inline]
174 pub fn append_option<I, V>(&mut self, i: Option<I>)
175 where
176 T: Extend<Option<V>>,
177 I: IntoIterator<Item = Option<V>>,
178 {
179 match i {
180 Some(i) => self.append_value(i),
181 None => self.append_null(),
182 }
183 }
184
185 pub fn finish(&mut self) -> GenericListViewArray<OffsetSize> {
192 let values = self.values_builder.finish();
193 let nulls = self.null_buffer_builder.finish();
194 let offsets = Buffer::from_vec(std::mem::take(&mut self.offsets_builder));
195 self.current_offset = OffsetSize::zero();
196
197 let offsets = ScalarBuffer::from(offsets);
199 let sizes = Buffer::from_vec(std::mem::take(&mut self.sizes_builder));
200 let sizes = ScalarBuffer::from(sizes);
201 let field = match &self.field {
202 Some(f) => f.clone(),
203 None => Arc::new(Field::new("item", values.data_type().clone(), true)),
204 };
205 GenericListViewArray::new(field, offsets, sizes, values, nulls)
206 }
207
208 pub fn finish_cloned(&self) -> GenericListViewArray<OffsetSize> {
215 let values = self.values_builder.finish_cloned();
216 let nulls = self.null_buffer_builder.finish_cloned();
217
218 let offsets = Buffer::from_slice_ref(self.offsets_builder.as_slice());
219 let offsets = ScalarBuffer::from(offsets);
221
222 let sizes = Buffer::from_slice_ref(self.sizes_builder.as_slice());
223 let sizes = ScalarBuffer::from(sizes);
224
225 let field = match &self.field {
226 Some(f) => f.clone(),
227 None => Arc::new(Field::new("item", values.data_type().clone(), true)),
228 };
229
230 GenericListViewArray::new(field, offsets, sizes, values, nulls)
231 }
232
233 fn finish_preserve_values(&mut self) -> GenericListViewArray<OffsetSize> {
234 let values = self.values_builder.finish_preserve_values();
235 let nulls = self.null_buffer_builder.finish();
236 let offsets = Buffer::from_vec(std::mem::take(&mut self.offsets_builder));
237 self.current_offset = OffsetSize::zero();
238
239 let offsets = ScalarBuffer::from(offsets);
241 let sizes = Buffer::from_vec(std::mem::take(&mut self.sizes_builder));
242 let sizes = ScalarBuffer::from(sizes);
243 let field = match &self.field {
244 Some(f) => f.clone(),
245 None => Arc::new(Field::new("item", values.data_type().clone(), true)),
246 };
247 GenericListViewArray::new(field, offsets, sizes, values, nulls)
248 }
249
250 pub fn offsets_slice(&self) -> &[OffsetSize] {
252 self.offsets_builder.as_slice()
253 }
254}
255
256impl<O, B, V, E> Extend<Option<V>> for GenericListViewBuilder<O, B>
257where
258 O: OffsetSizeTrait,
259 B: ArrayBuilder + Extend<E>,
260 V: IntoIterator<Item = E>,
261{
262 #[inline]
263 fn extend<T: IntoIterator<Item = Option<V>>>(&mut self, iter: T) {
264 for v in iter {
265 match v {
266 Some(elements) => {
267 self.values_builder.extend(elements);
268 self.append(true);
269 }
270 None => self.append(false),
271 }
272 }
273 }
274}
275
276#[cfg(test)]
277mod tests {
278 use super::*;
279 use crate::builder::{Int32Builder, ListViewBuilder, make_builder, tests::PreserveValuesMock};
280 use crate::cast::AsArray;
281 use crate::types::Int32Type;
282 use crate::{Array, Int32Array};
283 use arrow_schema::DataType;
284
285 fn test_generic_list_view_array_builder_impl<O: OffsetSizeTrait>() {
286 let values_builder = Int32Builder::with_capacity(10);
287 let mut builder = GenericListViewBuilder::<O, _>::new(values_builder);
288
289 builder.values().append_value(0);
291 builder.values().append_value(1);
292 builder.values().append_value(2);
293 builder.append(true);
294 builder.values().append_value(3);
295 builder.values().append_value(4);
296 builder.values().append_value(5);
297 builder.append(true);
298 builder.values().append_value(6);
299 builder.values().append_value(7);
300 builder.append(true);
301 let list_array = builder.finish();
302
303 let list_values = list_array.values().as_primitive::<Int32Type>();
304 assert_eq!(list_values.values(), &[0, 1, 2, 3, 4, 5, 6, 7]);
305 assert_eq!(list_array.value_offsets(), [0, 3, 6].map(O::usize_as));
306 assert_eq!(list_array.value_sizes(), [3, 3, 2].map(O::usize_as));
307 assert_eq!(DataType::Int32, list_array.value_type());
308 assert_eq!(3, list_array.len());
309 assert_eq!(0, list_array.null_count());
310 assert_eq!(O::from_usize(6).unwrap(), list_array.value_offsets()[2]);
311 assert_eq!(O::from_usize(2).unwrap(), list_array.value_sizes()[2]);
312 for i in 0..2 {
313 assert!(list_array.is_valid(i));
314 assert!(!list_array.is_null(i));
315 }
316 }
317
318 #[test]
319 fn test_list_view_array_builder() {
320 test_generic_list_view_array_builder_impl::<i32>()
321 }
322
323 #[test]
324 fn test_large_list_view_array_builder() {
325 test_generic_list_view_array_builder_impl::<i64>()
326 }
327
328 fn test_generic_list_view_array_builder_nulls_impl<O: OffsetSizeTrait>() {
329 let values_builder = Int32Builder::with_capacity(10);
330 let mut builder = GenericListViewBuilder::<O, _>::new(values_builder);
331
332 builder.values().append_value(0);
334 builder.values().append_value(1);
335 builder.values().append_value(2);
336 builder.append(true);
337 builder.append(false);
338 builder.values().append_value(3);
339 builder.values().append_null();
340 builder.values().append_value(5);
341 builder.append(true);
342 builder.values().append_value(6);
343 builder.values().append_value(7);
344 builder.append(true);
345
346 let list_array = builder.finish();
347
348 assert_eq!(DataType::Int32, list_array.value_type());
349 assert_eq!(4, list_array.len());
350 assert_eq!(1, list_array.null_count());
351 assert_eq!(O::from_usize(3).unwrap(), list_array.value_offsets()[2]);
352 assert_eq!(O::from_usize(3).unwrap(), list_array.value_sizes()[2]);
353 }
354
355 #[test]
356 fn test_list_view_array_builder_nulls() {
357 test_generic_list_view_array_builder_nulls_impl::<i32>()
358 }
359
360 #[test]
361 fn test_large_list_view_array_builder_nulls() {
362 test_generic_list_view_array_builder_nulls_impl::<i64>()
363 }
364
365 #[test]
366 fn test_list_view_array_builder_finish() {
367 let values_builder = Int32Array::builder(5);
368 let mut builder = ListViewBuilder::new(values_builder);
369
370 builder.values().append_slice(&[1, 2, 3]);
371 builder.append(true);
372 builder.values().append_slice(&[4, 5, 6]);
373 builder.append(true);
374
375 let mut arr = builder.finish();
376 assert_eq!(2, arr.len());
377 assert!(builder.is_empty());
378
379 builder.values().append_slice(&[7, 8, 9]);
380 builder.append(true);
381 arr = builder.finish();
382 assert_eq!(1, arr.len());
383 assert!(builder.is_empty());
384 }
385
386 #[test]
387 fn test_list_view_array_builder_finish_cloned() {
388 let values_builder = Int32Array::builder(5);
389 let mut builder = ListViewBuilder::new(values_builder);
390
391 builder.values().append_slice(&[1, 2, 3]);
392 builder.append(true);
393 builder.values().append_slice(&[4, 5, 6]);
394 builder.append(true);
395
396 let mut arr = builder.finish_cloned();
397 assert_eq!(2, arr.len());
398 assert!(!builder.is_empty());
399
400 builder.values().append_slice(&[7, 8, 9]);
401 builder.append(true);
402 arr = builder.finish();
403 assert_eq!(3, arr.len());
404 assert!(builder.is_empty());
405 }
406
407 #[test]
408 fn test_list_view_list_view_array_builder() {
409 let primitive_builder = Int32Builder::with_capacity(10);
410 let values_builder = ListViewBuilder::new(primitive_builder);
411 let mut builder = ListViewBuilder::new(values_builder);
412
413 builder.values().values().append_value(1);
415 builder.values().values().append_value(2);
416 builder.values().append(true);
417 builder.values().values().append_value(3);
418 builder.values().values().append_value(4);
419 builder.values().append(true);
420 builder.append(true);
421
422 builder.values().values().append_value(5);
423 builder.values().values().append_value(6);
424 builder.values().values().append_value(7);
425 builder.values().append(true);
426 builder.values().append(false);
427 builder.values().values().append_value(8);
428 builder.values().append(true);
429 builder.append(true);
430
431 builder.append(false);
432
433 builder.values().values().append_value(9);
434 builder.values().values().append_value(10);
435 builder.values().append(true);
436 builder.append(true);
437
438 let l1 = builder.finish();
439
440 assert_eq!(4, l1.len());
441 assert_eq!(1, l1.null_count());
442
443 assert_eq!(l1.value_offsets(), &[0, 2, 5, 5]);
444 assert_eq!(l1.value_sizes(), &[2, 3, 0, 1]);
445
446 let l2 = l1.values().as_list_view::<i32>();
447
448 assert_eq!(6, l2.len());
449 assert_eq!(1, l2.null_count());
450 assert_eq!(l2.value_offsets(), &[0, 2, 4, 7, 7, 8]);
451 assert_eq!(l2.value_sizes(), &[2, 2, 3, 0, 1, 2]);
452
453 let i1 = l2.values().as_primitive::<Int32Type>();
454 assert_eq!(10, i1.len());
455 assert_eq!(0, i1.null_count());
456 assert_eq!(i1.values(), &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
457 }
458
459 #[test]
460 fn test_extend() {
461 let mut builder = ListViewBuilder::new(Int32Builder::new());
462 builder.extend([
463 Some(vec![Some(1), Some(2), Some(7), None]),
464 Some(vec![]),
465 Some(vec![Some(4), Some(5)]),
466 None,
467 ]);
468
469 let array = builder.finish();
470 assert_eq!(array.value_offsets(), [0, 4, 4, 6]);
471 assert_eq!(array.value_sizes(), [4, 0, 2, 0]);
472 assert_eq!(array.null_count(), 1);
473 assert!(array.is_null(3));
474 let elements = array.values().as_primitive::<Int32Type>();
475 assert_eq!(elements.values(), &[1, 2, 7, 0, 4, 5]);
476 assert_eq!(elements.null_count(), 1);
477 assert!(elements.is_null(3));
478 }
479
480 #[test]
481 fn test_boxed_primitive_array_builder() {
482 let values_builder = make_builder(&DataType::Int32, 5);
483 let mut builder = ListViewBuilder::new(values_builder);
484
485 builder
486 .values()
487 .as_any_mut()
488 .downcast_mut::<Int32Builder>()
489 .expect("should be an Int32Builder")
490 .append_slice(&[1, 2, 3]);
491 builder.append(true);
492
493 builder
494 .values()
495 .as_any_mut()
496 .downcast_mut::<Int32Builder>()
497 .expect("should be an Int32Builder")
498 .append_slice(&[4, 5, 6]);
499 builder.append(true);
500
501 let arr = builder.finish();
502 assert_eq!(2, arr.len());
503
504 let elements = arr.values().as_primitive::<Int32Type>();
505 assert_eq!(elements.values(), &[1, 2, 3, 4, 5, 6]);
506 }
507
508 #[test]
509 fn test_boxed_list_view_list_view_array_builder() {
510 let values_builder = make_builder(
512 &DataType::ListView(Arc::new(Field::new("item", DataType::Int32, true))),
513 10,
514 );
515 test_boxed_generic_list_view_generic_list_view_array_builder::<i32>(values_builder);
516 }
517
518 #[test]
519 fn test_boxed_large_list_view_large_list_view_array_builder() {
520 let values_builder = make_builder(
522 &DataType::LargeListView(Arc::new(Field::new("item", DataType::Int32, true))),
523 10,
524 );
525 test_boxed_generic_list_view_generic_list_view_array_builder::<i64>(values_builder);
526 }
527
528 fn test_boxed_generic_list_view_generic_list_view_array_builder<O>(
529 values_builder: Box<dyn ArrayBuilder>,
530 ) where
531 O: OffsetSizeTrait + PartialEq,
532 {
533 let mut builder: GenericListViewBuilder<O, Box<dyn ArrayBuilder>> =
534 GenericListViewBuilder::<O, Box<dyn ArrayBuilder>>::new(values_builder);
535
536 builder
538 .values()
539 .as_any_mut()
540 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
541 .expect("should be an (Large)ListViewBuilder")
542 .values()
543 .as_any_mut()
544 .downcast_mut::<Int32Builder>()
545 .expect("should be an Int32Builder")
546 .append_value(1);
547 builder
548 .values()
549 .as_any_mut()
550 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
551 .expect("should be an (Large)ListViewBuilder")
552 .values()
553 .as_any_mut()
554 .downcast_mut::<Int32Builder>()
555 .expect("should be an Int32Builder")
556 .append_value(2);
557 builder
558 .values()
559 .as_any_mut()
560 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
561 .expect("should be an (Large)ListViewBuilder")
562 .append(true);
563 builder
564 .values()
565 .as_any_mut()
566 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
567 .expect("should be an (Large)ListViewBuilder")
568 .values()
569 .as_any_mut()
570 .downcast_mut::<Int32Builder>()
571 .expect("should be an Int32Builder")
572 .append_value(3);
573 builder
574 .values()
575 .as_any_mut()
576 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
577 .expect("should be an (Large)ListViewBuilder")
578 .values()
579 .as_any_mut()
580 .downcast_mut::<Int32Builder>()
581 .expect("should be an Int32Builder")
582 .append_value(4);
583 builder
584 .values()
585 .as_any_mut()
586 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
587 .expect("should be an (Large)ListViewBuilder")
588 .append(true);
589 builder.append(true);
590
591 builder
592 .values()
593 .as_any_mut()
594 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
595 .expect("should be an (Large)ListViewBuilder")
596 .values()
597 .as_any_mut()
598 .downcast_mut::<Int32Builder>()
599 .expect("should be an Int32Builder")
600 .append_value(5);
601 builder
602 .values()
603 .as_any_mut()
604 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
605 .expect("should be an (Large)ListViewBuilder")
606 .values()
607 .as_any_mut()
608 .downcast_mut::<Int32Builder>()
609 .expect("should be an Int32Builder")
610 .append_value(6);
611 builder
612 .values()
613 .as_any_mut()
614 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
615 .expect("should be an (Large)ListViewBuilder")
616 .values()
617 .as_any_mut()
618 .downcast_mut::<Int32Builder>()
619 .expect("should be an (Large)ListViewBuilder")
620 .append_value(7);
621 builder
622 .values()
623 .as_any_mut()
624 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
625 .expect("should be an (Large)ListViewBuilder")
626 .append(true);
627 builder
628 .values()
629 .as_any_mut()
630 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
631 .expect("should be an (Large)ListViewBuilder")
632 .append(false);
633 builder
634 .values()
635 .as_any_mut()
636 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
637 .expect("should be an (Large)ListViewBuilder")
638 .values()
639 .as_any_mut()
640 .downcast_mut::<Int32Builder>()
641 .expect("should be an Int32Builder")
642 .append_value(8);
643 builder
644 .values()
645 .as_any_mut()
646 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
647 .expect("should be an (Large)ListViewBuilder")
648 .append(true);
649 builder.append(true);
650
651 builder.append(false);
652
653 builder
654 .values()
655 .as_any_mut()
656 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
657 .expect("should be an (Large)ListViewBuilder")
658 .values()
659 .as_any_mut()
660 .downcast_mut::<Int32Builder>()
661 .expect("should be an Int32Builder")
662 .append_value(9);
663 builder
664 .values()
665 .as_any_mut()
666 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
667 .expect("should be an (Large)ListViewBuilder")
668 .values()
669 .as_any_mut()
670 .downcast_mut::<Int32Builder>()
671 .expect("should be an Int32Builder")
672 .append_value(10);
673 builder
674 .values()
675 .as_any_mut()
676 .downcast_mut::<GenericListViewBuilder<O, Box<dyn ArrayBuilder>>>()
677 .expect("should be an (Large)ListViewBuilder")
678 .append(true);
679 builder.append(true);
680
681 let l1 = builder.finish();
682 assert_eq!(4, l1.len());
683 assert_eq!(1, l1.null_count());
684 assert_eq!(l1.value_offsets(), &[0, 2, 5, 5].map(O::usize_as));
685 assert_eq!(l1.value_sizes(), &[2, 3, 0, 1].map(O::usize_as));
686
687 let l2 = l1.values().as_list_view::<O>();
688 assert_eq!(6, l2.len());
689 assert_eq!(1, l2.null_count());
690 assert_eq!(l2.value_offsets(), &[0, 2, 4, 7, 7, 8].map(O::usize_as));
691 assert_eq!(l2.value_sizes(), &[2, 2, 3, 0, 1, 2].map(O::usize_as));
692
693 let i1 = l2.values().as_primitive::<Int32Type>();
694 assert_eq!(10, i1.len());
695 assert_eq!(0, i1.null_count());
696 assert_eq!(i1.values(), &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
697 }
698
699 #[test]
700 fn test_with_field() {
701 let field = Arc::new(Field::new("bar", DataType::Int32, false));
702 let mut builder = ListViewBuilder::new(Int32Builder::new()).with_field(field.clone());
703 builder.append_value([Some(1), Some(2), Some(3)]);
704 builder.append_null(); builder.append_value([Some(4)]);
706 let array = builder.finish();
707 assert_eq!(array.len(), 3);
708 assert_eq!(array.data_type(), &DataType::ListView(field.clone()));
709
710 builder.append_value([Some(4), Some(5)]);
711 let array = builder.finish();
712 assert_eq!(array.data_type(), &DataType::ListView(field));
713 assert_eq!(array.len(), 1);
714 }
715
716 #[test]
717 #[should_panic(
718 expected = r#"Non-nullable field of ListViewArray \"item\" cannot contain nulls"#
719 )]
720 fn test_checks_nullability() {
722 let field = Arc::new(Field::new("item", DataType::Int32, false));
723 let mut builder = ListViewBuilder::new(Int32Builder::new()).with_field(field.clone());
724 builder.append_value([Some(1), None]);
725 builder.finish();
726 }
727
728 #[test]
729 #[should_panic(expected = "ListViewArray expected data type Int64 got Int32")]
730 fn test_checks_data_type() {
732 let field = Arc::new(Field::new("item", DataType::Int64, false));
733 let mut builder = ListViewBuilder::new(Int32Builder::new()).with_field(field.clone());
734 builder.append_value([Some(1)]);
735 builder.finish();
736 }
737
738 #[test]
739 fn test_finish_preserve_values() {
740 let mut builder = ListViewBuilder::new(PreserveValuesMock::default());
741
742 builder.values().inner.append_value(1);
743 builder.append(true);
744
745 let arr = builder.finish_preserve_values();
746
747 assert_eq!(1, arr.len());
748 assert_eq!(1, builder.values().called);
749 }
750}