From 595b8fa57f5afd16c054ce7be83506523082e3ed Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Wed, 17 Jun 2026 20:00:39 -0700 Subject: [PATCH 1/2] fix: avoid u32 overflow in statistics for full bitmaps Signed-off-by: Sai Asish Y --- roaring/src/bitmap/statistics.rs | 8 ++++---- roaring/tests/lib.rs | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/roaring/src/bitmap/statistics.rs b/roaring/src/bitmap/statistics.rs index 2869c42f..15672ab4 100644 --- a/roaring/src/bitmap/statistics.rs +++ b/roaring/src/bitmap/statistics.rs @@ -18,9 +18,9 @@ pub struct Statistics { /// Number of bitset containers in the bitmap pub n_bitset_containers: u32, /// Number of values stored in array containers - pub n_values_array_containers: u32, + pub n_values_array_containers: u64, /// Number of values stored in run containers - pub n_values_run_containers: u32, + pub n_values_run_containers: u64, /// Number of values stored in bitset containers pub n_values_bitset_containers: u64, /// Number of bytes used by array containers @@ -77,7 +77,7 @@ impl RoaringBitmap { match store { Store::Array(array) => { cardinality += array.len(); - n_values_array_containers += array.len() as u32; + n_values_array_containers += array.len(); n_bytes_array_containers += (array.capacity() * mem::size_of::()) as u64; n_array_containers += 1; } @@ -89,7 +89,7 @@ impl RoaringBitmap { } Store::Run(runs) => { cardinality += runs.len(); - n_values_run_containers += runs.len() as u32; + n_values_run_containers += runs.len(); n_bytes_run_containers += runs.byte_size() as u64; n_run_containers += 1; } diff --git a/roaring/tests/lib.rs b/roaring/tests/lib.rs index 568de01d..c16e3e67 100644 --- a/roaring/tests/lib.rs +++ b/roaring/tests/lib.rs @@ -150,3 +150,11 @@ fn optimize_run() { // Calling optimize a second time should return false as no changes will be made assert!(!bitmap.optimize()); } + +#[test] +fn statistics_full_run() { + let stats = RoaringBitmap::full().statistics(); + let expected: u64 = 1 << 32; + assert_eq!(stats.cardinality, expected); + assert_eq!(u64::from(stats.n_values_run_containers), expected); +} From ffd45bebf1dec21b8460f023c08257c430d30672 Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Fri, 2 Oct 2026 11:14:19 -0700 Subject: [PATCH 2/2] fix: preserve array statistics field compatibility --- roaring/src/bitmap/statistics.rs | 4 ++-- roaring/tests/lib.rs | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/roaring/src/bitmap/statistics.rs b/roaring/src/bitmap/statistics.rs index 15672ab4..8a0cddfc 100644 --- a/roaring/src/bitmap/statistics.rs +++ b/roaring/src/bitmap/statistics.rs @@ -18,7 +18,7 @@ pub struct Statistics { /// Number of bitset containers in the bitmap pub n_bitset_containers: u32, /// Number of values stored in array containers - pub n_values_array_containers: u64, + pub n_values_array_containers: u32, /// Number of values stored in run containers pub n_values_run_containers: u64, /// Number of values stored in bitset containers @@ -77,7 +77,7 @@ impl RoaringBitmap { match store { Store::Array(array) => { cardinality += array.len(); - n_values_array_containers += array.len(); + n_values_array_containers += array.len() as u32; n_bytes_array_containers += (array.capacity() * mem::size_of::()) as u64; n_array_containers += 1; } diff --git a/roaring/tests/lib.rs b/roaring/tests/lib.rs index c16e3e67..a8b37843 100644 --- a/roaring/tests/lib.rs +++ b/roaring/tests/lib.rs @@ -151,10 +151,19 @@ fn optimize_run() { assert!(!bitmap.optimize()); } +#[test] +fn statistics_array_count_remains_u32() { + let bitmap = RoaringBitmap::from_iter([1, 2, 65_536]); + let stats = bitmap.statistics(); + let count: u32 = stats.n_values_array_containers; + assert_eq!(stats.n_array_containers, 2); + assert_eq!(count, 3); +} + #[test] fn statistics_full_run() { let stats = RoaringBitmap::full().statistics(); let expected: u64 = 1 << 32; assert_eq!(stats.cardinality, expected); - assert_eq!(u64::from(stats.n_values_run_containers), expected); + assert_eq!(stats.n_values_run_containers, expected); }