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