/// Forked and adapted from arrow-rs
/// This is faster because it does no bounds checks and allocates directly into aligned memory
///
/// Takes/filters a list array's inner data using the offsets of the list array.
///
/// Where a list array has indices `[0,2,5,10]`, taking indices of `[2,0]` returns
/// an array of the indices `[5..10, 0..2]` and offsets `[0,5,7]` (5 elements and 2
/// elements)
///
/// # Safety
/// No bounds checks
Forked and adapted from arrow-rs
This is faster because it does no bounds checks and allocates directly into aligned memory

Takes/filters a list array's inner data using the offsets of the list array.


Forked and adapted from arrow - rs This is faster because it does no bounds checks and allocates directly into aligned memory Takes / filters a list array ' s inner data using the offsets of the list array .
unsafe fn take_value_indices_from_list(
    list: &ListArray<i64>,
    indices: &UInt32Array,
) -> (UInt32Array, AlignedVec<i64>) {
    let offsets = list.offsets().as_slice();
    let mut new_offsets = AlignedVec::with_capacity(indices.len());
    // will likely have at least indices.len values
    let mut values = AlignedVec::with_capacity(indices.len());
    let mut current_offset = 0;
    // add first offset
    new_offsets.push(0);
    // compute the value indices, and set offsets accordingly
    let indices_values = indices.values();
    if indices.null_count() == 0 {
        for i in 0..indices.len() {
            let idx = *indices_values.get_unchecked(i) as usize;
            let start = *offsets.get_unchecked(idx);
            let end = *offsets.get_unchecked(idx + 1);
            current_offset += end - start;
            new_offsets.push(current_offset);
            let mut curr = start;
            // if start == end, this slot is empty
            while curr < end {
                values.push(curr as u32);
                curr += 1;
            }
        }
    } else {
        let validity = indices.validity().as_ref().expect("should have nulls");
        for i in 0..indices.len() {
            if validity.get_bit_unchecked(i) {
                let idx = *indices_values.get_unchecked(i) as usize;
                let start = *offsets.get_unchecked(idx);
                let end = *offsets.get_unchecked(idx + 1);
                current_offset += end - start;
                new_offsets.push(current_offset);
                let mut curr = start;
                // if start == end, this slot is empty
                while curr < end {
                    values.push(curr as u32);
                    curr += 1;
                }
            } else {
                new_offsets.push(current_offset);
            }
        }
    }
    (
        PrimitiveArray::from_data(ArrowDataType::UInt32, values.into(), None),
        new_offsets,
    )
}
unsafe fn take_value_indices_from_list ( list : & ListArray < i64 > , indices : & UInt32Array , ) -> ( UInt32Array , AlignedVec < i64 > ) { let offsets = list . offsets ( ) . as_slice ( ) ; let mut new_offsets = AlignedVec :: with_capacity ( indices . len ( ) ) ; // will likely have at least indices.len values let mut values = AlignedVec :: with_capacity ( indices . len ( ) ) ; let mut current_offset = 0 ; // add first offset new_offsets . push ( 0 ) ; // compute the value indices, and set offsets accordingly let indices_values = indices . values ( ) ; if indices . null_count ( ) == 0 { for i in 0 .. indices . len ( ) { let idx = * indices_values . get_unchecked ( i ) as usize ; let start = * offsets . get_unchecked ( idx ) ; let end = * offsets . get_unchecked ( idx + 1 ) ; current_offset += end - start ; new_offsets . push ( current_offset ) ; let mut curr = start ; // if start == end, this slot is empty while curr < end { values . push ( curr as u32 ) ; curr += 1 ; } } } else { let validity = indices . validity ( ) . as_ref ( ) . expect ( " " ) ; for i in 0 .. indices . len ( ) { if validity . get_bit_unchecked ( i ) { let idx = * indices_values . get_unchecked ( i ) as usize ; let start = * offsets . get_unchecked ( idx ) ; let end = * offsets . get_unchecked ( idx + 1 ) ; current_offset += end - start ; new_offsets . push ( current_offset ) ; let mut curr = start ; // if start == end, this slot is empty while curr < end { values . push ( curr as u32 ) ; curr += 1 ; } } else { new_offsets . push ( current_offset ) ; } } } ( PrimitiveArray :: from_data ( ArrowDataType :: UInt32 , values . into ( ) , None ) , new_offsets , ) }
Forked and adapted from arrow-rs
This is faster because it does no bounds checks and allocates directly into aligned memory
Forked and adapted from arrow - rs This is faster because it does no bounds checks and allocates directly into aligned memory
list
&ListArray<i64>
indices
&UInt32Array
safety
No bounds checks
No bounds checks