polars_arrow/compute/take/
mod.rsuse crate::array::{
self, new_empty_array, Array, ArrayCollectIterExt, ArrayFromIterDtype, NullArray, StaticArray,
Utf8ViewArray,
};
use crate::compute::take::binview::take_binview_unchecked;
use crate::datatypes::{ArrowDataType, IdxArr};
use crate::types::Index;
mod binary;
mod binview;
mod bitmap;
mod boolean;
mod fixed_size_list;
mod generic_binary;
mod list;
mod primitive;
mod structure;
use crate::with_match_primitive_type_full;
pub unsafe fn take_unchecked(values: &dyn Array, indices: &IdxArr) -> Box<dyn Array> {
if indices.len() == 0 {
return new_empty_array(values.dtype().clone());
}
use crate::datatypes::PhysicalType::*;
match values.dtype().to_physical_type() {
Null => Box::new(NullArray::new(values.dtype().clone(), indices.len())),
Boolean => {
let values = values.as_any().downcast_ref().unwrap();
Box::new(boolean::take_unchecked(values, indices))
},
Primitive(primitive) => with_match_primitive_type_full!(primitive, |$T| {
let values = values.as_any().downcast_ref().unwrap();
Box::new(primitive::take_primitive_unchecked::<$T>(&values, indices))
}),
LargeBinary => {
let values = values.as_any().downcast_ref().unwrap();
Box::new(binary::take_unchecked::<i64, _>(values, indices))
},
Struct => {
let array = values.as_any().downcast_ref().unwrap();
structure::take_unchecked(array, indices).boxed()
},
LargeList => {
let array = values.as_any().downcast_ref().unwrap();
Box::new(list::take_unchecked::<i64>(array, indices))
},
FixedSizeList => {
let array = values.as_any().downcast_ref().unwrap();
fixed_size_list::take_unchecked(array, indices)
},
BinaryView => {
take_binview_unchecked(values.as_any().downcast_ref().unwrap(), indices).boxed()
},
Utf8View => {
let arr: &Utf8ViewArray = values.as_any().downcast_ref().unwrap();
take_binview_unchecked(&arr.to_binview(), indices)
.to_utf8view_unchecked()
.boxed()
},
t => unimplemented!("Take not supported for data type {:?}", t),
}
}
unsafe fn take_unchecked_impl_generic<T>(
values: &T,
indices: &IdxArr,
new_null_func: &dyn Fn(ArrowDataType, usize) -> T,
) -> T
where
T: StaticArray + ArrayFromIterDtype<std::option::Option<Box<dyn array::Array>>>,
{
if values.null_count() == values.len() || indices.null_count() == indices.len() {
return new_null_func(values.dtype().clone(), indices.len());
}
match (indices.has_nulls(), values.has_nulls()) {
(true, true) => {
let values_validity = values.validity().unwrap();
indices
.iter()
.map(|i| {
if let Some(i) = i {
let i = *i as usize;
if values_validity.get_bit_unchecked(i) {
return Some(values.value_unchecked(i));
}
}
None
})
.collect_arr_trusted_with_dtype(values.dtype().clone())
},
(true, false) => indices
.iter()
.map(|i| {
if let Some(i) = i {
let i = *i as usize;
return Some(values.value_unchecked(i));
}
None
})
.collect_arr_trusted_with_dtype(values.dtype().clone()),
(false, true) => {
let values_validity = values.validity().unwrap();
indices
.values_iter()
.map(|i| {
let i = *i as usize;
if values_validity.get_bit_unchecked(i) {
return Some(values.value_unchecked(i));
}
None
})
.collect_arr_trusted_with_dtype(values.dtype().clone())
},
(false, false) => indices
.values_iter()
.map(|i| {
let i = *i as usize;
Some(values.value_unchecked(i))
})
.collect_arr_trusted_with_dtype(values.dtype().clone()),
}
}