This is an automated email from the ASF dual-hosted git repository.

alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new 784fa7c2ad chore: deduplicate filter nulls code in coalesce/filter 
kernel (#10348)
784fa7c2ad is described below

commit 784fa7c2ad06aac24686285228d9dec49eed204d
Author: Jeffrey Vo <[email protected]>
AuthorDate: Sun Jul 26 07:20:31 2026 +0900

    chore: deduplicate filter nulls code in coalesce/filter kernel (#10348)
    
    whilst reviewing #10236 i noticed we have a little code duplication, so
    remedying that
---
 arrow-select/src/coalesce/byte_view.rs | 16 ++++++----------
 arrow-select/src/coalesce/primitive.rs | 14 +++-----------
 arrow-select/src/filter.rs             | 27 ---------------------------
 3 files changed, 9 insertions(+), 48 deletions(-)

diff --git a/arrow-select/src/coalesce/byte_view.rs 
b/arrow-select/src/coalesce/byte_view.rs
index f43572b37c..4cf0e006df 100644
--- a/arrow-select/src/coalesce/byte_view.rs
+++ b/arrow-select/src/coalesce/byte_view.rs
@@ -16,11 +16,11 @@
 // under the License.
 
 use crate::coalesce::InProgressArray;
-use crate::filter::{FilterPredicate, FilterSelection, filter_null_mask};
+use crate::filter::{FilterPredicate, FilterSelection};
 use arrow_array::cast::AsArray;
 use arrow_array::types::ByteViewType;
 use arrow_array::{Array, ArrayRef, GenericByteViewArray};
-use arrow_buffer::{BooleanBuffer, Buffer, NullBuffer, NullBufferBuilder};
+use arrow_buffer::{Buffer, NullBuffer, NullBufferBuilder};
 use arrow_data::{ByteView, MAX_INLINE_VIEW_LEN};
 use arrow_schema::ArrowError;
 use std::marker::PhantomData;
@@ -165,15 +165,11 @@ impl<B: ByteViewType> InProgressByteViewArray<B> {
         filter: &FilterPredicate,
         source_nulls: Option<&NullBuffer>,
     ) {
-        let Some((null_count, nulls)) = filter_null_mask(source_nulls, filter) 
else {
+        if let Some(nulls) = filter.filter_nulls(source_nulls) {
+            self.nulls.append_buffer(&nulls);
+        } else {
             self.nulls.append_n_non_nulls(filter.count());
-            return;
-        };
-
-        let nulls = unsafe {
-            NullBuffer::new_unchecked(BooleanBuffer::new(nulls, 0, 
filter.count()), null_count)
-        };
-        self.nulls.append_buffer(&nulls);
+        }
     }
 
     /// Append views to self.views, updating the buffer index if necessary
diff --git a/arrow-select/src/coalesce/primitive.rs 
b/arrow-select/src/coalesce/primitive.rs
index 21ddd956cc..3fa070d627 100644
--- a/arrow-select/src/coalesce/primitive.rs
+++ b/arrow-select/src/coalesce/primitive.rs
@@ -16,12 +16,10 @@
 // under the License.
 
 use crate::coalesce::InProgressArray;
-use crate::filter::{
-    FilterIndices, FilterPredicate, FilterSelection, FilterSlices, 
filter_null_mask,
-};
+use crate::filter::{FilterIndices, FilterPredicate, FilterSelection, 
FilterSlices};
 use arrow_array::cast::AsArray;
 use arrow_array::{Array, ArrayRef, ArrowPrimitiveType, PrimitiveArray};
-use arrow_buffer::{BooleanBuffer, NullBuffer, NullBufferBuilder, ScalarBuffer};
+use arrow_buffer::{NullBuffer, NullBufferBuilder, ScalarBuffer};
 use arrow_schema::{ArrowError, DataType};
 use std::fmt::Debug;
 use std::sync::Arc;
@@ -140,13 +138,7 @@ fn append_filtered_nulls(
     source_nulls: Option<&NullBuffer>,
     filter: &FilterPredicate,
 ) {
-    if let Some((null_count, filtered_nulls)) = filter_null_mask(source_nulls, 
filter) {
-        let filtered_nulls = unsafe {
-            NullBuffer::new_unchecked(
-                BooleanBuffer::new(filtered_nulls, 0, filter.count()),
-                null_count,
-            )
-        };
+    if let Some(filtered_nulls) = filter.filter_nulls(source_nulls) {
         nulls.append_buffer(&filtered_nulls);
     } else {
         nulls.append_n_non_nulls(filter.count());
diff --git a/arrow-select/src/filter.rs b/arrow-select/src/filter.rs
index 8b69811d4a..b7227cf6d9 100644
--- a/arrow-select/src/filter.rs
+++ b/arrow-select/src/filter.rs
@@ -660,33 +660,6 @@ where
     RunArray::try_new(&run_ends, &values)
 }
 
-/// Computes a new null mask for `data` based on `predicate`
-///
-/// If the predicate selected no null-rows, returns `None`, otherwise returns
-/// `Some((null_count, null_buffer))` where `null_count` is the number of nulls
-/// in the filtered output, and `null_buffer` is the filtered null buffer
-///
-pub(crate) fn filter_null_mask(
-    nulls: Option<&NullBuffer>,
-    predicate: &FilterPredicate,
-) -> Option<(usize, Buffer)> {
-    let nulls = nulls?;
-    if nulls.null_count() == 0 {
-        return None;
-    }
-
-    let nulls = filter_bits(nulls.inner(), predicate);
-    // The filtered `nulls` has a length of `predicate.count` bits and
-    // therefore the null count is this minus the number of valid bits
-    let null_count = predicate.count - nulls.count_set_bits_offset(0, 
predicate.count);
-
-    if null_count == 0 {
-        return None;
-    }
-
-    Some((null_count, nulls))
-}
-
 /// Filter the packed bitmask `buffer`, with `predicate` starting at bit 
offset `offset`
 fn filter_bits(buffer: &BooleanBuffer, predicate: &FilterPredicate) -> Buffer {
     let src = buffer.values();

Reply via email to