use rstest::rstest;
use vortex_buffer::buffer;
use super::common::{
create_basic_listview, create_empty_lists_listview, create_large_listview,
create_nullable_listview, create_overlapping_listview,
};
use crate::arrays::{ConstantArray, ListViewArray, PrimitiveArray};
use crate::compute::conformance::take::test_take_conformance;
use crate::compute::take;
use crate::validity::Validity;
use crate::{Array, IntoArray, ToCanonical};
#[rstest]
#[case::basic(create_basic_listview())]
#[case::nullable(create_nullable_listview())]
#[case::empty_lists(create_empty_lists_listview())]
#[case::overlapping(create_overlapping_listview())]
#[case::large(create_large_listview())]
fn test_take_listview_conformance(#[case] listview: ListViewArray) {
test_take_conformance(listview.as_ref());
}
#[ignore = "TODO(connor)[ListView]: Don't rebuild ListView after every `take`"]
#[test]
fn test_take_preserves_unreferenced_elements() {
let elements = buffer![0i32, 1, 2, 3, 4, 5, 6, 7, 8, 9].into_array();
let offsets = buffer![5u32, 2, 8, 0, 1].into_array();
let sizes = buffer![3u32, 2, 2, 2, 4].into_array();
let listview = ListViewArray::try_new(elements.clone(), offsets, sizes, Validity::NonNullable)
.unwrap()
.to_array();
let indices = buffer![1u32, 3].into_array();
let result = take(&listview, &indices).unwrap();
let result_list = result.to_listview();
assert_eq!(result_list.len(), 2);
let result_elements = result_list.elements().to_primitive();
assert_eq!(
result_elements.as_slice::<i32>(),
&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
);
assert_eq!(result_list.offset_at(0), 2); assert_eq!(result_list.offset_at(1), 0); }
#[ignore = "TODO(connor)[ListView]: Don't rebuild ListView after every `take`"]
#[test]
fn test_take_with_gaps() {
let elements = buffer![1i32, 2, 3, 999, 999, 999, 7, 8, 9, 999, 11, 12].into_array();
let offsets = buffer![0u32, 6, 10, 1, 7].into_array();
let sizes = buffer![3u32, 3, 2, 2, 2].into_array();
let listview = ListViewArray::try_new(elements.clone(), offsets, sizes, Validity::NonNullable)
.unwrap()
.to_array();
let indices = buffer![1u32, 3, 4, 2].into_array();
let result = take(&listview, &indices).unwrap();
let result_list = result.to_listview();
let result_elements = result_list.elements().to_primitive();
assert_eq!(
result_elements.as_slice::<i32>(),
&[1, 2, 3, 999, 999, 999, 7, 8, 9, 999, 11, 12]
);
let list0 = result_list.list_elements_at(0);
assert_eq!(list0.scalar_at(0).as_primitive().as_::<i32>().unwrap(), 7);
assert_eq!(list0.scalar_at(1).as_primitive().as_::<i32>().unwrap(), 8);
assert_eq!(list0.scalar_at(2).as_primitive().as_::<i32>().unwrap(), 9);
}
#[ignore = "TODO(connor)[ListView]: Don't rebuild ListView after every `take`"]
#[test]
fn test_take_constant_arrays() {
let elements = buffer![100i32, 200, 300, 400, 500, 600, 700, 800].into_array();
let constant_offsets = ConstantArray::new(2u32, 4).into_array();
let varying_sizes = buffer![1u32, 2, 3, 4].into_array();
let const_offset_list = ListViewArray::try_new(
elements.clone(),
constant_offsets,
varying_sizes,
Validity::NonNullable,
)
.unwrap()
.to_array();
let indices = buffer![3u32, 0, 2].into_array();
let result = take(&const_offset_list, &indices).unwrap();
let result_list = result.to_listview();
assert_eq!(result_list.len(), 3);
assert_eq!(result_list.offset_at(0), 2); assert_eq!(result_list.offset_at(1), 2);
assert_eq!(result_list.offset_at(2), 2);
assert_eq!(result_list.size_at(0), 4); assert_eq!(result_list.size_at(1), 1);
assert_eq!(result_list.size_at(2), 3);
let both_constant_offsets = ConstantArray::new(1u32, 3).into_array();
let both_constant_sizes = ConstantArray::new(3u32, 3).into_array();
let both_const_list = ListViewArray::try_new(
elements,
both_constant_offsets,
both_constant_sizes,
Validity::NonNullable,
)
.unwrap()
.to_array();
let indices2 = buffer![2u32, 0].into_array();
let result2 = take(&both_const_list, &indices2).unwrap();
let result2_list = result2.to_listview();
assert_eq!(result2_list.len(), 2);
assert_eq!(result2_list.offset_at(0), 1);
assert_eq!(result2_list.offset_at(1), 1);
assert_eq!(result2_list.size_at(0), 3);
assert_eq!(result2_list.size_at(1), 3);
}
#[ignore = "TODO(connor)[ListView]: Don't rebuild ListView after every `take`"]
#[test]
fn test_take_extreme_offsets() {
let elements = PrimitiveArray::from_iter(0i32..10000).into_array();
let offsets = buffer![0u32, 4999, 9995, 2500, 7500].into_array();
let sizes = buffer![5u32, 2, 5, 3, 4].into_array();
let listview = ListViewArray::try_new(elements.clone(), offsets, sizes, Validity::NonNullable)
.unwrap()
.to_array();
let indices = buffer![1u32, 4].into_array();
let result = take(&listview, &indices).unwrap();
let result_list = result.to_listview();
assert_eq!(result_list.len(), 2);
assert_eq!(result_list.offset_at(0), 4999);
assert_eq!(result_list.offset_at(1), 7500);
assert_eq!(result_list.elements().len(), 10000);
let list0 = result_list.list_elements_at(0);
assert_eq!(
list0.scalar_at(0).as_primitive().as_::<i32>().unwrap(),
4999
);
assert_eq!(
list0.scalar_at(1).as_primitive().as_::<i32>().unwrap(),
5000
);
}