Path: blob/main/crates/polars-arrow/src/legacy/kernels/take_agg/mod.rs
8474 views
#![allow(unsafe_op_in_unsafe_fn)]1//! kernels that combine take and aggregations.2mod boolean;3mod var;45pub use boolean::*;6use num_traits::ToPrimitive;7use polars_utils::IdxSize;8pub use var::*;910use crate::array::{Array, BinaryViewArray, BooleanArray, PrimitiveArray};11use crate::types::NativeType;1213/// Take kernel for single chunk without nulls and an iterator as index.14/// # Safety15/// caller must ensure iterators indexes are in bounds16#[inline]17pub unsafe fn take_agg_no_null_primitive_iter_unchecked<18T: NativeType + ToPrimitive,19I: IntoIterator<Item = usize>,20>(21arr: &PrimitiveArray<T>,22indices: I,23) -> impl Iterator<Item = T> {24debug_assert!(arr.null_count() == 0);25let array_values = arr.values().as_slice();2627indices28.into_iter()29.map(|idx| *array_values.get_unchecked(idx))30}3132/// Take kernel for single chunk and an iterator as index.33/// # Safety34/// caller must ensure iterators indexes are in bounds35#[inline]36pub unsafe fn take_agg_primitive_iter_unchecked<T: NativeType, I: IntoIterator<Item = usize>>(37arr: &PrimitiveArray<T>,38indices: I,39) -> impl Iterator<Item = T> {40let array_values = arr.values().as_slice();41let validity = arr.validity().unwrap();4243indices44.into_iter()45.filter(|&idx| validity.get_bit_unchecked(idx))46.map(|idx| *array_values.get_unchecked(idx))47}4849/// Take kernel for single chunk and an iterator as index.50/// # Safety51/// caller must ensure iterators indexes are in bounds52#[inline]53pub unsafe fn take_agg_primitive_iter_unchecked_count_nulls<54T: NativeType + ToPrimitive,55I: IntoIterator<Item = usize>,56TOut,57F: Fn(TOut, T) -> TOut,58>(59arr: &PrimitiveArray<T>,60indices: I,61init: TOut,62f: F,63len: IdxSize,64) -> Option<(TOut, IdxSize)> {65let array_values = arr.values().as_slice();66let validity = arr.validity().expect("null buffer should be there");6768let mut null_count = 0 as IdxSize;69let out = indices.into_iter().fold(init, |acc, idx| {70if validity.get_bit_unchecked(idx) {71f(acc, *array_values.get_unchecked(idx))72} else {73null_count += 1;74acc75}76});77if null_count == len {78None79} else {80Some((out, null_count))81}82}8384/// Take kernel for single chunk and an iterator as index.85/// # Safety86/// caller must ensure iterators indexes are in bounds87#[inline]88pub unsafe fn take_agg_bin_iter_unchecked<89'a,90I: IntoIterator<Item = usize>,91F: Fn(&'a [u8], &'a [u8]) -> &'a [u8],92>(93arr: &'a BinaryViewArray,94indices: I,95f: F,96len: IdxSize,97) -> Option<&'a [u8]> {98let mut null_count = 0 as IdxSize;99let validity = arr.validity().unwrap();100101let out = indices102.into_iter()103.map(|idx| {104if validity.get_bit_unchecked(idx) {105Some(arr.value_unchecked(idx))106} else {107None108}109})110.reduce(|acc, opt_val| match (acc, opt_val) {111(Some(acc), Some(str_val)) => Some(f(acc, str_val)),112(_, None) => {113null_count += 1;114acc115},116(None, Some(str_val)) => Some(str_val),117});118if null_count == len {119None120} else {121out.flatten()122}123}124125/// # Safety126/// caller must ensure iterators indexes are in bounds127#[inline]128pub unsafe fn take_agg_bin_iter_unchecked_arg<129'a,130I: IntoIterator<Item = usize>,131F: Fn((IdxSize, &'a [u8]), (IdxSize, &'a [u8])) -> (IdxSize, &'a [u8]),132>(133arr: &'a BinaryViewArray,134indices: I,135f: F,136) -> Option<IdxSize> {137let validity = arr.validity().unwrap();138139indices140.into_iter()141.enumerate()142.filter_map(|(pos, idx)| {143if validity.get_bit_unchecked(idx) {144Some((pos as IdxSize, arr.value_unchecked(idx)))145} else {146None147}148})149.reduce(f)150.map(|(pos, _)| pos)151}152153/// Take kernel for single chunk and an iterator as index.154/// # Safety155/// caller must ensure iterators indexes are in bounds156#[inline]157pub unsafe fn take_agg_bin_iter_unchecked_no_null<158'a,159I: IntoIterator<Item = usize>,160F: Fn(&'a [u8], &'a [u8]) -> &'a [u8],161>(162arr: &'a BinaryViewArray,163indices: I,164f: F,165) -> Option<&'a [u8]> {166indices167.into_iter()168.map(|idx| arr.value_unchecked(idx))169.reduce(|acc, str_val| f(acc, str_val))170}171172/// # Safety173/// caller must ensure iterators indexes are in bounds174#[inline]175pub unsafe fn take_agg_bin_iter_unchecked_no_null_arg<176'a,177I: IntoIterator<Item = usize>,178F: Fn((IdxSize, &'a [u8]), (IdxSize, &'a [u8])) -> (IdxSize, &'a [u8]),179>(180arr: &'a BinaryViewArray,181indices: I,182f: F,183) -> Option<IdxSize> {184indices185.into_iter()186.enumerate()187.map(|(pos, idx)| (pos as IdxSize, arr.value_unchecked(idx)))188.reduce(f)189.map(|(pos, _)| pos)190}191192193