Function polars_arrow::bit_util::unset_bit_raw
source · Expand description
Sets bit at position i for data to 0
Safety
Note this doesn’t do any bound checking, for performance reason. The caller is
responsible to guarantee that i is within bounds.
Examples found in repository?
src/compute/take/mod.rs (line 83)
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
pub unsafe fn take_primitive_unchecked<T: NativeType>(
arr: &PrimitiveArray<T>,
indices: &IdxArr,
) -> Box<PrimitiveArray<T>> {
let array_values = arr.values().as_slice();
let index_values = indices.values().as_slice();
let validity_values = arr.validity().expect("should have nulls");
// first take the values, these are always needed
let values: Vec<T> = index_values
.iter()
.map(|idx| {
debug_assert!((*idx as usize) < array_values.len());
*array_values.get_unchecked(*idx as usize)
})
.collect_trusted();
// the validity buffer we will fill with all valid. And we unset the ones that are null
// in later checks
// this is in the assumption that most values will be valid.
// Maybe we could add another branch based on the null count
let mut validity = MutableBitmap::with_capacity(indices.len());
validity.extend_constant(indices.len(), true);
let validity_ptr = validity.as_slice().as_ptr() as *mut u8;
if let Some(validity_indices) = indices.validity().as_ref() {
index_values.iter().enumerate().for_each(|(i, idx)| {
// i is iteration count
// idx is the index that we take from the values array.
let idx = *idx as usize;
if !validity_indices.get_bit_unchecked(i) || !validity_values.get_bit_unchecked(idx) {
unset_bit_raw(validity_ptr, i);
}
});
} else {
index_values.iter().enumerate().for_each(|(i, idx)| {
let idx = *idx as usize;
if !validity_values.get_bit_unchecked(idx) {
unset_bit_raw(validity_ptr, i);
}
});
};
let arr = PrimitiveArray::new(T::PRIMITIVE.into(), values.into(), Some(validity.into()));
Box::new(arr)
}