Skip to content

Commit 216213b

Browse files
committed
Implement native interleave for ListView
1 parent 89b1497 commit 216213b

1 file changed

Lines changed: 107 additions & 0 deletions

File tree

arrow-select/src/interleave.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ pub fn interleave(
108108
DataType::Struct(fields) => interleave_struct(fields, values, indices),
109109
DataType::List(field) => interleave_list::<i32>(values, indices, field),
110110
DataType::LargeList(field) => interleave_list::<i64>(values, indices, field),
111+
DataType::ListView(field) => interleave_list_view::<i32>(values, indices, field),
112+
DataType::LargeListView(field) => interleave_list_view::<i64>(values, indices, field),
111113
_ => interleave_fallback(values, indices)
112114
}
113115
}
@@ -411,6 +413,56 @@ fn interleave_list<O: OffsetSizeTrait>(
411413
Ok(Arc::new(list_array))
412414
}
413415

416+
fn interleave_list_view<O: OffsetSizeTrait>(
417+
values: &[&dyn Array],
418+
indices: &[(usize, usize)],
419+
field: &FieldRef,
420+
) -> Result<ArrayRef, ArrowError> {
421+
let interleaved = Interleave::<'_, GenericListViewArray<O>>::new(values, indices);
422+
423+
// Build new offsets/sizes and compute total child capacity
424+
let mut capacity = 0usize;
425+
let mut offsets = Vec::with_capacity(indices.len());
426+
let mut sizes = Vec::with_capacity(indices.len());
427+
for &(array_idx, row_idx) in indices {
428+
let list = interleaved.arrays[array_idx];
429+
let size = list.sizes()[row_idx].as_usize();
430+
offsets.push(
431+
O::from_usize(capacity).ok_or_else(|| ArrowError::OffsetOverflowError(capacity))?,
432+
);
433+
sizes.push(O::from_usize(size).ok_or_else(|| ArrowError::OffsetOverflowError(size))?);
434+
capacity += size;
435+
}
436+
437+
// Bulk-copy child value ranges into a single flat child array
438+
let child_data: Vec<_> = interleaved
439+
.arrays
440+
.iter()
441+
.map(|list| list.values().to_data())
442+
.collect();
443+
let child_data_refs: Vec<_> = child_data.iter().collect();
444+
let mut mutable_child = MutableArrayData::new(child_data_refs, false, capacity);
445+
for &(array_idx, row_idx) in indices {
446+
let list = interleaved.arrays[array_idx];
447+
let start = list.offsets()[row_idx].as_usize();
448+
let size = list.sizes()[row_idx].as_usize();
449+
if size > 0 {
450+
mutable_child.extend(array_idx, start, start + size);
451+
}
452+
}
453+
454+
let interleaved_values = make_array(mutable_child.freeze());
455+
let list_view_array = GenericListViewArray::<O>::new(
456+
field.clone(),
457+
offsets.into(),
458+
sizes.into(),
459+
interleaved_values,
460+
interleaved.nulls,
461+
);
462+
463+
Ok(Arc::new(list_view_array))
464+
}
465+
414466
/// Fallback implementation of interleave using [`MutableArrayData`]
415467
fn interleave_fallback(
416468
values: &[&dyn Array],
@@ -770,6 +822,61 @@ mod tests {
770822
test_interleave_lists::<i64>();
771823
}
772824

825+
fn test_interleave_list_views<O: OffsetSizeTrait>() {
826+
// [[1, 2], null, [3]]
827+
let mut a = GenericListBuilder::<O, _>::new(Int32Builder::new());
828+
a.values().append_value(1);
829+
a.values().append_value(2);
830+
a.append(true);
831+
a.append(false);
832+
a.values().append_value(3);
833+
a.append(true);
834+
let a: GenericListViewArray<O> = a.finish().into();
835+
836+
// [[4], null, [5, 6, null]]
837+
let mut b = GenericListBuilder::<O, _>::new(Int32Builder::new());
838+
b.values().append_value(4);
839+
b.append(true);
840+
b.append(false);
841+
b.values().append_value(5);
842+
b.values().append_value(6);
843+
b.values().append_null();
844+
b.append(true);
845+
let b: GenericListViewArray<O> = b.finish().into();
846+
847+
let values = interleave(&[&a, &b], &[(0, 2), (0, 1), (1, 0), (1, 2), (1, 1)]).unwrap();
848+
let v = values
849+
.as_any()
850+
.downcast_ref::<GenericListViewArray<O>>()
851+
.unwrap();
852+
853+
// [[3], null, [4], [5, 6, null], null]
854+
let mut expected = GenericListBuilder::<O, _>::new(Int32Builder::new());
855+
expected.values().append_value(3);
856+
expected.append(true);
857+
expected.append(false);
858+
expected.values().append_value(4);
859+
expected.append(true);
860+
expected.values().append_value(5);
861+
expected.values().append_value(6);
862+
expected.values().append_null();
863+
expected.append(true);
864+
expected.append(false);
865+
let expected: GenericListViewArray<O> = expected.finish().into();
866+
867+
assert_eq!(v, &expected);
868+
}
869+
870+
#[test]
871+
fn test_list_views() {
872+
test_interleave_list_views::<i32>();
873+
}
874+
875+
#[test]
876+
fn test_large_list_views() {
877+
test_interleave_list_views::<i64>();
878+
}
879+
773880
#[test]
774881
fn test_struct_without_nulls() {
775882
let fields = Fields::from(vec![

0 commit comments

Comments
 (0)