From ed8836fe48d70ec0c8581c5dfa3c4ff03e6a3d9e Mon Sep 17 00:00:00 2001 From: "Jorge C. Leitao" Date: Tue, 2 Nov 2021 20:08:45 +0000 Subject: [PATCH] Revert "Made null_count not cached. (#563)" This reverts commit f435f1f597980b2569907dc99b0bc498fd3f45e0. --- src/bitmap/immutable.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/bitmap/immutable.rs b/src/bitmap/immutable.rs index c530ff93c24..8a98c2caa97 100644 --- a/src/bitmap/immutable.rs +++ b/src/bitmap/immutable.rs @@ -20,6 +20,8 @@ pub struct Bitmap { // both are measured in bits. They are used to bound the bitmap to a region of Bytes. offset: usize, length: usize, + // this is a cache: it must be computed on initialization + null_count: usize, } impl std::fmt::Debug for Bitmap { @@ -66,10 +68,12 @@ impl Bitmap { #[inline] pub(crate) fn from_bytes(bytes: Bytes, length: usize) -> Self { assert!(length <= bytes.len() * 8); + let null_count = count_zeros(&bytes, 0, length); Self { length, offset: 0, bytes: Arc::new(bytes), + null_count, } } @@ -99,7 +103,7 @@ impl Bitmap { /// Returns the number of unset bits on this [`Bitmap`]. #[inline] pub fn null_count(&self) -> usize { - count_zeros(&self.bytes, self.offset, self.length) + self.null_count } /// Slices `self`, offseting by `offset` and truncating up to `length` bits. @@ -117,6 +121,17 @@ impl Bitmap { /// The caller must ensure that `self.offset + offset + length <= self.len()` #[inline] pub unsafe fn slice_unchecked(mut self, offset: usize, length: usize) -> Self { + // count the smallest chunk + if length < self.length / 2 { + // count the null values in the slice + self.null_count = count_zeros(&self.bytes, 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.offset += offset; self.length = length; self