Path: blob/main/crates/polars-arrow/src/legacy/bit_util.rs
6939 views
/// Forked from Arrow until their API stabilizes.1///2/// Note that the bound checks are optimized away.3///4use crate::bitmap::utils::{BitChunkIterExact, BitChunks};56pub fn find_first_true_false_null(7mut bit_chunks: BitChunks<u64>,8mut validity_chunks: BitChunks<u64>,9) -> (Option<usize>, Option<usize>, Option<usize>) {10let (mut true_index, mut false_index, mut null_index) = (None, None, None);11let (mut true_not_found_mask, mut false_not_found_mask, mut null_not_found_mask) =12(!0u64, !0u64, !0u64); // All ones while not found.13let mut offset: usize = 0;14let mut all_found = false;15for (truth_mask, null_mask) in (&mut bit_chunks).zip(&mut validity_chunks) {16let mask = null_mask & truth_mask & true_not_found_mask;17if mask > 0 {18true_index = Some(offset + mask.trailing_zeros() as usize);19true_not_found_mask = 0;20}21let mask = null_mask & !truth_mask & false_not_found_mask;22if mask > 0 {23false_index = Some(offset + mask.trailing_zeros() as usize);24false_not_found_mask = 0;25}26if !null_mask & null_not_found_mask > 0 {27null_index = Some(offset + null_mask.trailing_ones() as usize);28null_not_found_mask = 0;29}30if null_not_found_mask | true_not_found_mask | false_not_found_mask == 0 {31all_found = true;32break;33}34offset += 64;35}36if !all_found {37for (val, not_null) in bit_chunks38.remainder_iter()39.zip(validity_chunks.remainder_iter())40{41if true_index.is_none() && not_null && val {42true_index = Some(offset);43} else if false_index.is_none() && not_null && !val {44false_index = Some(offset);45} else if null_index.is_none() && !not_null {46null_index = Some(offset);47}48offset += 1;49}50}51(true_index, false_index, null_index)52}5354pub fn find_first_true_false_no_null(55mut bit_chunks: BitChunks<u64>,56) -> (Option<usize>, Option<usize>) {57let (mut true_index, mut false_index) = (None, None);58let (mut true_not_found_mask, mut false_not_found_mask) = (!0u64, !0u64); // All ones while not found.59let mut offset: usize = 0;60let mut all_found = false;61for truth_mask in &mut bit_chunks {62let mask = truth_mask & true_not_found_mask;63if mask > 0 {64true_index = Some(offset + mask.trailing_zeros() as usize);65true_not_found_mask = 0;66}67let mask = !truth_mask & false_not_found_mask;68if mask > 0 {69false_index = Some(offset + mask.trailing_zeros() as usize);70false_not_found_mask = 0;71}72if true_not_found_mask | false_not_found_mask == 0 {73all_found = true;74break;75}76offset += 64;77}78if !all_found {79for val in bit_chunks.remainder_iter() {80if true_index.is_none() && val {81true_index = Some(offset);82} else if false_index.is_none() && !val {83false_index = Some(offset);84}85offset += 1;86}87}88(true_index, false_index)89}909192