From 55599177e9809a52d990ee47df911314292580c5 Mon Sep 17 00:00:00 2001 From: "Steffen R. Knollmann" Date: Thu, 17 Feb 2022 09:34:28 +0000 Subject: [PATCH] Fix wrong null_count when slicing a sliced Bitmap When pre-calculating the null_count on a Bitmap we need to start from the correct place in the underlying byte-array (i.e. take into account that we may already be looking at a slice). Currently, when we slice of a small part (so that we enter the first branch of the null_count choice), the null_count assumes that the current offset is 0, but it should not. This adds a test for this situation and fixes the issue. --- src/bitmap/immutable.rs | 2 +- src/bitmap/mod.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/bitmap/immutable.rs b/src/bitmap/immutable.rs index 4037b9f8336..c51a7335e5d 100644 --- a/src/bitmap/immutable.rs +++ b/src/bitmap/immutable.rs @@ -126,7 +126,7 @@ 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, offset, length); + self.null_count = 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; diff --git a/src/bitmap/mod.rs b/src/bitmap/mod.rs index 1ee5c3f3018..703fc1dd407 100644 --- a/src/bitmap/mod.rs +++ b/src/bitmap/mod.rs @@ -9,3 +9,32 @@ mod bitmap_ops; pub use bitmap_ops::*; pub mod utils; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn subslicing_gives_correct_null_count() { + let mut base = MutableBitmap::new(); + base.push(false); + base.push(true); + base.push(true); + base.push(false); + base.push(false); + base.push(true); + base.push(true); + base.push(true); + + let base = Bitmap::from(base); + assert_eq!(base.null_count(), 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); + + let view3 = view2.slice(0, 1); + assert_eq!(view3.null_count(), 0); + } +}