Repository: jorgecarleitao/arrow2
Pull request #1087 (2022-06-19 17:53:21)

Renamed `Bitmap::null_count` to `Bitmap::unset_bits`
`null_count` is not a very relatable name to a "bitmap", since the association `null <> unset_bit` only emerges in arrays - this PR renames the function (and marks the old as deprecated).


codecov[bot]: # [Codecov](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao) Report
> Merging [#1087](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao) (f33c3a5) into [main](https://codecov.io/gh/jorgecarleitao/arrow2/commit/d1ab4efa5c895513681bacd5e20660be882433ac?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao) (d1ab4ef) will **increase** coverage by `0.00%`.
> The diff coverage is `94.73%`.

> :exclamation: Current head f33c3a5 differs from pull request most recent head f1a0bcc. Consider uploading reports for the commit f1a0bcc to get more accurate results

```diff
@@           Coverage Diff           @@
##             main    #1087   +/-   ##
=======================================
  Coverage   81.07%   81.08%           
=======================================
  Files         367      367           
  Lines       35309    35315    +6     
=======================================
+ Hits        28628    28634    +6     
  Misses       6681     6681           
```


| [Impacted Files](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao) | Coverage Δ | |
|---|---|---|
| [src/io/parquet/write/binary/basic.rs](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao#diff-c3JjL2lvL3BhcnF1ZXQvd3JpdGUvYmluYXJ5L2Jhc2ljLnJz) | `68.14% <0.00%> (ø)` | |
| [src/bitmap/mutable.rs](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao#diff-c3JjL2JpdG1hcC9tdXRhYmxlLnJz) | `96.86% <80.00%> (-0.66%)` | :arrow_down: |
| [src/bitmap/immutable.rs](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao#diff-c3JjL2JpdG1hcC9pbW11dGFibGUucnM=) | `81.48% <90.00%> (-1.54%)` | :arrow_down: |
| [src/array/binary/mutable.rs](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao#diff-c3JjL2FycmF5L2JpbmFyeS9tdXRhYmxlLnJz) | `87.97% <100.00%> (ø)` | |
| [src/array/boolean/mutable.rs](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao#diff-c3JjL2FycmF5L2Jvb2xlYW4vbXV0YWJsZS5ycw==) | `89.32% <100.00%> (ø)` | |
| [src/array/mod.rs](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao#diff-c3JjL2FycmF5L21vZC5ycw==) | `68.54% <100.00%> (ø)` | |
| [src/array/physical\_binary.rs](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao#diff-c3JjL2FycmF5L3BoeXNpY2FsX2JpbmFyeS5ycw==) | `97.67% <100.00%> (ø)` | |
| [src/array/primitive/mutable.rs](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao#diff-c3JjL2FycmF5L3ByaW1pdGl2ZS9tdXRhYmxlLnJz) | `95.57% <100.00%> (ø)` | |
| [src/array/utf8/mutable.rs](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao#diff-c3JjL2FycmF5L3V0ZjgvbXV0YWJsZS5ycw==) | `84.00% <100.00%> (ø)` | |
| [src/bitmap/assign\_ops.rs](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao#diff-c3JjL2JpdG1hcC9hc3NpZ25fb3BzLnJz) | `83.06% <100.00%> (ø)` | |
| ... and [13 more](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao). Last update [d1ab4ef...f1a0bcc](https://codecov.io/gh/jorgecarleitao/arrow2/pull/1087?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jorge+Leitao).


Patch:
diff --git a/benches/bitmap_ops.rs b/benches/bitmap_ops.rs
index f9c667db5e..dcd38661bf 100644
--- a/benches/bitmap_ops.rs
+++ b/benches/bitmap_ops.rs
@@ -4,7 +4,7 @@ use arrow2::bitmap::Bitmap;
 
 fn bench_arrow2(lhs: &Bitmap, rhs: &Bitmap) {
     let r = lhs | rhs;
-    assert!(r.null_count() > 0);
+    assert!(r.unset_bits() > 0);
 }
 
 fn add_benchmark(c: &mut Criterion) {
@@ -15,7 +15,7 @@ fn add_benchmark(c: &mut Criterion) {
         c.bench_function(&format!("bitmap aligned not 2^{}", log2_size), |b| {
             b.iter(|| {
                 let r = !&bitmap;
-                assert!(r.null_count() > 0);
+                assert!(r.unset_bits() > 0);
             })
         });
 
@@ -27,7 +27,7 @@ fn add_benchmark(c: &mut Criterion) {
             |b| {
                 b.iter(|| {
                     let r = bitmap.clone().slice(offset, len);
-                    assert!(r.null_count() > 0);
+                    assert!(r.unset_bits() > 0);
                 })
             },
         );
@@ -40,7 +40,7 @@ fn add_benchmark(c: &mut Criterion) {
             |b| {
                 b.iter(|| {
                     let r = bitmap.clone().slice(offset, len);
-                    assert!(r.null_count() > 0);
+                    assert!(r.unset_bits() > 0);
                 })
             },
         );
@@ -49,7 +49,7 @@ fn add_benchmark(c: &mut Criterion) {
         c.bench_function(&format!("bitmap not 2^{}", log2_size), |b| {
             b.iter(|| {
                 let r = !&bitmap1;
-                assert!(r.null_count() > 0);
+                assert!(r.unset_bits() > 0);
             })
         });
 
diff --git a/benches/slices_iterator.rs b/benches/slices_iterator.rs
index 854225886a..4a4e81e27a 100644
--- a/benches/slices_iterator.rs
+++ b/benches/slices_iterator.rs
@@ -3,7 +3,7 @@ use criterion::{criterion_group, criterion_main, Criterion};
 use arrow2::bitmap::{utils::SlicesIterator, Bitmap};
 
 fn bench_slices(lhs: &Bitmap) {
-    let set_count = lhs.len() - lhs.null_count();
+    let set_count = lhs.len() - lhs.unset_bits();
     let slices = SlicesIterator::new(lhs);
 
     let count = slices.fold(0usize, |acc, v| acc + v.1);
diff --git a/src/array/binary/mutable.rs b/src/array/binary/mutable.rs
index 78de609976..7c44a5ff44 100644
--- a/src/array/binary/mutable.rs
+++ b/src/array/binary/mutable.rs
@@ -306,7 +306,7 @@ impl<O: Offset> MutableBinaryArray<O> {
         // soundness: assumed trusted len
         let (mut validity, offsets, values) = try_trusted_len_unzip(iterator)?;
 
-        if validity.as_mut().unwrap().null_count() == 0 {
+        if validity.as_mut().unwrap().unset_bits() == 0 {
             validity = None;
         }
 
@@ -395,7 +395,7 @@ impl<O: Offset> MutableBinaryArray<O> {
             iterator,
         );
 
-        if self.validity.as_mut().unwrap().null_count() == 0 {
+        if self.validity.as_mut().unwrap().unset_bits() == 0 {
             self.validity = None;
         }
     }
diff --git a/src/array/boolean/mutable.rs b/src/array/boolean/mutable.rs
index 647d9e0214..39acab03e0 100644
--- a/src/array/boolean/mutable.rs
+++ b/src/array/boolean/mutable.rs
@@ -173,7 +173,7 @@ impl MutableBooleanArray {
 
             extend_trusted_len_unzip(iterator, &mut validity, &mut self.values);
 
-            if validity.null_count() > 0 {
+            if validity.unset_bits() > 0 {
                 self.validity = Some(validity);
             }
         }
@@ -299,7 +299,7 @@ impl MutableBooleanArray {
     {
         let (validity, values) = try_trusted_len_unzip(iterator)?;
 
-        let validity = if validity.null_count() > 0 {
+        let validity = if validity.unset_bits() > 0 {
             Some(validity)
         } else {
             None
@@ -344,7 +344,7 @@ where
 
     extend_trusted_len_unzip(iterator, &mut validity, &mut values);
 
-    let validity = if validity.null_count() > 0 {
+    let validity = if validity.unset_bits() > 0 {
         Some(validity)
     } else {
         None
diff --git a/src/array/mod.rs b/src/array/mod.rs
index 427dae7f65..e020a1bd18 100644
--- a/src/array/mod.rs
+++ b/src/array/mod.rs
@@ -63,7 +63,7 @@ pub trait Array: Send + Sync + dyn_clone::DynClone + 'static {
         };
         self.validity()
             .as_ref()
-            .map(|x| x.null_count())
+            .map(|x| x.unset_bits())
             .unwrap_or(0)
     }
 
diff --git a/src/array/physical_binary.rs b/src/array/physical_binary.rs
index b1395c0bb9..7c41fce41a 100644
--- a/src/array/physical_binary.rs
+++ b/src/array/physical_binary.rs
@@ -72,7 +72,7 @@ where
 
     extend_from_trusted_len_iter(&mut offsets, &mut values, &mut validity, iterator);
 
-    let validity = if validity.null_count() > 0 {
+    let validity = if validity.unset_bits() > 0 {
         Some(validity)
     } else {
         None
diff --git a/src/array/primitive/mutable.rs b/src/array/primitive/mutable.rs
index 573fa8953a..c390690d3b 100644
--- a/src/array/primitive/mutable.rs
+++ b/src/array/primitive/mutable.rs
@@ -25,7 +25,7 @@ impl<T: NativeType> From<MutablePrimitiveArray<T>> for PrimitiveArray<T> {
     fn from(other: MutablePrimitiveArray<T>) -> Self {
         let validity = other.validity.and_then(|x| {
             let bitmap: Bitmap = x.into();
-            if bitmap.null_count() == 0 {
+            if bitmap.unset_bits() == 0 {
                 None
             } else {
                 Some(bitmap)
diff --git a/src/array/utf8/mutable.rs b/src/array/utf8/mutable.rs
index d8c0998d75..3d53e69bbb 100644
--- a/src/array/utf8/mutable.rs
+++ b/src/array/utf8/mutable.rs
@@ -39,7 +39,7 @@ impl<O: Offset> From<MutableUtf8Array<O>> for Utf8Array<O> {
         // `Utf8Array` can be safely created from `MutableUtf8Array` without checks.
         let validity = other.validity.and_then(|x| {
             let bitmap: Bitmap = x.into();
-            if bitmap.null_count() == 0 {
+            if bitmap.unset_bits() == 0 {
                 None
             } else {
                 Some(bitmap)
diff --git a/src/bitmap/assign_ops.rs b/src/bitmap/assign_ops.rs
index 31bfa24e2e..81ded04578 100644
--- a/src/bitmap/assign_ops.rs
+++ b/src/bitmap/assign_ops.rs
@@ -107,11 +107,11 @@ where
 #[inline]
 /// Compute bitwise OR operation in-place
 fn or_assign<T: BitChunk>(lhs: &mut MutableBitmap, rhs: &Bitmap) {
-    if rhs.null_count() == 0 {
+    if rhs.unset_bits() == 0 {
         assert_eq!(lhs.len(), rhs.len());
         lhs.clear();
         lhs.extend_constant(rhs.len(), true);
-    } else if rhs.null_count() == rhs.len() {
+    } else if rhs.unset_bits() == rhs.len() {
         // bitmap remains
     } else {
         binary_assign(lhs, rhs, |x: T, y| x | y)
@@ -138,10 +138,10 @@ impl<'a, 'b> std::ops::BitOr<&'a Bitmap> for MutableBitmap {
 #[inline]
 /// Compute bitwise `&` between `lhs` and `rhs`, assigning it to `lhs`
 fn and_assign<T: BitChunk>(lhs: &mut MutableBitmap, rhs: &Bitmap) {
-    if rhs.null_count() == 0 {
+    if rhs.unset_bits() == 0 {
         // bitmap remains
     }
-    if rhs.null_count() == rhs.len() {
+    if rhs.unset_bits() == rhs.len() {
         assert_eq!(lhs.len(), rhs.len());
         lhs.clear();
         lhs.extend_constant(rhs.len(), false);
diff --git a/src/bitmap/bitmap_ops.rs b/src/bitmap/bitmap_ops.rs
index ee3b8e619e..46a525a049 100644
--- a/src/bitmap/bitmap_ops.rs
+++ b/src/bitmap/bitmap_ops.rs
@@ -166,7 +166,7 @@ pub(crate) fn align(bitmap: &Bitmap, new_offset: usize) -> Bitmap {
 #[inline]
 /// Compute bitwise AND operation
 pub fn and(lhs: &Bitmap, rhs: &Bitmap) -> Bitmap {
-    if lhs.null_count() == lhs.len() || rhs.null_count() == rhs.len() {
+    if lhs.unset_bits() == lhs.len() || rhs.unset_bits() == rhs.len() {
         assert_eq!(lhs.len(), rhs.len());
         Bitmap::new_zeroed(lhs.len())
     } else {
@@ -177,7 +177,7 @@ pub fn and(lhs: &Bitmap, rhs: &Bitmap) -> Bitmap {
 #[inline]
 /// Compute bitwise OR operation
 pub fn or(lhs: &Bitmap, rhs: &Bitmap) -> Bitmap {
-    if lhs.null_count() == 0 || rhs.null_count() == 0 {
+    if lhs.unset_bits() == 0 || rhs.unset_bits() == 0 {
         assert_eq!(lhs.len(), rhs.len());
         let mut mutable = MutableBitmap::with_capacity(lhs.len());
         mutable.extend_constant(lhs.len(), true);
@@ -190,8 +190,8 @@ pub fn or(lhs: &Bitmap, rhs: &Bitmap) -> Bitmap {
 #[inline]
 /// Compute bitwise XOR operation
 pub fn xor(lhs: &Bitmap, rhs: &Bitmap) -> Bitmap {
-    let lhs_nulls = lhs.null_count();
-    let rhs_nulls = rhs.null_count();
+    let lhs_nulls = lhs.unset_bits();
+    let rhs_nulls = rhs.unset_bits();
 
     // all false or all true
     if lhs_nulls == rhs_nulls && rhs_nulls == rhs.len() || lhs_nulls == 0 && rhs_nulls == 0 {
diff --git a/src/bitmap/immutable.rs b/src/bitmap/immutable.rs
index c9514e30b8..5384ae5ec1 100644
--- a/src/bitmap/immutable.rs
+++ b/src/bitmap/immutable.rs
@@ -48,7 +48,7 @@ pub struct Bitmap {
     offset: usize,
     length: usize,
     // this is a cache: it is computed on initialization
-    null_count: usize,
+    unset_bits: usize,
 }
 
 impl std::fmt::Debug for Bitmap {
@@ -83,12 +83,12 @@ impl Bitmap {
                 bytes.len().saturating_mul(8)
             )));
         }
-        let null_count = count_zeros(&bytes, 0, length);
+        let unset_bits = count_zeros(&bytes, 0, length);
         Ok(Self {
             length,
             offset: 0,
             bytes: Arc::new(bytes.into()),
-            null_count,
+            unset_bits,
         })
     }
 
@@ -122,12 +122,12 @@ impl Bitmap {
     #[inline]
     pub(crate) fn from_bytes(bytes: Bytes<u8>, length: usize) -> Self {
         assert!(length <= bytes.len() * 8);
-        let null_count = count_zeros(&bytes, 0, length);
+        let unset_bits = count_zeros(&bytes, 0, length);
         Self {
             length,
             offset: 0,
             bytes: Arc::new(bytes),
-            null_count,
+            unset_bits,
         }
     }
 
@@ -149,10 +149,21 @@ impl Bitmap {
         )
     }
 
+    /// Returns the number of unset bits on this [`Bitmap`].
+    ///
+    /// Guaranted to be `<= self.len()`.
+    /// # Implementation
+    /// This function is `O(1)` - the number of unset bits is computed when the bitmap is
+    /// created
+    pub const fn unset_bits(&self) -> usize {
+        self.unset_bits
+    }
+
     /// Returns the number of unset bits on this [`Bitmap`].
     #[inline]
+    #[deprecated(since = "0.13.0", note = "use `unset_bits` instead")]
     pub fn null_count(&self) -> usize {
-        self.null_count
+        self.unset_bits
     }
 
     /// Slices `self`, offsetting by `offset` and truncating up to `length` bits.
@@ -174,13 +185,13 @@ impl Bitmap {
         // count the smallest chunk
         if length < self.length / 2 {
             // count the null values in the slice
-            self.null_count = count_zeros(&self.bytes, self.offset + offset, length);
+            self.unset_bits = count_zeros(&self.bytes, self.offset + offset, length);
         } else {
             // subtract the null count of the chunks we slice off
             let start_end = self.offset + offset + length;
             let head_count = count_zeros(&self.bytes, self.offset, offset);
             let tail_count = count_zeros(&self.bytes, start_end, self.length - length - offset);
-            self.null_count -= head_count + tail_count;
+            self.unset_bits -= head_count + tail_count;
         }
         self.offset += offset;
         self.length = length;
diff --git a/src/bitmap/mutable.rs b/src/bitmap/mutable.rs
index d490a74eac..2cfc253b2a 100644
--- a/src/bitmap/mutable.rs
+++ b/src/bitmap/mutable.rs
@@ -224,11 +224,20 @@ impl MutableBitmap {
     }
 
     /// Returns the number of unset bits on this [`MutableBitmap`].
-    #[inline]
-    pub fn null_count(&self) -> usize {
+    ///
+    /// Guaranted to be `<= self.len()`.
+    /// # Implementation
+    /// This function is `O(N)`
+    pub fn unset_bits(&self) -> usize {
         count_zeros(&self.buffer, 0, self.length)
     }
 
+    /// Returns the number of unset bits on this [`MutableBitmap`].
+    #[deprecated(since = "0.13.0", note = "use `unset_bits` instead")]
+    pub fn null_count(&self) -> usize {
+        self.unset_bits()
+    }
+
     /// Returns the length of the [`MutableBitmap`].
     #[inline]
     pub fn len(&self) -> usize {
@@ -327,7 +336,7 @@ impl From<MutableBitmap> for Bitmap {
 impl From<MutableBitmap> for Option<Bitmap> {
     #[inline]
     fn from(buffer: MutableBitmap) -> Self {
-        if buffer.null_count() > 0 {
+        if buffer.unset_bits() > 0 {
             Some(Bitmap::try_new(buffer.buffer, buffer.length).unwrap())
         } else {
             None
diff --git a/src/bitmap/utils/slice_iterator.rs b/src/bitmap/utils/slice_iterator.rs
index e539baa011..bf5fab578c 100644
--- a/src/bitmap/utils/slice_iterator.rs
+++ b/src/bitmap/utils/slice_iterator.rs
@@ -39,7 +39,7 @@ impl<'a> SlicesIterator<'a> {
 
         Self {
             state,
-            count: values.len() - values.null_count(),
+            count: values.len() - values.unset_bits(),
             max_len: values.len(),
             values: iter,
             mask: 1u8.rotate_left(offset as u32),
diff --git a/src/compute/aggregate/min_max.rs b/src/compute/aggregate/min_max.rs
index b9338a2d19..00f76b052b 100644
--- a/src/compute/aggregate/min_max.rs
+++ b/src/compute/aggregate/min_max.rs
@@ -263,7 +263,7 @@ pub fn min_boolean(array: &BooleanArray) -> Option<bool> {
     if null_count == array.len() {
         None
     } else if null_count == 0 {
-        Some(array.values().null_count() == 0)
+        Some(array.values().unset_bits() == 0)
     } else {
         // Note the min bool is false (0), so short circuit as soon as we see it
         array
@@ -291,7 +291,7 @@ pub fn max_boolean(array: &BooleanArray) -> Option<bool> {
     if null_count == array.len() {
         None
     } else if null_count == 0 {
-        Some(array.values().null_count() < array.len())
+        Some(array.values().unset_bits() < array.len())
     } else {
         // Note the max bool is true (1), so short circuit as soon as we see it
         array
diff --git a/src/compute/boolean.rs b/src/compute/boolean.rs
index b6738c068c..39084400f9 100644
--- a/src/compute/boolean.rs
+++ b/src/compute/boolean.rs
@@ -194,7 +194,7 @@ pub fn any(array: &BooleanArray) -> bool {
         array.into_iter().any(|v| v == Some(true))
     } else {
         let vals = array.values();
-        vals.null_count() != vals.len()
+        vals.unset_bits() != vals.len()
     }
 }
 
@@ -204,6 +204,6 @@ pub fn all(array: &BooleanArray) -> bool {
         false
     } else {
         let vals = array.values();
-        vals.null_count() == 0
+        vals.unset_bits() == 0
     }
 }
diff --git a/src/compute/filter.rs b/src/compute/filter.rs
index 1f7db06183..4bcb2be744 100644
--- a/src/compute/filter.rs
+++ b/src/compute/filter.rs
@@ -136,7 +136,7 @@ fn null_filter_simd<T: NativeType + Simd>(
     mask: &Bitmap,
 ) -> (Vec<T>, MutableBitmap) {
     assert_eq!(values.len(), mask.len());
-    let filter_count = mask.len() - mask.null_count();
+    let filter_count = mask.len() - mask.unset_bits();
 
     let (slice, offset, length) = mask.as_slice();
     if offset == 0 {
@@ -150,7 +150,7 @@ fn null_filter_simd<T: NativeType + Simd>(
 
 fn nonnull_filter_simd<T: NativeType + Simd>(values: &[T], mask: &Bitmap) -> Vec<T> {
     assert_eq!(values.len(), mask.len());
-    let filter_count = mask.len() - mask.null_count();
+    let filter_count = mask.len() - mask.unset_bits();
 
     let (slice, offset, length) = mask.as_slice();
     if offset == 0 {
@@ -264,7 +264,7 @@ pub fn filter(array: &dyn Array, filter: &BooleanArray) -> Result<Box<dyn Array>
         return crate::compute::filter::filter(array, &filter);
     }
 
-    let false_count = filter.values().null_count();
+    let false_count = filter.values().unset_bits();
     if false_count == filter.len() {
         assert_eq!(array.len(), filter.len());
         return Ok(array.slice(0, 0));
diff --git a/src/compute/sort/common.rs b/src/compute/sort/common.rs
index dea456c72a..cb221d50ad 100644
--- a/src/compute/sort/common.rs
+++ b/src/compute/sort/common.rs
@@ -105,7 +105,7 @@ where
                 .zip(I::range(0, length).unwrap())
                 .for_each(|(is_valid, index)| {
                     if is_valid {
-                        indices[validity.null_count() + valids] = index;
+                        indices[validity.unset_bits() + valids] = index;
                         valids += 1;
                     } else {
                         indices[nulls] = index;
@@ -113,18 +113,18 @@ where
                     }
                 });
 
-            if limit > validity.null_count() {
+            if limit > validity.unset_bits() {
                 // when limit is larger, we must sort values:
 
                 // Soundness:
                 // all indices in `indices` are by construction `< array.len() == values.len()`
                 // limit is by construction < indices.len()
-                let limit = limit.saturating_sub(validity.null_count());
-                let indices = &mut indices.as_mut_slice()[validity.null_count()..];
+                let limit = limit.saturating_sub(validity.unset_bits());
+                let indices = &mut indices.as_mut_slice()[validity.unset_bits()..];
                 sort_unstable_by(indices, get, cmp, options.descending, limit)
             }
         } else {
-            let last_valid_index = length.saturating_sub(validity.null_count());
+            let last_valid_index = length.saturating_sub(validity.unset_bits());
             let mut nulls = 0;
             let mut valids = 0;
             validity
diff --git a/src/compute/sort/primitive/sort.rs b/src/compute/sort/primitive/sort.rs
index a496edcf9c..106c991f34 100644
--- a/src/compute/sort/primitive/sort.rs
+++ b/src/compute/sort/primitive/sort.rs
@@ -70,14 +70,14 @@ where
     F: FnMut(&T, &T) -> std::cmp::Ordering,
 {
     assert!(limit <= values.len());
-    if options.nulls_first && limit < validity.null_count() {
+    if options.nulls_first && limit < validity.unset_bits() {
         let buffer = vec![T::default(); limit];
         let bitmap = MutableBitmap::from_trusted_len_iter(std::iter::repeat(false).take(limit));
         return (buffer.into(), bitmap.into());
     }
 
-    let nulls = std::iter::repeat(false).take(validity.null_count());
-    let valids = std::iter::repeat(true).take(values.len() - validity.null_count());
+    let nulls = std::iter::repeat(false).take(validity.unset_bits());
+    let valids = std::iter::repeat(true).take(values.len() - validity.unset_bits());
 
     let mut buffer = Vec::<T>::with_capacity(values.len());
     let mut new_validity = MutableBitmap::with_capacity(values.len());
@@ -88,17 +88,17 @@ where
         new_validity.extend_from_trusted_len_iter(nulls.chain(valids).take(limit));
 
         // extend buffer with constants followed by non-null values
-        buffer.resize(validity.null_count(), T::default());
+        buffer.resize(validity.unset_bits(), T::default());
         for (start, len) in slices {
             buffer.extend_from_slice(&values[start..start + len])
         }
 
         // sort values
         sort_values(
-            &mut buffer.as_mut_slice()[validity.null_count()..],
+            &mut buffer.as_mut_slice()[validity.unset_bits()..],
             cmp,
             options.descending,
-            limit - validity.null_count(),
+            limit - validity.unset_bits(),
         );
     } else {
         // validity is [1,1,1,...,0,0,0,0]
@@ -114,12 +114,12 @@ where
             buffer.as_mut_slice(),
             cmp,
             options.descending,
-            limit - validity.null_count(),
+            limit - validity.unset_bits(),
         );
 
-        if limit > values.len() - validity.null_count() {
+        if limit > values.len() - validity.unset_bits() {
             // extend remaining with nulls
-            buffer.resize(buffer.len() + validity.null_count(), T::default());
+            buffer.resize(buffer.len() + validity.unset_bits(), T::default());
         }
     };
     // values are sorted, we can now truncate the remaining.
diff --git a/src/io/parquet/write/binary/basic.rs b/src/io/parquet/write/binary/basic.rs
index 6bfe2fa484..58156c901e 100644
--- a/src/io/parquet/write/binary/basic.rs
+++ b/src/io/parquet/write/binary/basic.rs
@@ -133,7 +133,7 @@ pub(crate) fn encode_delta<O: Offset>(
                 .map(|w| (w[1] - w[0]).to_usize() as i64)
                 .zip(validity.iter())
                 .flat_map(|(x, is_valid)| if is_valid { Some(x) } else { None });
-            let length = offsets.len() - 1 - validity.null_count();
+            let length = offsets.len() - 1 - validity.unset_bits();
             let lengths = utils::ExactSizedIter::new(lengths, length);
 
             delta_bitpacked::encode(lengths, buffer);
diff --git a/src/io/parquet/write/boolean/basic.rs b/src/io/parquet/write/boolean/basic.rs
index 418d67576c..74f5b5a506 100644
--- a/src/io/parquet/write/boolean/basic.rs
+++ b/src/io/parquet/write/boolean/basic.rs
@@ -28,7 +28,7 @@ pub(super) fn encode_plain(
             array
                 .validity()
                 .as_ref()
-                .map(|x| x.len() - x.null_count())
+                .map(|x| x.len() - x.unset_bits())
                 .unwrap_or_else(|| array.len()),
         );
         encode(iter, buffer)
diff --git a/src/io/parquet/write/dictionary.rs b/src/io/parquet/write/dictionary.rs
index 8aeba5d52b..65f13a4904 100644
--- a/src/io/parquet/write/dictionary.rs
+++ b/src/io/parquet/write/dictionary.rs
@@ -42,7 +42,7 @@ fn encode_keys<K: DictionaryKey>(
         });
         let projected_val = Bitmap::from_trusted_len_iter(projected_validity);
 
-        let null_count = projected_val.null_count();
+        let null_count = projected_val.unset_bits();
 
         utils::write_def_levels(
             &mut buffer,


Test patch:
diff --git a/tests/it/array/primitive/mutable.rs b/tests/it/array/primitive/mutable.rs
index 2de49822c3..762c1a2404 100644
--- a/tests/it/array/primitive/mutable.rs
+++ b/tests/it/array/primitive/mutable.rs
@@ -133,7 +133,7 @@ fn from_iter() {
     let a = MutablePrimitiveArray::<i32>::from_iter((0..2).map(Some));
     assert_eq!(a.len(), 2);
     let validity = a.validity().unwrap();
-    assert_eq!(validity.null_count(), 0);
+    assert_eq!(validity.unset_bits(), 0);
 }
 
 #[test]
@@ -194,7 +194,7 @@ fn extend_trusted_len() {
     let mut a = MutablePrimitiveArray::<i32>::new();
     a.extend_trusted_len(vec![Some(1), Some(2)].into_iter());
     let validity = a.validity().unwrap();
-    assert_eq!(validity.null_count(), 0);
+    assert_eq!(validity.unset_bits(), 0);
     a.extend_trusted_len(vec![None, Some(4)].into_iter());
     assert_eq!(
         a.validity(),
@@ -285,7 +285,7 @@ fn set_validity() {
     let mut a = MutablePrimitiveArray::<i32>::new();
     a.extend_trusted_len(vec![Some(1), Some(2)].into_iter());
     let validity = a.validity().unwrap();
-    assert_eq!(validity.null_count(), 0);
+    assert_eq!(validity.unset_bits(), 0);
 
     // test that upon conversion to array the bitmap is set to None
     let arr: PrimitiveArray<_> = a.clone().into();
diff --git a/tests/it/bitmap/mod.rs b/tests/it/bitmap/mod.rs
index c04e2c009d..59d5100415 100644
--- a/tests/it/bitmap/mod.rs
+++ b/tests/it/bitmap/mod.rs
@@ -113,13 +113,13 @@ fn not() {
 #[test]
 fn subslicing_gives_correct_null_count() {
     let base = Bitmap::from([false, true, true, false, false, true, true, true]);
-    assert_eq!(base.null_count(), 3);
+    assert_eq!(base.unset_bits(), 3);
 
     let view1 = base.clone().slice(0, 1);
     let view2 = base.slice(1, 7);
-    assert_eq!(view1.null_count(), 1);
-    assert_eq!(view2.null_count(), 2);
+    assert_eq!(view1.unset_bits(), 1);
+    assert_eq!(view2.unset_bits(), 2);
 
     let view3 = view2.slice(0, 1);
-    assert_eq!(view3.null_count(), 0);
+    assert_eq!(view3.unset_bits(), 0);
 }
diff --git a/tests/it/bitmap/mutable.rs b/tests/it/bitmap/mutable.rs
index f228c323b7..ccd4fc83d8 100644
--- a/tests/it/bitmap/mutable.rs
+++ b/tests/it/bitmap/mutable.rs
@@ -11,14 +11,14 @@ fn from_slice() {
 fn from_len_zeroed() {
     let a = MutableBitmap::from_len_zeroed(10);
     assert_eq!(a.len(), 10);
-    assert_eq!(a.null_count(), 10);
+    assert_eq!(a.unset_bits(), 10);
 }
 
 #[test]
 fn from_len_set() {
     let a = MutableBitmap::from_len_set(10);
     assert_eq!(a.len(), 10);
-    assert_eq!(a.null_count(), 0);
+    assert_eq!(a.unset_bits(), 0);
 }
 
 #[test]
diff --git a/tests/it/bitmap/utils/mod.rs b/tests/it/bitmap/utils/mod.rs
index 1ebce6f7f8..9b138d82eb 100644
--- a/tests/it/bitmap/utils/mod.rs
+++ b/tests/it/bitmap/utils/mod.rs
@@ -79,6 +79,6 @@ proptest! {
     #[cfg_attr(miri, ignore)] // miri and proptest do not work well :(
     fn null_count(bitmap in bitmap_strategy()) {
         let sum_of_sets: usize = (0..bitmap.len()).map(|x| (!bitmap.get_bit(x)) as usize).sum();
-        assert_eq!(bitmap.null_count(), sum_of_sets);
+        assert_eq!(bitmap.unset_bits(), sum_of_sets);
     }
 }
diff --git a/tests/it/bitmap/utils/slice_iterator.rs b/tests/it/bitmap/utils/slice_iterator.rs
index f9d9e409ce..d34b99d09b 100644
--- a/tests/it/bitmap/utils/slice_iterator.rs
+++ b/tests/it/bitmap/utils/slice_iterator.rs
@@ -17,7 +17,7 @@ proptest! {
 
         let slots = iter.slots();
 
-        assert_eq!(bitmap.len() - bitmap.null_count(), slots);
+        assert_eq!(bitmap.len() - bitmap.unset_bits(), slots);
 
         let slices = iter.collect::<Vec<_>>();
         let mut sum = 0;
@@ -110,7 +110,7 @@ fn bla() {
         .collect::<Bitmap>();
     let iter = SlicesIterator::new(&values);
     let count = iter.slots();
-    assert_eq!(values.null_count() + iter.slots(), values.len());
+    assert_eq!(values.unset_bits() + iter.slots(), values.len());
 
     let total = iter.into_iter().fold(0, |acc, x| acc + x.1);
 
@@ -122,7 +122,7 @@ fn past_end_should_not_be_returned() {
     let values = Bitmap::from_u8_slice(&[0b11111010], 3);
     let iter = SlicesIterator::new(&values);
     let count = iter.slots();
-    assert_eq!(values.null_count() + iter.slots(), values.len());
+    assert_eq!(values.unset_bits() + iter.slots(), values.len());
 
     let total = iter.into_iter().fold(0, |acc, x| acc + x.1);