From f2ceac5ee9986200c174218faa36ae50dc6718eb Mon Sep 17 00:00:00 2001 From: Sylvain Laperche Date: Thu, 10 Aug 2023 10:53:54 +0200 Subject: [PATCH 1/4] make RoaringBitmap generic over its values This will allows to easily implement Roaring64, a 64-bit RoaringBitmap using the TwoLevelRoaringBitmap approach, which is up to 11x faster than the RoaringTreemap approach and reuse most of Roaring32 code. Note that RoaringBitmap::full have been removed because it won't scale for Roaring64. Comment out RoaringTreemap for now, will be replaced in the next commit. --- Cargo.toml | 1 - benchmarks/benches/datasets.rs | 6 +- benchmarks/benches/lib.rs | 114 +++--- src/bitmap/mod.rs | 42 --- src/bitmap/util.rs | 93 ----- src/{bitmap => core}/arbitrary.rs | 26 +- src/{bitmap => core}/cmp.rs | 55 +-- src/{bitmap => core}/container.rs | 124 +++--- src/{bitmap => core}/fmt.rs | 7 +- src/{bitmap => core}/inherent.rs | 355 +++++++++--------- src/{bitmap => core}/iter.rs | 109 +++--- src/core/mod.rs | 30 ++ src/{bitmap => core}/multiops.rs | 100 +++-- src/{bitmap => core}/ops.rs | 234 ++++++------ src/{bitmap => core}/proptests.rs | 106 +++--- src/{bitmap => core}/serde.rs | 37 +- src/{bitmap => core}/serialization.rs | 112 +++--- src/{bitmap => core}/store/array_store/mod.rs | 7 +- .../store/array_store/scalar.rs | 2 +- .../store/array_store/vector.rs | 2 +- .../store/array_store/visitor.rs | 2 +- src/{bitmap => core}/store/bitmap_store.rs | 2 +- src/{bitmap => core}/store/mod.rs | 2 +- src/lib.rs | 24 +- src/roaring32.rs | 147 ++++++++ src/value.rs | 54 +++ tests/clone.rs | 19 +- tests/difference_with.rs | 87 ++--- tests/intersect_with.rs | 67 ++-- tests/is_disjoint.rs | 51 ++- tests/is_subset.rs | 51 ++- tests/iter.rs | 61 ++- tests/lib.rs | 27 +- tests/ops.rs | 29 +- tests/push.rs | 23 +- tests/range_checks.rs | 11 +- tests/rank.rs | 18 +- tests/select.rs | 17 +- tests/serialization.rs | 40 +- tests/size_hint.rs | 19 +- tests/symmetric_difference_with.rs | 73 ++-- tests/treemap_clone.rs | 80 ++-- tests/treemap_difference_with.rs | 174 ++++----- tests/treemap_intersect_with.rs | 138 +++---- tests/treemap_is_disjoint.rs | 124 +++--- tests/treemap_is_subset.rs | 138 +++---- tests/treemap_iter.rs | 258 ++++++------- tests/treemap_lib.rs | 214 +++++------ tests/treemap_ops.rs | 156 ++++---- tests/treemap_rank.rs | 108 +++--- tests/treemap_select.rs | 88 ++--- tests/treemap_serialization.rs | 88 ++--- tests/treemap_size_hint.rs | 96 ++--- tests/treemap_symmetric_difference_with.rs | 230 ++++++------ tests/treemap_union_with.rs | 182 ++++----- tests/union_with.rs | 61 ++- 56 files changed, 2271 insertions(+), 2250 deletions(-) delete mode 100644 src/bitmap/mod.rs delete mode 100644 src/bitmap/util.rs rename src/{bitmap => core}/arbitrary.rs (91%) rename src/{bitmap => core}/cmp.rs (74%) rename src/{bitmap => core}/container.rs (69%) rename src/{bitmap => core}/fmt.rs (81%) rename src/{bitmap => core}/inherent.rs (71%) rename src/{bitmap => core}/iter.rs (68%) create mode 100644 src/core/mod.rs rename src/{bitmap => core}/multiops.rs (83%) rename src/{bitmap => core}/ops.rs (72%) rename src/{bitmap => core}/proptests.rs (90%) rename src/{bitmap => core}/serde.rs (72%) rename src/{bitmap => core}/serialization.rs (73%) rename src/{bitmap => core}/store/array_store/mod.rs (99%) rename src/{bitmap => core}/store/array_store/scalar.rs (97%) rename src/{bitmap => core}/store/array_store/vector.rs (99%) rename src/{bitmap => core}/store/array_store/visitor.rs (97%) rename src/{bitmap => core}/store/bitmap_store.rs (99%) rename src/{bitmap => core}/store/mod.rs (99%) create mode 100644 src/roaring32.rs create mode 100644 src/value.rs diff --git a/Cargo.toml b/Cargo.toml index 232ba0558..90fa6a874 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,6 @@ license = "MIT OR Apache-2.0" [dependencies] bytemuck = "1.7.3" byteorder = "1.4.3" -retain_mut = "=0.1.7" serde = { version = "1.0.139", optional = true } [features] diff --git a/benchmarks/benches/datasets.rs b/benchmarks/benches/datasets.rs index afd2288e4..89deedd95 100644 --- a/benchmarks/benches/datasets.rs +++ b/benchmarks/benches/datasets.rs @@ -6,7 +6,7 @@ use std::path::{Path, PathBuf}; use git2::FetchOptions; use once_cell::sync::OnceCell as SyncOnceCell; -use roaring::RoaringBitmap; +use roaring::Roaring32; static INSTANCE: SyncOnceCell> = SyncOnceCell::new(); @@ -41,7 +41,7 @@ impl IntoIterator for Datasets { pub struct Dataset { pub name: String, - pub bitmaps: Vec, + pub bitmaps: Vec, } fn init_datasets() -> Result> { @@ -186,7 +186,7 @@ fn parse_datasets>(path: P) -> Result, Box RoaringBitmap, - op_own_ref: impl Fn(RoaringBitmap, &RoaringBitmap) -> RoaringBitmap, - op_ref_own: impl Fn(&RoaringBitmap, RoaringBitmap) -> RoaringBitmap, - op_ref_ref: impl Fn(&RoaringBitmap, &RoaringBitmap) -> RoaringBitmap, - mut op_assign_owned: impl FnMut(&mut RoaringBitmap, RoaringBitmap), - mut op_assign_ref: impl FnMut(&mut RoaringBitmap, &RoaringBitmap), - op_len: impl Fn(&RoaringBitmap, &RoaringBitmap) -> u64, + op_own_own: impl Fn(Roaring32, Roaring32) -> Roaring32, + op_own_ref: impl Fn(Roaring32, &Roaring32) -> Roaring32, + op_ref_own: impl Fn(&Roaring32, Roaring32) -> Roaring32, + op_ref_ref: impl Fn(&Roaring32, &Roaring32) -> Roaring32, + mut op_assign_owned: impl FnMut(&mut Roaring32, Roaring32), + mut op_assign_ref: impl FnMut(&mut Roaring32, &Roaring32), + op_len: impl Fn(&Roaring32, &Roaring32) -> u64, ) { let mut group = c.benchmark_group(format!("pairwise_{}", op_name)); @@ -120,7 +120,7 @@ fn pairwise_binary_op_matrix( fn pairwise_binary_op( group: &mut BenchmarkGroup, op_name: &str, - op: impl Fn(RoaringBitmap, RoaringBitmap) -> R, + op: impl Fn(Roaring32, Roaring32) -> R, ) { for dataset in Datasets { group.bench_function(BenchmarkId::new(op_name, &dataset.name), |b| { @@ -152,9 +152,7 @@ fn creation(c: &mut Criterion) { group.bench_function(BenchmarkId::new("from_sorted_iter", &dataset.name), |b| { b.iter(|| { for bitmap_numbers in &dataset_numbers { - black_box( - RoaringBitmap::from_sorted_iter(bitmap_numbers.iter().copied()).unwrap(), - ); + black_box(Roaring32::from_sorted_iter(bitmap_numbers.iter().copied()).unwrap()); } }) }); @@ -162,7 +160,7 @@ fn creation(c: &mut Criterion) { group.bench_function(BenchmarkId::new("collect", &dataset.name), |b| { b.iter(|| { for bitmap_numbers in &dataset_numbers { - black_box(bitmap_numbers.iter().copied().collect::()); + black_box(bitmap_numbers.iter().copied().collect::()); } }) }); @@ -408,7 +406,7 @@ fn deserialization(c: &mut Criterion) { group.bench_function(BenchmarkId::new("deserialize_from", &dataset.name), |b| { b.iter(|| { for buf in input.iter() { - black_box(RoaringBitmap::deserialize_from(buf.as_slice()).unwrap()); + black_box(Roaring32::deserialize_from(buf.as_slice()).unwrap()); } }); }); @@ -416,7 +414,7 @@ fn deserialization(c: &mut Criterion) { group.bench_function(BenchmarkId::new("deserialize_unchecked_from", &dataset.name), |b| { b.iter(|| { for buf in input.iter() { - black_box(RoaringBitmap::deserialize_unchecked_from(buf.as_slice()).unwrap()); + black_box(Roaring32::deserialize_unchecked_from(buf.as_slice()).unwrap()); } }); }); @@ -476,7 +474,7 @@ fn successive_and(c: &mut Criterion) { group.bench_function(BenchmarkId::new("Multi And Owned", &dataset.name), |b| { b.iter_batched( || dataset.bitmaps.clone(), - |bitmaps: Vec| black_box(bitmaps.intersection()), + |bitmaps: Vec| black_box(bitmaps.intersection()), BatchSize::LargeInput, ); }); @@ -491,7 +489,7 @@ fn successive_or(c: &mut Criterion) { for dataset in Datasets { group.bench_function(BenchmarkId::new("Successive Or Assign Ref", &dataset.name), |b| { b.iter(|| { - let mut output = RoaringBitmap::new(); + let mut output = Roaring32::new(); for bitmap in &dataset.bitmaps { output |= bitmap; } @@ -501,8 +499,8 @@ fn successive_or(c: &mut Criterion) { group.bench_function(BenchmarkId::new("Successive Or Assign Owned", &dataset.name), |b| { b.iter_batched( || dataset.bitmaps.clone(), - |bitmaps: Vec| { - let mut output = RoaringBitmap::new(); + |bitmaps: Vec| { + let mut output = Roaring32::new(); for bitmap in bitmaps { output |= bitmap; } @@ -513,7 +511,7 @@ fn successive_or(c: &mut Criterion) { group.bench_function(BenchmarkId::new("Successive Or Ref Ref", &dataset.name), |b| { b.iter(|| { - let mut output = RoaringBitmap::new(); + let mut output = Roaring32::new(); for bitmap in &dataset.bitmaps { output = (&output) | bitmap; } @@ -527,7 +525,7 @@ fn successive_or(c: &mut Criterion) { group.bench_function(BenchmarkId::new("Multi Or Owned", &dataset.name), |b| { b.iter_batched( || dataset.bitmaps.clone(), - |bitmaps: Vec| black_box(bitmaps.union()), + |bitmaps: Vec| black_box(bitmaps.union()), BatchSize::LargeInput, ); }); @@ -541,13 +539,13 @@ fn successive_or(c: &mut Criterion) { fn is_empty(c: &mut Criterion) { c.bench_function("is_empty true", |b| { - let bitmap = RoaringBitmap::new(); + let bitmap = Roaring32::new(); b.iter(|| { bitmap.is_empty(); }); }); c.bench_function("is_empty false", |b| { - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); bitmap.insert(1); b.iter(|| { bitmap.is_empty(); @@ -558,13 +556,13 @@ fn is_empty(c: &mut Criterion) { fn insert(c: &mut Criterion) { c.bench_function("create & insert 1", |b| { b.iter(|| { - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); bitmap.insert(black_box(1)); }); }); c.bench_function("insert 1", |b| { - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); b.iter(|| { bitmap.insert(black_box(1)); }); @@ -572,7 +570,7 @@ fn insert(c: &mut Criterion) { c.bench_function("create & insert several", |b| { b.iter(|| { - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); bitmap.insert(black_box(1)); bitmap.insert(black_box(10)); bitmap.insert(black_box(100)); @@ -584,7 +582,7 @@ fn insert(c: &mut Criterion) { }); c.bench_function("insert several", |b| { - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); b.iter(|| { bitmap.insert(black_box(1)); bitmap.insert(black_box(10)); @@ -599,7 +597,7 @@ fn insert(c: &mut Criterion) { fn contains(c: &mut Criterion) { c.bench_function("contains true", |b| { - let mut bitmap: RoaringBitmap = RoaringBitmap::new(); + let mut bitmap: Roaring32 = Roaring32::new(); bitmap.insert(1); b.iter(|| { @@ -608,7 +606,7 @@ fn contains(c: &mut Criterion) { }); c.bench_function("contains false", |b| { - let bitmap: RoaringBitmap = RoaringBitmap::new(); + let bitmap: Roaring32 = Roaring32::new(); b.iter(|| { bitmap.contains(black_box(1)); @@ -618,7 +616,7 @@ fn contains(c: &mut Criterion) { fn remove(c: &mut Criterion) { c.bench_function("remove 1", |b| { - let mut sub: RoaringBitmap = (0..65_536).collect(); + let mut sub: Roaring32 = (0..65_536).collect(); b.iter(|| { black_box(sub.remove(1000)); }); @@ -627,7 +625,7 @@ fn remove(c: &mut Criterion) { fn remove_range_bitmap(c: &mut Criterion) { c.bench_function("remove_range 1", |b| { - let mut sub: RoaringBitmap = (0..65_536).collect(); + let mut sub: Roaring32 = (0..65_536).collect(); b.iter(|| { // carefully delete part of the bitmap // only the first iteration will actually change something @@ -641,7 +639,7 @@ fn remove_range_bitmap(c: &mut Criterion) { // Slower bench that creates a new bitmap on each iteration so that can benchmark // bitmap to array conversion b.iter(|| { - let mut sub: RoaringBitmap = (0..65_536).collect(); + let mut sub: Roaring32 = (0..65_536).collect(); black_box(sub.remove_range(100..65_536)); assert_eq!(sub.len(), 100); }); @@ -653,7 +651,7 @@ fn insert_range_bitmap(c: &mut Criterion) { let mut group = c.benchmark_group("insert_range"); group.throughput(criterion::Throughput::Elements(size as u64)); group.bench_function(format!("from_empty_{}", size), |b| { - let bm = RoaringBitmap::new(); + let bm = Roaring32::new(); b.iter_batched( || bm.clone(), |mut bm| black_box(bm.insert_range(0..size)), @@ -661,7 +659,7 @@ fn insert_range_bitmap(c: &mut Criterion) { ) }); group.bench_function(format!("pre_populated_{}", size), |b| { - let mut bm = RoaringBitmap::new(); + let mut bm = Roaring32::new(); bm.insert_range(0..size); b.iter_batched( || bm.clone(), @@ -672,29 +670,29 @@ fn insert_range_bitmap(c: &mut Criterion) { } } -fn insert_range_treemap(c: &mut Criterion) { - for &size in &[1_000_u64, 10_000u64, 2 * (u32::MAX as u64)] { - let mut group = c.benchmark_group("insert_range_treemap"); - group.throughput(criterion::Throughput::Elements(size)); - group.bench_function(format!("from_empty_{}", size), |b| { - let bm = RoaringTreemap::new(); - b.iter_batched( - || bm.clone(), - |mut bm| black_box(bm.insert_range(0..size)), - criterion::BatchSize::SmallInput, - ) - }); - group.bench_function(format!("pre_populated_{}", size), |b| { - let mut bm = RoaringTreemap::new(); - bm.insert_range(0..size); - b.iter_batched( - || bm.clone(), - |mut bm| black_box(bm.insert_range(0..size)), - criterion::BatchSize::SmallInput, - ) - }); - } -} +// fn insert_range_treemap(c: &mut Criterion) { +// for &size in &[1_000_u64, 10_000u64, 2 * (u32::MAX as u64)] { +// let mut group = c.benchmark_group("insert_range_treemap"); +// group.throughput(criterion::Throughput::Elements(size)); +// group.bench_function(format!("from_empty_{}", size), |b| { +// let bm = RoaringTreemap::new(); +// b.iter_batched( +// || bm.clone(), +// |mut bm| black_box(bm.insert_range(0..size)), +// criterion::BatchSize::SmallInput, +// ) +// }); +// group.bench_function(format!("pre_populated_{}", size), |b| { +// let mut bm = RoaringTreemap::new(); +// bm.insert_range(0..size); +// b.iter_batched( +// || bm.clone(), +// |mut bm| black_box(bm.insert_range(0..size)), +// criterion::BatchSize::SmallInput, +// ) +// }); +// } +// } criterion_group!( benches, @@ -713,7 +711,7 @@ criterion_group!( remove, remove_range_bitmap, insert_range_bitmap, - insert_range_treemap, + // insert_range_treemap, iteration, is_empty, serialization, diff --git a/src/bitmap/mod.rs b/src/bitmap/mod.rs deleted file mode 100644 index 9b34bdcd3..000000000 --- a/src/bitmap/mod.rs +++ /dev/null @@ -1,42 +0,0 @@ -mod arbitrary; -mod container; -mod fmt; -mod multiops; -mod proptests; -mod store; -mod util; - -// Order of these modules matters as it determines the `impl` blocks order in -// the docs -mod cmp; -mod inherent; -mod iter; -mod ops; -#[cfg(feature = "serde")] -mod serde; -mod serialization; - -use self::cmp::Pairs; -pub use self::iter::IntoIter; -pub use self::iter::Iter; - -/// A compressed bitmap using the [Roaring bitmap compression scheme](https://roaringbitmap.org/). -/// -/// # Examples -/// -/// ```rust -/// use roaring::RoaringBitmap; -/// -/// let mut rb = RoaringBitmap::new(); -/// -/// // insert all primes less than 10 -/// rb.insert(2); -/// rb.insert(3); -/// rb.insert(5); -/// rb.insert(7); -/// println!("total bits set to true: {}", rb.len()); -/// ``` -#[derive(PartialEq)] -pub struct RoaringBitmap { - containers: Vec, -} diff --git a/src/bitmap/util.rs b/src/bitmap/util.rs deleted file mode 100644 index d6fc7db69..000000000 --- a/src/bitmap/util.rs +++ /dev/null @@ -1,93 +0,0 @@ -use std::ops::{Bound, RangeBounds, RangeInclusive}; - -/// Returns the container key and the index -/// in this container for a given integer. -#[inline] -pub fn split(value: u32) -> (u16, u16) { - ((value >> 16) as u16, value as u16) -} - -/// Returns the original integer from the container -/// key and the index of it in the container. -#[inline] -pub fn join(high: u16, low: u16) -> u32 { - (u32::from(high) << 16) + u32::from(low) -} - -/// Convert a `RangeBounds` object to `RangeInclusive`, -pub fn convert_range_to_inclusive(range: R) -> Option> -where - R: RangeBounds, -{ - let start: u32 = match range.start_bound() { - Bound::Included(&i) => i, - Bound::Excluded(&i) => i.checked_add(1)?, - Bound::Unbounded => 0, - }; - let end: u32 = match range.end_bound() { - Bound::Included(&i) => i, - Bound::Excluded(&i) => i.checked_sub(1)?, - Bound::Unbounded => u32::MAX, - }; - if end < start { - return None; - } - Some(start..=end) -} - -#[cfg(test)] -mod test { - use super::{convert_range_to_inclusive, join, split}; - use std::ops::Bound; - - #[test] - fn test_split_u32() { - assert_eq!((0x0000u16, 0x0000u16), split(0x0000_0000u32)); - assert_eq!((0x0000u16, 0x0001u16), split(0x0000_0001u32)); - assert_eq!((0x0000u16, 0xFFFEu16), split(0x0000_FFFEu32)); - assert_eq!((0x0000u16, 0xFFFFu16), split(0x0000_FFFFu32)); - assert_eq!((0x0001u16, 0x0000u16), split(0x0001_0000u32)); - assert_eq!((0x0001u16, 0x0001u16), split(0x0001_0001u32)); - assert_eq!((0xFFFFu16, 0xFFFEu16), split(0xFFFF_FFFEu32)); - assert_eq!((0xFFFFu16, 0xFFFFu16), split(0xFFFF_FFFFu32)); - } - - #[test] - fn test_join_u32() { - assert_eq!(0x0000_0000u32, join(0x0000u16, 0x0000u16)); - assert_eq!(0x0000_0001u32, join(0x0000u16, 0x0001u16)); - assert_eq!(0x0000_FFFEu32, join(0x0000u16, 0xFFFEu16)); - assert_eq!(0x0000_FFFFu32, join(0x0000u16, 0xFFFFu16)); - assert_eq!(0x0001_0000u32, join(0x0001u16, 0x0000u16)); - assert_eq!(0x0001_0001u32, join(0x0001u16, 0x0001u16)); - assert_eq!(0xFFFF_FFFEu32, join(0xFFFFu16, 0xFFFEu16)); - assert_eq!(0xFFFF_FFFFu32, join(0xFFFFu16, 0xFFFFu16)); - } - - #[test] - #[allow(clippy::reversed_empty_ranges)] - fn test_convert_range_to_inclusive() { - assert_eq!(Some(1..=5), convert_range_to_inclusive(1..6)); - assert_eq!(Some(1..=u32::MAX), convert_range_to_inclusive(1..)); - assert_eq!(Some(0..=u32::MAX), convert_range_to_inclusive(..)); - assert_eq!(Some(16..=16), convert_range_to_inclusive(16..=16)); - assert_eq!( - Some(11..=19), - convert_range_to_inclusive((Bound::Excluded(10), Bound::Excluded(20))) - ); - - assert_eq!(None, convert_range_to_inclusive(0..0)); - assert_eq!(None, convert_range_to_inclusive(5..5)); - assert_eq!(None, convert_range_to_inclusive(1..0)); - assert_eq!(None, convert_range_to_inclusive(10..5)); - assert_eq!( - None, - convert_range_to_inclusive((Bound::Excluded(u32::MAX), Bound::Included(u32::MAX))) - ); - assert_eq!( - None, - convert_range_to_inclusive((Bound::Excluded(u32::MAX), Bound::Included(u32::MAX))) - ); - assert_eq!(None, convert_range_to_inclusive((Bound::Excluded(0), Bound::Included(0)))); - } -} diff --git a/src/bitmap/arbitrary.rs b/src/core/arbitrary.rs similarity index 91% rename from src/bitmap/arbitrary.rs rename to src/core/arbitrary.rs index f1dda728c..ea1de8d18 100644 --- a/src/bitmap/arbitrary.rs +++ b/src/core/arbitrary.rs @@ -1,11 +1,17 @@ #[cfg(test)] mod test { - use crate::bitmap::container::Container; - use crate::bitmap::store::{ArrayStore, BitmapStore, Store}; - use crate::RoaringBitmap; - use proptest::bits::{BitSetLike, BitSetStrategy, SampledBitSetStrategy}; - use proptest::collection::{vec, SizeRange}; - use proptest::prelude::*; + use crate::{ + core::{ + container::Container, + store::{ArrayStore, BitmapStore, Store}, + }, + RoaringBitmap, Value, + }; + use proptest::{ + bits::{BitSetLike, BitSetStrategy, SampledBitSetStrategy}, + collection::{vec, SizeRange}, + prelude::*, + }; use std::fmt::{Debug, Formatter}; impl Debug for BitmapStore { @@ -172,19 +178,19 @@ mod test { prop_compose! { fn containers(n: usize) (keys in ArrayStore::sampled(..=n, ..=n), - stores in vec(Store::arbitrary(), n)) -> RoaringBitmap { + stores in vec(Store::arbitrary(), n)) -> RoaringBitmap { let containers = keys.into_iter().zip(stores).map(|(key, store)| { let mut container = Container { key, store }; container.ensure_correct_store(); container - }).collect::>(); + }).collect::>>(); RoaringBitmap { containers } } } - impl RoaringBitmap { + impl RoaringBitmap { prop_compose! { - pub fn arbitrary()(bitmap in (0usize..=16).prop_flat_map(containers)) -> RoaringBitmap { + pub fn arbitrary()(bitmap in (0usize..=16).prop_flat_map(containers)) -> RoaringBitmap { bitmap } } diff --git a/src/bitmap/cmp.rs b/src/core/cmp.rs similarity index 74% rename from src/bitmap/cmp.rs rename to src/core/cmp.rs index ad4a7d0a1..1af730521 100644 --- a/src/bitmap/cmp.rs +++ b/src/core/cmp.rs @@ -1,21 +1,18 @@ -use std::borrow::Borrow; -use std::cmp::Ordering; -use std::iter::Peekable; - use super::container::Container; -use crate::RoaringBitmap; +use crate::{RoaringBitmap, Value}; +use std::{borrow::Borrow, cmp::Ordering, iter::Peekable, marker::PhantomData}; -impl RoaringBitmap { +impl RoaringBitmap { /// Returns true if the set has no elements in common with other. This is equivalent to /// checking for an empty intersection. /// /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb1 = RoaringBitmap::new(); - /// let mut rb2 = RoaringBitmap::new(); + /// let mut rb1 = Roaring32::new(); + /// let mut rb2 = Roaring32::new(); /// /// rb1.insert(1); /// @@ -37,10 +34,10 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb1 = RoaringBitmap::new(); - /// let mut rb2 = RoaringBitmap::new(); + /// let mut rb1 = Roaring32::new(); + /// let mut rb2 = Roaring32::new(); /// /// rb1.insert(1); /// @@ -74,10 +71,10 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb1 = RoaringBitmap::new(); - /// let mut rb2 = RoaringBitmap::new(); + /// let mut rb1 = Roaring32::new(); + /// let mut rb2 = Roaring32::new(); /// /// rb1.insert(1); /// @@ -101,39 +98,45 @@ impl RoaringBitmap { /// Returns the smallest container according to its key /// or both if the key is the same. It is useful when you need /// to iterate over two containers to do operations on them. -pub struct Pairs +pub struct Pairs where + V: Value, I: Iterator, J: Iterator, - L: Borrow, - R: Borrow, + L: Borrow>, + R: Borrow>, { left: Peekable, right: Peekable, + value_type: PhantomData, } -impl Pairs +impl Pairs where I: Iterator, J: Iterator, - L: Borrow, - R: Borrow, + L: Borrow>, + R: Borrow>, { - pub fn new(left: A, right: B) -> Pairs + pub fn new(left: A, right: B) -> Pairs where A: IntoIterator, B: IntoIterator, { - Pairs { left: left.into_iter().peekable(), right: right.into_iter().peekable() } + Pairs { + left: left.into_iter().peekable(), + right: right.into_iter().peekable(), + value_type: PhantomData, + } } } -impl Iterator for Pairs +impl Iterator for Pairs where I: Iterator, J: Iterator, - L: Borrow, - R: Borrow, + L: Borrow>, + R: Borrow>, { type Item = (Option, Option); diff --git a/src/bitmap/container.rs b/src/core/container.rs similarity index 69% rename from src/bitmap/container.rs rename to src/core/container.rs index 773f90993..97c6dbd27 100644 --- a/src/bitmap/container.rs +++ b/src/core/container.rs @@ -1,35 +1,35 @@ -use std::fmt; -use std::ops::{ - BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, RangeInclusive, Sub, SubAssign, -}; - use super::store::{self, Store}; -use super::util; +use crate::Value; +use std::{ + fmt, + ops::{ + BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, RangeInclusive, Sub, + SubAssign, + }, +}; pub const ARRAY_LIMIT: u64 = 4096; #[derive(PartialEq, Clone)] -pub struct Container { - pub key: u16, +pub struct Container { + pub key: V::Key, pub store: Store, } -pub struct Iter<'a> { - pub key: u16, +pub struct Iter<'a, V: Value> { + pub key: V::Key, inner: store::Iter<'a>, } -impl Container { - pub fn new(key: u16) -> Container { - Container { key, store: Store::new() } +impl Container { + pub fn new(key: V::Key) -> Self { + Self { key, store: Store::new() } } - pub fn full(key: u16) -> Container { - Container { key, store: Store::full() } + pub fn full(key: V::Key) -> Self { + Self { key, store: Store::full() } } -} -impl Container { pub fn len(&self) -> u64 { self.store.len() } @@ -176,132 +176,132 @@ impl Container { } } -impl BitOr<&Container> for &Container { - type Output = Container; +impl BitOr<&Container> for &Container { + type Output = Container; - fn bitor(self, rhs: &Container) -> Container { + fn bitor(self, rhs: &Container) -> Self::Output { let store = BitOr::bitor(&self.store, &rhs.store); - let mut container = Container { key: self.key, store }; + let mut container = Self::Output { key: self.key, store }; container.ensure_correct_store(); container } } -impl BitOrAssign for Container { - fn bitor_assign(&mut self, rhs: Container) { +impl BitOrAssign> for Container { + fn bitor_assign(&mut self, rhs: Container) { BitOrAssign::bitor_assign(&mut self.store, rhs.store); self.ensure_correct_store(); } } -impl BitOrAssign<&Container> for Container { - fn bitor_assign(&mut self, rhs: &Container) { +impl BitOrAssign<&Container> for Container { + fn bitor_assign(&mut self, rhs: &Container) { BitOrAssign::bitor_assign(&mut self.store, &rhs.store); self.ensure_correct_store(); } } -impl BitAnd<&Container> for &Container { - type Output = Container; +impl BitAnd<&Container> for &Container { + type Output = Container; - fn bitand(self, rhs: &Container) -> Container { + fn bitand(self, rhs: &Container) -> Self::Output { let store = BitAnd::bitand(&self.store, &rhs.store); - let mut container = Container { key: self.key, store }; + let mut container = Self::Output { key: self.key, store }; container.ensure_correct_store(); container } } -impl BitAndAssign for Container { - fn bitand_assign(&mut self, rhs: Container) { +impl BitAndAssign> for Container { + fn bitand_assign(&mut self, rhs: Container) { BitAndAssign::bitand_assign(&mut self.store, rhs.store); self.ensure_correct_store(); } } -impl BitAndAssign<&Container> for Container { - fn bitand_assign(&mut self, rhs: &Container) { +impl BitAndAssign<&Container> for Container { + fn bitand_assign(&mut self, rhs: &Container) { BitAndAssign::bitand_assign(&mut self.store, &rhs.store); self.ensure_correct_store(); } } -impl Sub<&Container> for &Container { - type Output = Container; +impl Sub<&Container> for &Container { + type Output = Container; - fn sub(self, rhs: &Container) -> Container { + fn sub(self, rhs: &Container) -> Self::Output { let store = Sub::sub(&self.store, &rhs.store); - let mut container = Container { key: self.key, store }; + let mut container = Self::Output { key: self.key, store }; container.ensure_correct_store(); container } } -impl SubAssign<&Container> for Container { - fn sub_assign(&mut self, rhs: &Container) { +impl SubAssign<&Container> for Container { + fn sub_assign(&mut self, rhs: &Container) { SubAssign::sub_assign(&mut self.store, &rhs.store); self.ensure_correct_store(); } } -impl BitXor<&Container> for &Container { - type Output = Container; +impl BitXor<&Container> for &Container { + type Output = Container; - fn bitxor(self, rhs: &Container) -> Container { + fn bitxor(self, rhs: &Container) -> Self::Output { let store = BitXor::bitxor(&self.store, &rhs.store); - let mut container = Container { key: self.key, store }; + let mut container = Self::Output { key: self.key, store }; container.ensure_correct_store(); container } } -impl BitXorAssign for Container { - fn bitxor_assign(&mut self, rhs: Container) { +impl BitXorAssign> for Container { + fn bitxor_assign(&mut self, rhs: Container) { BitXorAssign::bitxor_assign(&mut self.store, rhs.store); self.ensure_correct_store(); } } -impl BitXorAssign<&Container> for Container { - fn bitxor_assign(&mut self, rhs: &Container) { +impl BitXorAssign<&Container> for Container { + fn bitxor_assign(&mut self, rhs: &Container) { BitXorAssign::bitxor_assign(&mut self.store, &rhs.store); self.ensure_correct_store(); } } -impl<'a> IntoIterator for &'a Container { - type Item = u32; - type IntoIter = Iter<'a>; +impl<'a, V: Value> IntoIterator for &'a Container { + type Item = V; + type IntoIter = Iter<'a, V>; - fn into_iter(self) -> Iter<'a> { + fn into_iter(self) -> Iter<'a, V> { let store: &Store = &self.store; Iter { key: self.key, inner: store.into_iter() } } } -impl IntoIterator for Container { - type Item = u32; - type IntoIter = Iter<'static>; +impl IntoIterator for Container { + type Item = V; + type IntoIter = Iter<'static, V>; - fn into_iter(self) -> Iter<'static> { + fn into_iter(self) -> Iter<'static, V> { Iter { key: self.key, inner: self.store.into_iter() } } } -impl<'a> Iterator for Iter<'a> { - type Item = u32; - fn next(&mut self) -> Option { - self.inner.next().map(|i| util::join(self.key, i)) +impl<'a, V: Value> Iterator for Iter<'a, V> { + type Item = V; + fn next(&mut self) -> Option { + self.inner.next().map(|i| V::join(self.key, i)) } } -impl DoubleEndedIterator for Iter<'_> { +impl DoubleEndedIterator for Iter<'_, V> { fn next_back(&mut self) -> Option { - self.inner.next_back().map(|i| util::join(self.key, i)) + self.inner.next_back().map(|i| V::join(self.key, i)) } } -impl fmt::Debug for Container { +impl fmt::Debug for Container { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { format!("Container<{:?} @ {:?}>", self.len(), self.key).fmt(formatter) } diff --git a/src/bitmap/fmt.rs b/src/core/fmt.rs similarity index 81% rename from src/bitmap/fmt.rs rename to src/core/fmt.rs index 7dca81705..3ee2040f6 100644 --- a/src/bitmap/fmt.rs +++ b/src/core/fmt.rs @@ -1,11 +1,10 @@ +use crate::{RoaringBitmap, Value}; use std::fmt; -use crate::RoaringBitmap; - -impl fmt::Debug for RoaringBitmap { +impl fmt::Debug for RoaringBitmap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.len() < 16 { - write!(f, "RoaringBitmap<{:?}>", self.iter().collect::>()) + write!(f, "RoaringBitmap<{:?}>", self.iter().collect::>()) } else { write!( f, diff --git a/src/bitmap/inherent.rs b/src/core/inherent.rs similarity index 71% rename from src/bitmap/inherent.rs rename to src/core/inherent.rs index 540ef0d3e..8bf8dfffd 100644 --- a/src/bitmap/inherent.rs +++ b/src/core/inherent.rs @@ -1,34 +1,18 @@ -use std::cmp::Ordering; -use std::ops::RangeBounds; - -use crate::RoaringBitmap; - use super::container::Container; -use super::util; +use crate::{RoaringBitmap, Value, ValueRange}; +use std::{cmp::Ordering, ops::RangeBounds}; -impl RoaringBitmap { +impl RoaringBitmap { /// Creates an empty `RoaringBitmap`. /// /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; - /// let rb = RoaringBitmap::new(); - /// ``` - pub fn new() -> RoaringBitmap { - RoaringBitmap { containers: Vec::new() } - } - - /// Creates a full `RoaringBitmap`. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringBitmap; - /// let rb = RoaringBitmap::full(); + /// use roaring::Roaring32; + /// let rb = Roaring32::new(); /// ``` - pub fn full() -> RoaringBitmap { - RoaringBitmap { containers: (0..=u16::MAX).map(Container::full).collect() } + pub fn new() -> Self { + Self { containers: Vec::new() } } /// Adds a value to the set. @@ -38,15 +22,15 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// assert_eq!(rb.insert(3), true); /// assert_eq!(rb.insert(3), false); /// assert_eq!(rb.contains(3), true); /// ``` - pub fn insert(&mut self, value: u32) -> bool { - let (key, index) = util::split(value); + pub fn insert(&mut self, value: V) -> bool { + let (key, index) = value.split(); let container = match self.containers.binary_search_by_key(&key, |c| c.key) { Ok(loc) => &mut self.containers[loc], Err(loc) => { @@ -61,7 +45,7 @@ impl RoaringBitmap { /// Create a new container if not exist. /// /// Return the index of the target container. - fn find_container_by_key(&mut self, key: u16) -> usize { + fn find_container_by_key(&mut self, key: V::Key) -> usize { match self.containers.binary_search_by_key(&key, |c| c.key) { Ok(loc) => loc, Err(loc) => { @@ -77,25 +61,21 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// rb.insert_range(2..4); /// assert!(rb.contains(2)); /// assert!(rb.contains(3)); /// assert!(!rb.contains(4)); /// ``` - pub fn insert_range(&mut self, range: R) -> u64 - where - R: RangeBounds, - { - let (start, end) = match util::convert_range_to_inclusive(range) { - Some(range) => (*range.start(), *range.end()), - None => return 0, + pub fn insert_range(&mut self, range: impl RangeBounds) -> u64 { + let Some(range) = V::range(range) else { + return 0; }; - let (start_container_key, start_index) = util::split(start); - let (end_container_key, end_index) = util::split(end); + let (start_container_key, start_index) = range.start(); + let (end_container_key, end_index) = range.end(); // Find the container index for start_container_key let first_index = self.find_container_by_key(start_container_key); @@ -114,8 +94,10 @@ impl RoaringBitmap { let mut low = start_index; let mut inserted = 0; - for i in start_container_key..end_container_key { - let index = self.find_container_by_key(i); + let count = range.containers_count(); + assert!(count > 1, "non-empty range"); + for key in range.keys().take(count - 1) { + let index = self.find_container_by_key(key); // Insert the range subset for this container inserted += self.containers[index].insert_range(low..=u16::MAX); @@ -126,7 +108,6 @@ impl RoaringBitmap { // Handle the last container let last_index = self.find_container_by_key(end_container_key); - inserted += self.containers[last_index].insert_range(0..=end_index); inserted @@ -139,9 +120,9 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// assert!(rb.push(1)); /// assert!(rb.push(3)); /// assert_eq!(rb.push(3), false); @@ -149,8 +130,8 @@ impl RoaringBitmap { /// /// assert_eq!(rb.iter().collect::>(), vec![1, 3, 5]); /// ``` - pub fn push(&mut self, value: u32) -> bool { - let (key, index) = util::split(value); + pub fn push(&mut self, value: V) -> bool { + let (key, index) = value.split(); match self.containers.last_mut() { Some(container) if container.key == key => container.push(index), @@ -171,8 +152,8 @@ impl RoaringBitmap { /// # Panics /// /// If debug_assertions enabled and index is > self.max() - pub(crate) fn push_unchecked(&mut self, value: u32) { - let (key, index) = util::split(value); + pub(crate) fn push_unchecked(&mut self, value: V) { + let (key, index) = value.split(); match self.containers.last_mut() { Some(container) if container.key == key => container.push_unchecked(index), @@ -192,16 +173,16 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// rb.insert(3); /// assert_eq!(rb.remove(3), true); /// assert_eq!(rb.remove(3), false); /// assert_eq!(rb.contains(3), false); /// ``` - pub fn remove(&mut self, value: u32) -> bool { - let (key, index) = util::split(value); + pub fn remove(&mut self, value: V) -> bool { + let (key, index) = value.split(); match self.containers.binary_search_by_key(&key, |c| c.key) { Ok(loc) => { if self.containers[loc].remove(index) { @@ -223,24 +204,23 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// rb.insert(2); /// rb.insert(3); /// assert_eq!(rb.remove_range(2..4), 2); /// ``` pub fn remove_range(&mut self, range: R) -> u64 where - R: RangeBounds, + R: RangeBounds, { - let (start, end) = match util::convert_range_to_inclusive(range) { - Some(range) => (*range.start(), *range.end()), - None => return 0, + let Some(range) = V::range(range) else { + return 0; }; - let (start_container_key, start_index) = util::split(start); - let (end_container_key, end_index) = util::split(end); + let (start_container_key, start_index) = range.start(); + let (end_container_key, end_index) = range.end(); let mut index = 0; let mut removed = 0; @@ -265,16 +245,16 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// rb.insert(1); /// assert_eq!(rb.contains(0), false); /// assert_eq!(rb.contains(1), true); /// assert_eq!(rb.contains(100), false); /// ``` - pub fn contains(&self, value: u32) -> bool { - let (key, index) = util::split(value); + pub fn contains(&self, value: V) -> bool { + let (key, index) = value.split(); match self.containers.binary_search_by_key(&key, |c| c.key) { Ok(loc) => self.containers[loc].contains(index), Err(_) => false, @@ -286,9 +266,9 @@ impl RoaringBitmap { /// # Examples /// /// ``` - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// // An empty range is always contained /// assert!(rb.contains_range(7..7)); /// @@ -302,15 +282,15 @@ impl RoaringBitmap { /// ``` pub fn contains_range(&self, range: R) -> bool where - R: RangeBounds, + R: RangeBounds, { - let (start, end) = match util::convert_range_to_inclusive(range) { - Some(range) => (*range.start(), *range.end()), + let Some(range) = V::range(range) else { // Empty ranges are always contained - None => return true, + return true; }; - let (start_high, start_low) = util::split(start); - let (end_high, end_low) = util::split(end); + + let (start_high, start_low) = range.start(); + let (end_high, end_low) = range.end(); debug_assert!(start_high <= end_high); let containers = @@ -323,7 +303,7 @@ impl RoaringBitmap { return containers[0].contains_range(start_low..=end_low); } - let high_span = usize::from(end_high - start_high); + let high_span = range.containers_count() - 1; // If this contains everything in the range, there should be a container for every item in the span // and the container that many items away should be the high key let containers = match containers.get(high_span) { @@ -346,9 +326,9 @@ impl RoaringBitmap { /// # Examples /// /// ``` - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// rb.insert_range(0x10000..0x40000); /// rb.insert(0x50001); /// rb.insert(0x50005); @@ -362,16 +342,14 @@ impl RoaringBitmap { /// ``` pub fn range_cardinality(&self, range: R) -> u64 where - R: RangeBounds, + R: RangeBounds, { - let (start, end) = match util::convert_range_to_inclusive(range) { - Some(range) => (*range.start(), *range.end()), - // Empty ranges have 0 bits set in them - None => return 0, + let Some(range) = V::range(range) else { + return 0; }; - let (start_key, start_low) = util::split(start); - let (end_key, end_low) = util::split(end); + let (start_key, start_low) = range.start(); + let (end_key, end_low) = range.end(); let mut cardinality = 0; @@ -411,9 +389,9 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// rb.insert(1); /// assert_eq!(rb.contains(1), true); /// rb.clear(); @@ -428,9 +406,9 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// assert_eq!(rb.is_empty(), true); /// /// rb.insert(3); @@ -445,14 +423,14 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::full(); - /// assert!(!rb.is_empty()); - /// assert!(rb.is_full()); + /// let mut rb = Roaring32::new(); + /// rb.insert(42); + /// assert!(!rb.is_full()); /// ``` pub fn is_full(&self) -> bool { - self.containers.len() == (u16::MAX as usize + 1) + self.containers.len() == V::max_containers() && self.containers.iter().all(Container::is_full) } @@ -461,9 +439,9 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// assert_eq!(rb.len(), 0); /// /// rb.insert(3); @@ -482,17 +460,17 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// assert_eq!(rb.min(), None); /// /// rb.insert(3); /// rb.insert(4); /// assert_eq!(rb.min(), Some(3)); /// ``` - pub fn min(&self) -> Option { - self.containers.first().and_then(|tail| tail.min().map(|min| util::join(tail.key, min))) + pub fn min(&self) -> Option { + self.containers.first().and_then(|tail| tail.min().map(|min| V::join(tail.key, min))) } /// Returns the maximum value in the set (if the set is non-empty). @@ -500,17 +478,17 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// assert_eq!(rb.max(), None); /// /// rb.insert(3); /// rb.insert(4); /// assert_eq!(rb.max(), Some(4)); /// ``` - pub fn max(&self) -> Option { - self.containers.last().and_then(|tail| tail.max().map(|max| util::join(tail.key, max))) + pub fn max(&self) -> Option { + self.containers.last().and_then(|tail| tail.max().map(|max| V::join(tail.key, max))) } /// Returns the number of integers that are <= value. rank(u32::MAX) == len() @@ -518,9 +496,9 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// assert_eq!(rb.rank(0), 0); /// /// rb.insert(3); @@ -528,10 +506,10 @@ impl RoaringBitmap { /// assert_eq!(rb.rank(3), 1); /// assert_eq!(rb.rank(10), 2) /// ``` - pub fn rank(&self, value: u32) -> u64 { + pub fn rank(&self, value: V) -> u64 { // if len becomes cached for RoaringBitmap: return len if len > value - let (key, index) = util::split(value); + let (key, index) = value.split(); match self.containers.binary_search_by_key(&key, |c| c.key) { Ok(i) => { @@ -550,9 +528,9 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// assert_eq!(rb.select(0), None); /// /// rb.append(vec![0, 10, 100]); @@ -562,16 +540,13 @@ impl RoaringBitmap { /// assert_eq!(rb.select(2), Some(100)); /// assert_eq!(rb.select(3), None); /// ``` - pub fn select(&self, n: u32) -> Option { - let mut n = n as u64; + pub fn select(&self, n: V) -> Option { + let mut n: u64 = n.into(); for container in &self.containers { let len = container.len(); if len > n { - return container - .store - .select(n as u16) - .map(|index| util::join(container.key, index)); + return container.store.select(n as u16).map(|index| V::join(container.key, index)); } n -= len; } @@ -584,15 +559,15 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::from_iter([1, 5, 7, 9]); + /// let mut rb = Roaring32::from_iter([1, 5, 7, 9]); /// rb.remove_smallest(2); - /// assert_eq!(rb, RoaringBitmap::from_iter([7, 9])); + /// assert_eq!(rb, Roaring32::from_iter([7, 9])); /// - /// let mut rb = RoaringBitmap::from_iter([1, 3, 7, 9]); + /// let mut rb = Roaring32::from_iter([1, 3, 7, 9]); /// rb.remove_smallest(2); - /// assert_eq!(rb, RoaringBitmap::from_iter([7, 9])); + /// assert_eq!(rb, Roaring32::from_iter([7, 9])); pub fn remove_smallest(&mut self, mut n: u64) { // remove containers up to the front of the target let position = self.containers.iter().position(|container| { @@ -620,13 +595,13 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::from_iter([1, 5, 7, 9]); + /// let mut rb = Roaring32::from_iter([1, 5, 7, 9]); /// rb.remove_biggest(2); - /// assert_eq!(rb, RoaringBitmap::from_iter([1, 5])); + /// assert_eq!(rb, Roaring32::from_iter([1, 5])); /// rb.remove_biggest(1); - /// assert_eq!(rb, RoaringBitmap::from_iter([1])); + /// assert_eq!(rb, Roaring32::from_iter([1])); pub fn remove_biggest(&mut self, mut n: u64) { // remove containers up to the back of the target let position = self.containers.iter().rposition(|container| { @@ -648,17 +623,27 @@ impl RoaringBitmap { self.containers.clear(); } } + + #[cfg(test)] + pub fn with_containers(containers: Vec>) -> Self { + Self { containers } + } + + #[cfg(test)] + pub fn containers(&self) -> &[Container] { + &self.containers + } } -impl Default for RoaringBitmap { - fn default() -> RoaringBitmap { - RoaringBitmap::new() +impl Default for RoaringBitmap { + fn default() -> Self { + Self::new() } } -impl Clone for RoaringBitmap { +impl Clone for RoaringBitmap { fn clone(&self) -> Self { - RoaringBitmap { containers: self.containers.clone() } + Self { containers: self.containers.clone() } } fn clone_from(&mut self, other: &Self) { @@ -668,10 +653,8 @@ impl Clone for RoaringBitmap { #[cfg(test)] mod tests { - use proptest::collection::vec; - use proptest::prelude::*; - - use super::*; + use crate::Roaring32; + use proptest::{collection::vec, prelude::*}; proptest! { #[test] @@ -680,7 +663,7 @@ mod tests { checks in vec(0u32..=262143, 1000) ){ let r = lo..hi; - let mut b = RoaringBitmap::new(); + let mut b = Roaring32::new(); let inserted = b.insert_range(r.clone()); if r.end > r.start { assert_eq!(inserted, r.end as u64 - r.start as u64); @@ -708,7 +691,7 @@ mod tests { #[test] fn test_insert_remove_range_same_container() { - let mut b = RoaringBitmap::new(); + let mut b = Roaring32::new(); let inserted = b.insert_range(1..5); assert_eq!(inserted, 4); @@ -726,7 +709,7 @@ mod tests { #[test] fn test_insert_remove_range_pre_populated() { - let mut b = RoaringBitmap::new(); + let mut b = Roaring32::new(); let inserted = b.insert_range(1..20_000); assert_eq!(inserted, 19_999); @@ -739,7 +722,7 @@ mod tests { #[test] fn test_insert_max_u32() { - let mut b = RoaringBitmap::new(); + let mut b = Roaring32::new(); let inserted = b.insert(u32::MAX); // We are allowed to add u32::MAX assert!(inserted); @@ -747,123 +730,123 @@ mod tests { #[test] fn test_insert_remove_across_container() { - let mut b = RoaringBitmap::new(); + let mut b = Roaring32::new(); let inserted = b.insert_range(u16::MAX as u32..=u16::MAX as u32 + 1); assert_eq!(inserted, 2); - assert_eq!(b.containers.len(), 2); + assert_eq!(b.containers().len(), 2); let removed = b.remove_range(u16::MAX as u32 + 1..=u16::MAX as u32 + 1); assert_eq!(removed, 1); - assert_eq!(b.containers.len(), 1); + assert_eq!(b.containers().len(), 1); } #[test] fn test_insert_remove_single_element() { - let mut b = RoaringBitmap::new(); + let mut b = Roaring32::new(); let inserted = b.insert_range(u16::MAX as u32 + 1..=u16::MAX as u32 + 1); assert_eq!(inserted, 1); - assert_eq!(b.containers[0].len(), 1); - assert_eq!(b.containers.len(), 1); + assert_eq!(b.containers()[0].len(), 1); + assert_eq!(b.containers().len(), 1); let removed = b.remove_range(u16::MAX as u32 + 1..=u16::MAX as u32 + 1); assert_eq!(removed, 1); - assert_eq!(b.containers.len(), 0); + assert_eq!(b.containers().len(), 0); } #[test] fn test_insert_remove_range_multi_container() { - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); assert_eq!(bitmap.insert_range(0..((1_u32 << 16) + 1)), (1_u64 << 16) + 1); - assert_eq!(bitmap.containers.len(), 2); - assert_eq!(bitmap.containers[0].key, 0); - assert_eq!(bitmap.containers[1].key, 1); + assert_eq!(bitmap.containers().len(), 2); + assert_eq!(bitmap.containers()[0].key, 0); + assert_eq!(bitmap.containers()[1].key, 1); assert_eq!(bitmap.insert_range(0..((1_u32 << 16) + 1)), 0); assert!(bitmap.insert((1_u32 << 16) * 4)); - assert_eq!(bitmap.containers.len(), 3); - assert_eq!(bitmap.containers[2].key, 4); + assert_eq!(bitmap.containers().len(), 3); + assert_eq!(bitmap.containers()[2].key, 4); assert_eq!(bitmap.remove_range(((1_u32 << 16) * 3)..=((1_u32 << 16) * 4)), 1); - assert_eq!(bitmap.containers.len(), 2); + assert_eq!(bitmap.containers().len(), 2); } #[test] fn insert_range_single() { - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); assert_eq!(bitmap.insert_range((1_u32 << 16)..(2_u32 << 16)), 1_u64 << 16); - assert_eq!(bitmap.containers.len(), 1); - assert_eq!(bitmap.containers[0].key, 1); + assert_eq!(bitmap.containers().len(), 1); + assert_eq!(bitmap.containers()[0].key, 1); } #[test] fn remove_smallest_for_vec() { - let mut bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]); + let mut bitmap = Roaring32::from_iter([1, 2, 3, 7, 9, 11]); bitmap.remove_smallest(3); assert_eq!(bitmap.len(), 3); - assert_eq!(bitmap, RoaringBitmap::from_iter([7, 9, 11])); + assert_eq!(bitmap, Roaring32::from_iter([7, 9, 11])); - bitmap = RoaringBitmap::from_iter([1, 2, 5, 7, 9, 11]); + bitmap = Roaring32::from_iter([1, 2, 5, 7, 9, 11]); bitmap.remove_smallest(3); assert_eq!(bitmap.len(), 3); - assert_eq!(bitmap, RoaringBitmap::from_iter([7, 9, 11])); + assert_eq!(bitmap, Roaring32::from_iter([7, 9, 11])); - bitmap = RoaringBitmap::from_iter([1, 3]); + bitmap = Roaring32::from_iter([1, 3]); bitmap.remove_smallest(2); assert_eq!(bitmap.len(), 0); - bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]); + bitmap = Roaring32::from_iter([1, 2, 3, 7, 9, 11]); bitmap.remove_smallest(0); assert_eq!(bitmap.len(), 6); - assert_eq!(bitmap, RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11])); + assert_eq!(bitmap, Roaring32::from_iter([1, 2, 3, 7, 9, 11])); - bitmap = RoaringBitmap::new(); + bitmap = Roaring32::new(); bitmap.insert_range(0..(1_u32 << 16) + 5); bitmap.remove_smallest(65537); assert_eq!(bitmap.len(), 4); - assert_eq!(bitmap, RoaringBitmap::from_iter([65537, 65538, 65539, 65540])); + assert_eq!(bitmap, Roaring32::from_iter([65537, 65538, 65539, 65540])); - bitmap = RoaringBitmap::from_iter([1, 2, 5, 7, 9, 11]); + bitmap = Roaring32::from_iter([1, 2, 5, 7, 9, 11]); bitmap.remove_smallest(7); - assert_eq!(bitmap, RoaringBitmap::default()); + assert_eq!(bitmap, Roaring32::default()); } #[test] fn remove_smallest_for_bit() { - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); bitmap.insert_range(0..4098); bitmap.remove_smallest(4095); assert_eq!(bitmap.len(), 3); // removed bit to vec - assert_eq!(bitmap, RoaringBitmap::from_iter([4095, 4096, 4097])); + assert_eq!(bitmap, Roaring32::from_iter([4095, 4096, 4097])); - bitmap = RoaringBitmap::new(); + bitmap = Roaring32::new(); bitmap.insert_range(0..6000); bitmap.remove_smallest(999); assert_eq!(bitmap.len(), 5001); - bitmap = RoaringBitmap::new(); + bitmap = Roaring32::new(); bitmap.insert_range(0..8000); bitmap.remove_smallest(10); assert_eq!(bitmap.len(), 7990); - bitmap = RoaringBitmap::new(); + bitmap = Roaring32::new(); bitmap.insert_range(0..200000); bitmap.remove_smallest(2000); assert_eq!(bitmap.len(), 198000); - assert_eq!(bitmap, RoaringBitmap::from_iter(2000..200000)); + assert_eq!(bitmap, Roaring32::from_iter(2000..200000)); - bitmap = RoaringBitmap::new(); + bitmap = Roaring32::new(); bitmap.insert_range(0..2); bitmap.insert_range(4..7); bitmap.insert_range(1000..6000); bitmap.remove_smallest(30); assert_eq!(bitmap.len(), 4975); - bitmap = RoaringBitmap::new(); + bitmap = Roaring32::new(); bitmap.insert_range(0..65535); bitmap.remove_smallest(0); assert_eq!(bitmap.len(), 65535); @@ -871,28 +854,28 @@ mod tests { #[test] fn remove_biggest_for_bit() { - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); bitmap.insert_range(0..5000); bitmap.remove_biggest(1000); assert_eq!(bitmap.len(), 4000); - bitmap = RoaringBitmap::new(); + bitmap = Roaring32::new(); bitmap.insert_range(0..6000); bitmap.remove_biggest(1000); assert_eq!(bitmap.len(), 5000); - bitmap = RoaringBitmap::new(); + bitmap = Roaring32::new(); bitmap.insert_range(0..200000); bitmap.remove_biggest(196000); assert_eq!(bitmap.len(), 4000); - bitmap = RoaringBitmap::new(); + bitmap = Roaring32::new(); bitmap.insert_range(0..200000); bitmap.remove_biggest(2000); assert_eq!(bitmap.len(), 198000); - assert_eq!(bitmap, RoaringBitmap::from_iter(0..198000)); + assert_eq!(bitmap, Roaring32::from_iter(0..198000)); - bitmap = RoaringBitmap::new(); + bitmap = Roaring32::new(); bitmap.insert_range(0..65535); bitmap.remove_biggest(0); assert_eq!(bitmap.len(), 65535); @@ -900,27 +883,27 @@ mod tests { #[test] fn remove_biggest_for_vec() { - let mut bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]); + let mut bitmap = Roaring32::from_iter([1, 2, 3, 7, 9, 11]); bitmap.remove_biggest(2); - assert_eq!(bitmap, RoaringBitmap::from_iter([1, 2, 3, 7])); + assert_eq!(bitmap, Roaring32::from_iter([1, 2, 3, 7])); - bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]); + bitmap = Roaring32::from_iter([1, 2, 3, 7, 9, 11]); bitmap.remove_biggest(6); assert_eq!(bitmap.len(), 0); - bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]); + bitmap = Roaring32::from_iter([1, 2, 3, 7, 9, 11]); bitmap.remove_biggest(0); assert_eq!(bitmap.len(), 6); - assert_eq!(bitmap, RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11])); + assert_eq!(bitmap, Roaring32::from_iter([1, 2, 3, 7, 9, 11])); - bitmap = RoaringBitmap::new(); + bitmap = Roaring32::new(); bitmap.insert_range(0..(1_u32 << 16) + 5); bitmap.remove_biggest(65537); assert_eq!(bitmap.len(), 4); - assert_eq!(bitmap, RoaringBitmap::from_iter([0, 1, 2, 3])); + assert_eq!(bitmap, Roaring32::from_iter([0, 1, 2, 3])); - let mut bitmap = RoaringBitmap::from_iter([1, 2, 3]); + let mut bitmap = Roaring32::from_iter([1, 2, 3]); bitmap.remove_biggest(4); - assert_eq!(bitmap, RoaringBitmap::default()); + assert_eq!(bitmap, Roaring32::default()); } } diff --git a/src/bitmap/iter.rs b/src/core/iter.rs similarity index 68% rename from src/bitmap/iter.rs rename to src/core/iter.rs index 35eddc820..a3eb035c4 100644 --- a/src/bitmap/iter.rs +++ b/src/core/iter.rs @@ -1,39 +1,40 @@ -use std::iter::{self, FromIterator}; -use std::{slice, vec}; - use super::container::Container; -use crate::{NonSortedIntegers, RoaringBitmap}; +use crate::{NonSortedIntegers, RoaringBitmap, Value}; +use std::{ + iter::{self, FromIterator}, + slice, vec, +}; /// An iterator for `RoaringBitmap`. -pub struct Iter<'a> { - inner: iter::Flatten>, +pub struct Iter<'a, V: Value> { + inner: iter::Flatten>>, size_hint: u64, } /// An iterator for `RoaringBitmap`. -pub struct IntoIter { - inner: iter::Flatten>, +pub struct IntoIter { + inner: iter::Flatten>>, size_hint: u64, } -impl Iter<'_> { - fn new(containers: &[Container]) -> Iter { +impl<'a, V: Value> Iter<'a, V> { + fn new(containers: &'a [Container]) -> Self { let size_hint = containers.iter().map(|c| c.len()).sum(); Iter { inner: containers.iter().flatten(), size_hint } } } -impl IntoIter { - fn new(containers: Vec) -> IntoIter { +impl IntoIter { + fn new(containers: Vec>) -> Self { let size_hint = containers.iter().map(|c| c.len()).sum(); IntoIter { inner: containers.into_iter().flatten(), size_hint } } } -impl Iterator for Iter<'_> { - type Item = u32; +impl Iterator for Iter<'_, V> { + type Item = V; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option { self.size_hint = self.size_hint.saturating_sub(1); self.inner.next() } @@ -47,7 +48,7 @@ impl Iterator for Iter<'_> { } } -impl DoubleEndedIterator for Iter<'_> { +impl DoubleEndedIterator for Iter<'_, V> { fn next_back(&mut self) -> Option { self.size_hint = self.size_hint.saturating_sub(1); self.inner.next_back() @@ -55,16 +56,16 @@ impl DoubleEndedIterator for Iter<'_> { } #[cfg(target_pointer_width = "64")] -impl ExactSizeIterator for Iter<'_> { +impl ExactSizeIterator for Iter<'_, V> { fn len(&self) -> usize { self.size_hint as usize } } -impl Iterator for IntoIter { - type Item = u32; +impl Iterator for IntoIter { + type Item = V; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option { self.size_hint = self.size_hint.saturating_sub(1); self.inner.next() } @@ -78,7 +79,7 @@ impl Iterator for IntoIter { } } -impl DoubleEndedIterator for IntoIter { +impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { self.size_hint = self.size_hint.saturating_sub(1); self.inner.next_back() @@ -86,90 +87,90 @@ impl DoubleEndedIterator for IntoIter { } #[cfg(target_pointer_width = "64")] -impl ExactSizeIterator for IntoIter { +impl ExactSizeIterator for IntoIter { fn len(&self) -> usize { self.size_hint as usize } } -impl RoaringBitmap { +impl RoaringBitmap { /// Iterator over each value stored in the RoaringBitmap, guarantees values are ordered by value. /// /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// use std::iter::FromIterator; /// - /// let bitmap = (1..3).collect::(); + /// let bitmap = (1..3).collect::(); /// let mut iter = bitmap.iter(); /// /// assert_eq!(iter.next(), Some(1)); /// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), None); /// ``` - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter { Iter::new(&self.containers) } } -impl<'a> IntoIterator for &'a RoaringBitmap { - type Item = u32; - type IntoIter = Iter<'a>; +impl<'a, V: Value> IntoIterator for &'a RoaringBitmap { + type Item = V; + type IntoIter = Iter<'a, V>; - fn into_iter(self) -> Iter<'a> { + fn into_iter(self) -> Iter<'a, V> { self.iter() } } -impl IntoIterator for RoaringBitmap { - type Item = u32; - type IntoIter = IntoIter; +impl IntoIterator for RoaringBitmap { + type Item = V; + type IntoIter = IntoIter; - fn into_iter(self) -> IntoIter { + fn into_iter(self) -> IntoIter { IntoIter::new(self.containers) } } -impl From<[u32; N]> for RoaringBitmap { - fn from(arr: [u32; N]) -> Self { +impl From<[V; N]> for RoaringBitmap { + fn from(arr: [V; N]) -> Self { RoaringBitmap::from_iter(arr) } } -impl FromIterator for RoaringBitmap { - fn from_iter>(iterator: I) -> RoaringBitmap { +impl FromIterator for RoaringBitmap { + fn from_iter>(iterator: I) -> RoaringBitmap { let mut rb = RoaringBitmap::new(); rb.extend(iterator); rb } } -impl<'a> FromIterator<&'a u32> for RoaringBitmap { - fn from_iter>(iterator: I) -> RoaringBitmap { +impl<'a, V: Value> FromIterator<&'a V> for RoaringBitmap { + fn from_iter>(iterator: I) -> RoaringBitmap { let mut rb = RoaringBitmap::new(); rb.extend(iterator); rb } } -impl Extend for RoaringBitmap { - fn extend>(&mut self, iterator: I) { +impl Extend for RoaringBitmap { + fn extend>(&mut self, iterator: I) { for value in iterator { self.insert(value); } } } -impl<'a> Extend<&'a u32> for RoaringBitmap { - fn extend>(&mut self, iterator: I) { +impl<'a, V: Value> Extend<&'a V> for RoaringBitmap { + fn extend>(&mut self, iterator: I) { for value in iterator { self.insert(*value); } } } -impl RoaringBitmap { +impl RoaringBitmap { /// Create the set from a sorted iterator. Values must be sorted and deduplicated. /// /// The values of the iterator must be ordered and strictly greater than the greatest value @@ -182,9 +183,9 @@ impl RoaringBitmap { /// # Example: Create a set from an ordered list of integers. /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::from_sorted_iter(0..10).unwrap(); + /// let mut rb = Roaring32::from_sorted_iter(0..10).unwrap(); /// /// assert!(rb.iter().eq(0..10)); /// ``` @@ -192,16 +193,16 @@ impl RoaringBitmap { /// # Example: Try to create a set from a non-ordered list of integers. /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// /// let integers = 0..10u32; - /// let error = RoaringBitmap::from_sorted_iter(integers.rev()).unwrap_err(); + /// let error = Roaring32::from_sorted_iter(integers.rev()).unwrap_err(); /// /// assert_eq!(error.valid_until(), 1); /// ``` - pub fn from_sorted_iter>( + pub fn from_sorted_iter>( iterator: I, - ) -> Result { + ) -> Result, NonSortedIntegers> { let mut rb = RoaringBitmap::new(); rb.append(iterator).map(|_| rb) } @@ -218,14 +219,14 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let mut rb = RoaringBitmap::new(); + /// let mut rb = Roaring32::new(); /// assert_eq!(rb.append(0..10), Ok(10)); /// /// assert!(rb.iter().eq(0..10)); /// ``` - pub fn append>( + pub fn append>( &mut self, iterator: I, ) -> Result { diff --git a/src/core/mod.rs b/src/core/mod.rs new file mode 100644 index 000000000..53c406c15 --- /dev/null +++ b/src/core/mod.rs @@ -0,0 +1,30 @@ +mod arbitrary; +mod container; +mod fmt; +mod multiops; +mod proptests; +mod store; + +// Order of these modules matters as it determines the `impl` blocks order in +// the docs +mod cmp; +mod inherent; +mod iter; +mod ops; + +#[cfg(feature = "serde")] +mod serde; + +mod serialization; + +use self::cmp::Pairs; +use crate::Value; + +pub use self::iter::IntoIter; +pub use self::iter::Iter; + +/// A generic compressed bitmap using the [Roaring bitmap compression scheme](https://roaringbitmap.org/). +#[derive(PartialEq)] +pub struct RoaringBitmap { + containers: Vec>, +} diff --git a/src/bitmap/multiops.rs b/src/core/multiops.rs similarity index 83% rename from src/bitmap/multiops.rs rename to src/core/multiops.rs index cb337bdc9..0c9accbc0 100644 --- a/src/bitmap/multiops.rs +++ b/src/core/multiops.rs @@ -1,3 +1,5 @@ +use super::{container::Container, store::Store}; +use crate::{MultiOps, RoaringBitmap, Value}; use std::{ borrow::Cow, cmp::Reverse, @@ -6,12 +8,6 @@ use std::{ ops::{BitOrAssign, BitXorAssign}, }; -use retain_mut::RetainMut; - -use crate::{MultiOps, RoaringBitmap}; - -use super::{container::Container, store::Store}; - /// When collecting bitmaps for optimizing the computation. If we don't know how many // elements are in the iterator we collect 10 elements. const BASE_COLLECT: usize = 10; @@ -20,11 +16,11 @@ const BASE_COLLECT: usize = 10; /// much faster without impacting the memory usage too much (in most cases). const MAX_COLLECT: usize = 50; -impl MultiOps for I +impl MultiOps> for I where - I: IntoIterator, + I: IntoIterator>, { - type Output = RoaringBitmap; + type Output = RoaringBitmap; fn union(self) -> Self::Output { try_multi_or_owned(self.into_iter().map(Ok::<_, Infallible>)).unwrap() @@ -43,11 +39,11 @@ where } } -impl MultiOps> for I +impl MultiOps, E>> for I where - I: IntoIterator>, + I: IntoIterator, E>>, { - type Output = Result; + type Output = Result, E>; fn union(self) -> Self::Output { try_multi_or_owned(self) @@ -66,11 +62,11 @@ where } } -impl<'a, I> MultiOps<&'a RoaringBitmap> for I +impl<'a, V: Value, I> MultiOps<&'a RoaringBitmap> for I where - I: IntoIterator, + I: IntoIterator>, { - type Output = RoaringBitmap; + type Output = RoaringBitmap; fn union(self) -> Self::Output { try_multi_or_ref(self.into_iter().map(Ok::<_, Infallible>)).unwrap() @@ -89,11 +85,11 @@ where } } -impl<'a, I, E: 'a> MultiOps> for I +impl<'a, V: Value, I, E: 'a> MultiOps, E>> for I where - I: IntoIterator>, + I: IntoIterator, E>>, { - type Output = Result; + type Output = Result, E>; fn union(self) -> Self::Output { try_multi_or_ref(self) @@ -113,9 +109,9 @@ where } #[inline] -fn try_multi_and_owned( - bitmaps: impl IntoIterator>, -) -> Result { +fn try_multi_and_owned( + bitmaps: impl IntoIterator, E>>, +) -> Result, E> { let mut iter = bitmaps.into_iter(); // We're going to take a bunch of elements at the start of the iterator and sort @@ -139,9 +135,9 @@ fn try_multi_and_owned( } #[inline] -fn try_multi_and_ref<'a, E>( - bitmaps: impl IntoIterator>, -) -> Result { +fn try_multi_and_ref<'a, V: Value + 'a, E>( + bitmaps: impl IntoIterator, E>>, +) -> Result, E> { let mut iter = bitmaps.into_iter(); // We're going to take a bunch of elements at the start of the iterator and sort @@ -164,9 +160,9 @@ fn try_multi_and_ref<'a, E>( } #[inline] -fn try_multi_sub_owned( - bitmaps: impl IntoIterator>, -) -> Result { +fn try_multi_sub_owned( + bitmaps: impl IntoIterator, E>>, +) -> Result, E> { let mut iter = bitmaps.into_iter(); match iter.next().transpose()? { Some(mut lhs) => { @@ -183,9 +179,9 @@ fn try_multi_sub_owned( } #[inline] -fn try_multi_sub_ref<'a, E>( - bitmaps: impl IntoIterator>, -) -> Result { +fn try_multi_sub_ref<'a, V: Value + 'a, E>( + bitmaps: impl IntoIterator, E>>, +) -> Result, E> { let mut iter = bitmaps.into_iter(); match iter.next().transpose()?.cloned() { Some(mut lhs) => { @@ -203,9 +199,9 @@ fn try_multi_sub_ref<'a, E>( } #[inline] -fn try_multi_or_owned( - bitmaps: impl IntoIterator>, -) -> Result { +fn try_multi_or_owned( + bitmaps: impl IntoIterator, E>>, +) -> Result, E> { let mut iter = bitmaps.into_iter(); // We're going to take a bunch of elements at the start of the iterator and @@ -229,7 +225,7 @@ fn try_multi_or_owned( merge_container_owned(&mut containers, bitmap?.containers, BitOrAssign::bitor_assign); } - RetainMut::retain_mut(&mut containers, |container| { + containers.retain_mut(|container| { if container.len() > 0 { container.ensure_correct_store(); true @@ -242,9 +238,9 @@ fn try_multi_or_owned( } #[inline] -fn try_multi_xor_owned( - bitmaps: impl IntoIterator>, -) -> Result { +fn try_multi_xor_owned( + bitmaps: impl IntoIterator, E>>, +) -> Result, E> { let mut iter = bitmaps.into_iter(); let mut containers = match iter.next().transpose()? { None => Vec::new(), @@ -255,7 +251,7 @@ fn try_multi_xor_owned( merge_container_owned(&mut containers, bitmap?.containers, BitXorAssign::bitxor_assign); } - RetainMut::retain_mut(&mut containers, |container| { + containers.retain_mut(|container| { if container.len() > 0 { container.ensure_correct_store(); true @@ -267,9 +263,9 @@ fn try_multi_xor_owned( Ok(RoaringBitmap { containers }) } -fn merge_container_owned( - lhs: &mut Vec, - rhs: Vec, +fn merge_container_owned( + lhs: &mut Vec>, + rhs: Vec>, op: impl Fn(&mut Store, Store), ) { for mut rhs in rhs { @@ -289,9 +285,9 @@ fn merge_container_owned( } #[inline] -fn try_multi_or_ref<'a, E: 'a>( - bitmaps: impl IntoIterator>, -) -> Result { +fn try_multi_or_ref<'a, V: Value + 'a, E: 'a>( + bitmaps: impl IntoIterator, E>>, +) -> Result, E> { // This algorithm operates on bitmaps. It must deal with arrays for which there are not (yet) // any others with the same key. // @@ -310,7 +306,7 @@ fn try_multi_or_ref<'a, E: 'a>( let mut start = start.into_iter(); let mut containers = match start.next() { Some(c) => { - let c: Vec> = c.containers.iter().map(Cow::Borrowed).collect(); + let c: Vec>> = c.containers.iter().map(Cow::Borrowed).collect(); if c.is_empty() { // everything must be empty if the max is empty start.by_ref().nth(start_size); @@ -343,9 +339,9 @@ fn try_multi_or_ref<'a, E: 'a>( } #[inline] -fn try_multi_xor_ref<'a, E: 'a>( - bitmaps: impl IntoIterator>, -) -> Result { +fn try_multi_xor_ref<'a, V: Value + 'a, E: 'a>( + bitmaps: impl IntoIterator, E>>, +) -> Result, E> { // // This algorithm operates on bitmaps. It must deal with arrays for which there are not (yet) // any others with the same key. @@ -358,7 +354,7 @@ fn try_multi_xor_ref<'a, E: 'a>( // Phase 1. Borrow all the containers from the first element. let mut iter = bitmaps.into_iter(); - let mut containers: Vec> = match iter.next().transpose()? { + let mut containers: Vec>> = match iter.next().transpose()? { None => Vec::new(), Some(v) => v.containers.iter().map(Cow::Borrowed).collect(), }; @@ -383,9 +379,9 @@ fn try_multi_xor_ref<'a, E: 'a>( Ok(RoaringBitmap { containers }) } -fn merge_container_ref<'a>( - containers: &mut Vec>, - rhs: &'a [Container], +fn merge_container_ref<'a, V: Value>( + containers: &mut Vec>>, + rhs: &'a [Container], op: impl Fn(&mut Store, &Store), ) { for rhs in rhs { diff --git a/src/bitmap/ops.rs b/src/core/ops.rs similarity index 72% rename from src/bitmap/ops.rs rename to src/core/ops.rs index 7fe930a6a..c8b87f25a 100644 --- a/src/bitmap/ops.rs +++ b/src/core/ops.rs @@ -1,13 +1,11 @@ -use std::mem; -use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; - -use retain_mut::RetainMut; - -use crate::bitmap::container::Container; -use crate::bitmap::Pairs; -use crate::RoaringBitmap; - -impl RoaringBitmap { +use super::{container::Container, Pairs}; +use crate::{RoaringBitmap, Value}; +use std::{ + mem, + ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}, +}; + +impl RoaringBitmap { /// Computes the len of the intersection with the specified other bitmap without creating a /// new bitmap. /// @@ -17,15 +15,15 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let rb1: RoaringBitmap = (1..4).collect(); - /// let rb2: RoaringBitmap = (3..5).collect(); + /// let rb1: Roaring32 = (1..4).collect(); + /// let rb2: Roaring32 = (3..5).collect(); /// /// /// assert_eq!(rb1.intersection_len(&rb2), (rb1 & rb2).len()); /// ``` - pub fn intersection_len(&self, other: &RoaringBitmap) -> u64 { + pub fn intersection_len(&self, other: &RoaringBitmap) -> u64 { Pairs::new(&self.containers, &other.containers) .map(|pair| match pair { (Some(..), None) => 0, @@ -44,15 +42,15 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let rb1: RoaringBitmap = (1..4).collect(); - /// let rb2: RoaringBitmap = (3..5).collect(); + /// let rb1: Roaring32 = (1..4).collect(); + /// let rb2: Roaring32 = (3..5).collect(); /// /// /// assert_eq!(rb1.union_len(&rb2), (rb1 | rb2).len()); /// ``` - pub fn union_len(&self, other: &RoaringBitmap) -> u64 { + pub fn union_len(&self, other: &RoaringBitmap) -> u64 { self.len().wrapping_add(other.len()).wrapping_sub(self.intersection_len(other)) } @@ -65,15 +63,15 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let rb1: RoaringBitmap = (1..4).collect(); - /// let rb2: RoaringBitmap = (3..5).collect(); + /// let rb1: Roaring32 = (1..4).collect(); + /// let rb2: Roaring32 = (3..5).collect(); /// /// /// assert_eq!(rb1.difference_len(&rb2), (rb1 - rb2).len()); /// ``` - pub fn difference_len(&self, other: &RoaringBitmap) -> u64 { + pub fn difference_len(&self, other: &RoaringBitmap) -> u64 { self.len() - self.intersection_len(other) } @@ -86,15 +84,15 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let rb1: RoaringBitmap = (1..4).collect(); - /// let rb2: RoaringBitmap = (3..5).collect(); + /// let rb1: Roaring32 = (1..4).collect(); + /// let rb2: Roaring32 = (3..5).collect(); /// /// /// assert_eq!(rb1.symmetric_difference_len(&rb2), (rb1 ^ rb2).len()); /// ``` - pub fn symmetric_difference_len(&self, other: &RoaringBitmap) -> u64 { + pub fn symmetric_difference_len(&self, other: &RoaringBitmap) -> u64 { let intersection_len = self.intersection_len(other); self.len() .wrapping_add(other.len()) @@ -103,40 +101,40 @@ impl RoaringBitmap { } } -impl BitOr for RoaringBitmap { - type Output = RoaringBitmap; +impl BitOr> for RoaringBitmap { + type Output = RoaringBitmap; /// An `union` between two sets. - fn bitor(mut self, rhs: RoaringBitmap) -> RoaringBitmap { + fn bitor(mut self, rhs: RoaringBitmap) -> Self::Output { BitOrAssign::bitor_assign(&mut self, rhs); self } } -impl BitOr<&RoaringBitmap> for RoaringBitmap { - type Output = RoaringBitmap; +impl BitOr<&RoaringBitmap> for RoaringBitmap { + type Output = RoaringBitmap; /// An `union` between two sets. - fn bitor(mut self, rhs: &RoaringBitmap) -> RoaringBitmap { + fn bitor(mut self, rhs: &RoaringBitmap) -> Self::Output { BitOrAssign::bitor_assign(&mut self, rhs); self } } -impl BitOr for &RoaringBitmap { - type Output = RoaringBitmap; +impl BitOr> for &RoaringBitmap { + type Output = RoaringBitmap; /// An `union` between two sets. - fn bitor(self, rhs: RoaringBitmap) -> RoaringBitmap { + fn bitor(self, rhs: RoaringBitmap) -> Self::Output { BitOr::bitor(rhs, self) } } -impl BitOr<&RoaringBitmap> for &RoaringBitmap { - type Output = RoaringBitmap; +impl BitOr<&RoaringBitmap> for &RoaringBitmap { + type Output = RoaringBitmap; /// An `union` between two sets. - fn bitor(self, rhs: &RoaringBitmap) -> RoaringBitmap { + fn bitor(self, rhs: &RoaringBitmap) -> Self::Output { let mut containers = Vec::new(); for pair in Pairs::new(&self.containers, &rhs.containers) { @@ -148,13 +146,13 @@ impl BitOr<&RoaringBitmap> for &RoaringBitmap { } } - RoaringBitmap { containers } + Self::Output { containers } } } -impl BitOrAssign for RoaringBitmap { +impl BitOrAssign> for RoaringBitmap { /// An `union` between two sets. - fn bitor_assign(&mut self, mut rhs: RoaringBitmap) { + fn bitor_assign(&mut self, mut rhs: RoaringBitmap) { // We make sure that we apply the union operation on the biggest map. if self.len() < rhs.len() { mem::swap(self, &mut rhs); @@ -170,9 +168,9 @@ impl BitOrAssign for RoaringBitmap { } } -impl BitOrAssign<&RoaringBitmap> for RoaringBitmap { +impl BitOrAssign<&RoaringBitmap> for RoaringBitmap { /// An `union` between two sets. - fn bitor_assign(&mut self, rhs: &RoaringBitmap) { + fn bitor_assign(&mut self, rhs: &RoaringBitmap) { for container in &rhs.containers { let key = container.key; match self.containers.binary_search_by_key(&key, |c| c.key) { @@ -183,40 +181,40 @@ impl BitOrAssign<&RoaringBitmap> for RoaringBitmap { } } -impl BitAnd for RoaringBitmap { - type Output = RoaringBitmap; +impl BitAnd> for RoaringBitmap { + type Output = RoaringBitmap; /// An `intersection` between two sets. - fn bitand(mut self, rhs: RoaringBitmap) -> RoaringBitmap { + fn bitand(mut self, rhs: RoaringBitmap) -> Self::Output { BitAndAssign::bitand_assign(&mut self, rhs); self } } -impl BitAnd<&RoaringBitmap> for RoaringBitmap { - type Output = RoaringBitmap; +impl BitAnd<&RoaringBitmap> for RoaringBitmap { + type Output = RoaringBitmap; /// An `intersection` between two sets. - fn bitand(mut self, rhs: &RoaringBitmap) -> RoaringBitmap { + fn bitand(mut self, rhs: &RoaringBitmap) -> Self::Output { BitAndAssign::bitand_assign(&mut self, rhs); self } } -impl BitAnd for &RoaringBitmap { - type Output = RoaringBitmap; +impl BitAnd> for &RoaringBitmap { + type Output = RoaringBitmap; /// An `intersection` between two sets. - fn bitand(self, rhs: RoaringBitmap) -> RoaringBitmap { + fn bitand(self, rhs: RoaringBitmap) -> Self::Output { BitAnd::bitand(rhs, self) } } -impl BitAnd<&RoaringBitmap> for &RoaringBitmap { - type Output = RoaringBitmap; +impl BitAnd<&RoaringBitmap> for &RoaringBitmap { + type Output = RoaringBitmap; /// An `intersection` between two sets. - fn bitand(self, rhs: &RoaringBitmap) -> RoaringBitmap { + fn bitand(self, rhs: &RoaringBitmap) -> RoaringBitmap { let mut containers = Vec::new(); for pair in Pairs::new(&self.containers, &rhs.containers) { @@ -228,19 +226,19 @@ impl BitAnd<&RoaringBitmap> for &RoaringBitmap { } } - RoaringBitmap { containers } + Self::Output { containers } } } -impl BitAndAssign for RoaringBitmap { +impl BitAndAssign> for RoaringBitmap { /// An `intersection` between two sets. - fn bitand_assign(&mut self, mut rhs: RoaringBitmap) { + fn bitand_assign(&mut self, mut rhs: RoaringBitmap) { // We make sure that we apply the intersection operation on the smallest map. if rhs.containers.len() < self.containers.len() { mem::swap(self, &mut rhs); } - RetainMut::retain_mut(&mut self.containers, |cont| { + self.containers.retain_mut(|cont| { let key = cont.key; match rhs.containers.binary_search_by_key(&key, |c| c.key) { Ok(loc) => { @@ -255,10 +253,10 @@ impl BitAndAssign for RoaringBitmap { } } -impl BitAndAssign<&RoaringBitmap> for RoaringBitmap { +impl BitAndAssign<&RoaringBitmap> for RoaringBitmap { /// An `intersection` between two sets. - fn bitand_assign(&mut self, rhs: &RoaringBitmap) { - RetainMut::retain_mut(&mut self.containers, |cont| { + fn bitand_assign(&mut self, rhs: &RoaringBitmap) { + self.containers.retain_mut(|cont| { let key = cont.key; match rhs.containers.binary_search_by_key(&key, |c| c.key) { Ok(loc) => { @@ -271,40 +269,40 @@ impl BitAndAssign<&RoaringBitmap> for RoaringBitmap { } } -impl Sub for RoaringBitmap { - type Output = RoaringBitmap; +impl Sub> for RoaringBitmap { + type Output = RoaringBitmap; /// A `difference` between two sets. - fn sub(mut self, rhs: RoaringBitmap) -> RoaringBitmap { + fn sub(mut self, rhs: RoaringBitmap) -> Self::Output { SubAssign::sub_assign(&mut self, &rhs); self } } -impl Sub<&RoaringBitmap> for RoaringBitmap { - type Output = RoaringBitmap; +impl Sub<&RoaringBitmap> for RoaringBitmap { + type Output = RoaringBitmap; /// A `difference` between two sets. - fn sub(mut self, rhs: &RoaringBitmap) -> RoaringBitmap { + fn sub(mut self, rhs: &RoaringBitmap) -> Self::Output { SubAssign::sub_assign(&mut self, rhs); self } } -impl Sub for &RoaringBitmap { - type Output = RoaringBitmap; +impl Sub> for &RoaringBitmap { + type Output = RoaringBitmap; /// A `difference` between two sets. - fn sub(self, rhs: RoaringBitmap) -> RoaringBitmap { + fn sub(self, rhs: RoaringBitmap) -> Self::Output { Sub::sub(self, &rhs) } } -impl Sub<&RoaringBitmap> for &RoaringBitmap { - type Output = RoaringBitmap; +impl Sub<&RoaringBitmap> for &RoaringBitmap { + type Output = RoaringBitmap; /// A `difference` between two sets. - fn sub(self, rhs: &RoaringBitmap) -> RoaringBitmap { + fn sub(self, rhs: &RoaringBitmap) -> Self::Output { let mut containers = Vec::new(); for pair in Pairs::new(&self.containers, &rhs.containers) { @@ -321,21 +319,21 @@ impl Sub<&RoaringBitmap> for &RoaringBitmap { } } - RoaringBitmap { containers } + Self::Output { containers } } } -impl SubAssign for RoaringBitmap { +impl SubAssign> for RoaringBitmap { /// A `difference` between two sets. - fn sub_assign(&mut self, rhs: RoaringBitmap) { + fn sub_assign(&mut self, rhs: RoaringBitmap) { SubAssign::sub_assign(self, &rhs) } } -impl SubAssign<&RoaringBitmap> for RoaringBitmap { +impl SubAssign<&RoaringBitmap> for RoaringBitmap { /// A `difference` between two sets. - fn sub_assign(&mut self, rhs: &RoaringBitmap) { - RetainMut::retain_mut(&mut self.containers, |cont| { + fn sub_assign(&mut self, rhs: &RoaringBitmap) { + self.containers.retain_mut(|cont| { match rhs.containers.binary_search_by_key(&cont.key, |c| c.key) { Ok(loc) => { SubAssign::sub_assign(cont, &rhs.containers[loc]); @@ -347,40 +345,40 @@ impl SubAssign<&RoaringBitmap> for RoaringBitmap { } } -impl BitXor for RoaringBitmap { - type Output = RoaringBitmap; +impl BitXor> for RoaringBitmap { + type Output = RoaringBitmap; /// A `symmetric difference` between two sets. - fn bitxor(mut self, rhs: RoaringBitmap) -> RoaringBitmap { + fn bitxor(mut self, rhs: RoaringBitmap) -> Self::Output { BitXorAssign::bitxor_assign(&mut self, rhs); self } } -impl BitXor<&RoaringBitmap> for RoaringBitmap { - type Output = RoaringBitmap; +impl BitXor<&RoaringBitmap> for RoaringBitmap { + type Output = RoaringBitmap; /// A `symmetric difference` between two sets. - fn bitxor(mut self, rhs: &RoaringBitmap) -> RoaringBitmap { + fn bitxor(mut self, rhs: &RoaringBitmap) -> Self::Output { BitXorAssign::bitxor_assign(&mut self, rhs); self } } -impl BitXor for &RoaringBitmap { - type Output = RoaringBitmap; +impl BitXor> for &RoaringBitmap { + type Output = RoaringBitmap; /// A `symmetric difference` between two sets. - fn bitxor(self, rhs: RoaringBitmap) -> RoaringBitmap { + fn bitxor(self, rhs: RoaringBitmap) -> Self::Output { BitXor::bitxor(rhs, self) } } -impl BitXor<&RoaringBitmap> for &RoaringBitmap { - type Output = RoaringBitmap; +impl BitXor<&RoaringBitmap> for &RoaringBitmap { + type Output = RoaringBitmap; /// A `symmetric difference` between two sets. - fn bitxor(self, rhs: &RoaringBitmap) -> RoaringBitmap { + fn bitxor(self, rhs: &RoaringBitmap) -> Self::Output { let mut containers = Vec::new(); for pair in Pairs::new(&self.containers, &rhs.containers) { @@ -397,13 +395,13 @@ impl BitXor<&RoaringBitmap> for &RoaringBitmap { } } - RoaringBitmap { containers } + Self::Output { containers } } } -impl BitXorAssign for RoaringBitmap { +impl BitXorAssign> for RoaringBitmap { /// A `symmetric difference` between two sets. - fn bitxor_assign(&mut self, rhs: RoaringBitmap) { + fn bitxor_assign(&mut self, rhs: RoaringBitmap) { for pair in Pairs::new(mem::take(&mut self.containers), rhs.containers) { match pair { (Some(mut lhs), Some(rhs)) => { @@ -420,9 +418,9 @@ impl BitXorAssign for RoaringBitmap { } } -impl BitXorAssign<&RoaringBitmap> for RoaringBitmap { +impl BitXorAssign<&RoaringBitmap> for RoaringBitmap { /// A `symmetric difference` between two sets. - fn bitxor_assign(&mut self, rhs: &RoaringBitmap) { + fn bitxor_assign(&mut self, rhs: &RoaringBitmap) { for pair in Pairs::new(mem::take(&mut self.containers), &rhs.containers) { match pair { (Some(mut lhs), Some(rhs)) => { @@ -441,7 +439,7 @@ impl BitXorAssign<&RoaringBitmap> for RoaringBitmap { #[cfg(test)] mod test { - use crate::{MultiOps, RoaringBitmap}; + use crate::{MultiOps, Roaring32}; use proptest::prelude::*; use std::convert::Infallible; @@ -449,41 +447,41 @@ mod test { proptest! { #[test] fn union_len_eq_len_of_materialized_union( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary() ) { prop_assert_eq!(a.union_len(&b), (a | b).len()); } #[test] fn intersection_len_eq_len_of_materialized_intersection( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary() ) { prop_assert_eq!(a.intersection_len(&b), (a & b).len()); } #[test] fn difference_len_eq_len_of_materialized_difference( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary() ) { prop_assert_eq!(a.difference_len(&b), (a - b).len()); } #[test] fn symmetric_difference_len_eq_len_of_materialized_symmetric_difference( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary() ) { prop_assert_eq!(a.symmetric_difference_len(&b), (a ^ b).len()); } #[test] fn all_union_give_the_same_result( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary(), - c in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary(), + c in Roaring32::arbitrary() ) { let mut ref_assign = a.clone(); ref_assign |= &b; @@ -517,9 +515,9 @@ mod test { #[test] fn all_intersection_give_the_same_result( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary(), - c in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary(), + c in Roaring32::arbitrary() ) { let mut ref_assign = a.clone(); ref_assign &= &b; @@ -553,9 +551,9 @@ mod test { #[test] fn all_difference_give_the_same_result( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary(), - c in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary(), + c in Roaring32::arbitrary() ) { let mut ref_assign = a.clone(); ref_assign -= &b; @@ -589,9 +587,9 @@ mod test { #[test] fn all_symmetric_difference_give_the_same_result( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary(), - c in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary(), + c in Roaring32::arbitrary() ) { let mut ref_assign = a.clone(); ref_assign ^= &b; diff --git a/src/bitmap/proptests.rs b/src/core/proptests.rs similarity index 90% rename from src/bitmap/proptests.rs rename to src/core/proptests.rs index 54b9c07d5..d8be0dbef 100644 --- a/src/bitmap/proptests.rs +++ b/src/core/proptests.rs @@ -1,7 +1,7 @@ #[cfg(test)] #[allow(clippy::eq_op)] // Allow equal expressions as operands mod test { - use crate::RoaringBitmap; + use crate::Roaring32; use proptest::prelude::*; // @@ -29,8 +29,8 @@ mod test { proptest! { #[test] fn unions_are_commutative( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary() ) { prop_assert_eq!(&a | &b, &b | &a); @@ -57,8 +57,8 @@ mod test { #[test] fn intersections_are_commutative( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary() ) { prop_assert_eq!(&a & &b, &b & &a); @@ -85,8 +85,8 @@ mod test { #[test] fn symmetric_differences_are_commutative( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary() ) { prop_assert_eq!(&a ^ &b, &b ^ &a); @@ -119,9 +119,9 @@ mod test { proptest! { #[test] fn unions_are_associative( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary(), - c in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary(), + c in Roaring32::arbitrary() ) { prop_assert_eq!( &a | ( &b | &c ), @@ -157,9 +157,9 @@ mod test { #[test] fn intersections_are_associative( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary(), - c in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary(), + c in Roaring32::arbitrary() ) { prop_assert_eq!( &a & ( &b & &c ), @@ -195,9 +195,9 @@ mod test { #[test] fn symmetric_differences_are_associative( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary(), - c in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary(), + c in Roaring32::arbitrary() ) { prop_assert_eq!( &a ^ ( &b ^ &c ), @@ -239,9 +239,9 @@ mod test { proptest! { #[test] fn union_distributes_over_intersection( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary(), - c in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary(), + c in Roaring32::arbitrary() ) { prop_assert_eq!( &a | ( &b & &c), @@ -290,9 +290,9 @@ mod test { #[test] fn intersection_distributes_over_union( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary(), - c in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary(), + c in Roaring32::arbitrary() ) { prop_assert_eq!( &a & ( &b | &c), @@ -341,9 +341,9 @@ mod test { #[test] fn intersection_distributes_over_symmetric_difference( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary(), - c in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary(), + c in Roaring32::arbitrary() ) { prop_assert_eq!( &a & ( &b ^ &c), @@ -396,10 +396,9 @@ mod test { proptest! { #[test] - fn the_empty_set_is_the_identity_for_union(a in RoaringBitmap::arbitrary()) { + fn the_empty_set_is_the_identity_for_union(a in Roaring32::arbitrary()) { prop_assert_eq!(&(&a | &empty_set()), &a); - #[allow(clippy::redundant_clone)] { // op_assign_ref let mut x = a.clone(); x |= &empty_set(); @@ -417,10 +416,9 @@ mod test { } #[test] - fn the_empty_set_is_the_identity_for_symmetric_difference(a in RoaringBitmap::arbitrary()) { + fn the_empty_set_is_the_identity_for_symmetric_difference(a in Roaring32::arbitrary()) { prop_assert_eq!(&(&a ^ &empty_set()), &a); - #[allow(clippy::redundant_clone)] { // op_assign_ref let mut x = a.clone(); x ^= &empty_set(); @@ -448,7 +446,7 @@ mod test { proptest! { #[test] - fn unions_are_idempotent(a in RoaringBitmap::arbitrary()) { + fn unions_are_idempotent(a in Roaring32::arbitrary()) { prop_assert_eq!(&(&a | &a), &a); { // op_assign_ref @@ -467,7 +465,7 @@ mod test { } #[test] - fn intersections_are_idempotent(a in RoaringBitmap::arbitrary()) { + fn intersections_are_idempotent(a in Roaring32::arbitrary()) { prop_assert_eq!(&(&a & &a), &a); { // op_assign_ref @@ -492,7 +490,7 @@ mod test { proptest! { #[test] - fn empty_set_domination(a in RoaringBitmap::arbitrary()) { + fn empty_set_domination(a in Roaring32::arbitrary()) { prop_assert_eq!(&a & &empty_set(), empty_set()); { // op_assign_ref @@ -520,18 +518,18 @@ mod test { proptest! { #[test] - fn reflexivity(a in RoaringBitmap::arbitrary()) { + fn reflexivity(a in Roaring32::arbitrary()) { prop_assert!(a.is_subset(&a)); } #[test] - fn antisymmetry(a in RoaringBitmap::arbitrary()) { + fn antisymmetry(a in Roaring32::arbitrary()) { let mut b = a.clone(); prop_assert_eq!(&a, &b); prop_assert!(a.is_subset(&b) && b.is_subset(&a)); // Flip one bit - let mut c = RoaringBitmap::new(); + let mut c = Roaring32::new(); c.insert(0); b ^= c; @@ -541,9 +539,9 @@ mod test { #[test] fn transitivity( - a in RoaringBitmap::arbitrary(), - mut b in RoaringBitmap::arbitrary(), - mut c in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + mut b in Roaring32::arbitrary(), + mut c in Roaring32::arbitrary() ) { b |= &a; c |= &b; @@ -560,12 +558,12 @@ mod test { proptest! { #[test] - fn existence_of_joins(a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary()) { + fn existence_of_joins(a in Roaring32::arbitrary(), b in Roaring32::arbitrary()) { prop_assert!(a.is_subset(&(&a | &b))); } #[test] - fn existence_of_meets(a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary()) { + fn existence_of_meets(a in Roaring32::arbitrary(), b in Roaring32::arbitrary()) { prop_assert!(&(&a & &b).is_subset(&a)); } } @@ -575,8 +573,8 @@ mod test { proptest! { #[test] fn inclusion_can_be_characterized_by_union_or_inersection( - b in RoaringBitmap::arbitrary(), - c in RoaringBitmap::arbitrary() + b in Roaring32::arbitrary(), + c in Roaring32::arbitrary() ) { let a = &b - &c; @@ -599,9 +597,9 @@ mod test { proptest! { #[test] fn relative_compliments( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary(), - c in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary(), + c in Roaring32::arbitrary() ) { let u = &a | &b | &c; @@ -938,9 +936,9 @@ mod test { proptest! { #[test] fn symmetric_difference_triangle_inequality( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary(), - c in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary(), + c in Roaring32::arbitrary() ) { prop_assert_eq!( &((&a ^ &b) ^ (&b ^ &c)), @@ -982,7 +980,7 @@ mod test { #[test] fn symmetric_difference_empty_set_neutral( - a in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary() ) { prop_assert_eq!( &(&a ^ &empty_set()), @@ -1006,7 +1004,7 @@ mod test { #[test] fn symmetric_difference_inverse_of_itself( - a in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary() ) { prop_assert_eq!( @@ -1031,8 +1029,8 @@ mod test { #[test] fn symmetric_difference_relative_compliments( - a in RoaringBitmap::arbitrary(), - b in RoaringBitmap::arbitrary() + a in Roaring32::arbitrary(), + b in Roaring32::arbitrary() ) { prop_assert_eq!( @@ -1111,7 +1109,7 @@ mod test { } } - fn empty_set() -> RoaringBitmap { - RoaringBitmap::new() + fn empty_set() -> Roaring32 { + Roaring32::new() } } diff --git a/src/bitmap/serde.rs b/src/core/serde.rs similarity index 72% rename from src/bitmap/serde.rs rename to src/core/serde.rs index f2d1d5ba0..22e97120e 100644 --- a/src/bitmap/serde.rs +++ b/src/core/serde.rs @@ -1,26 +1,27 @@ -use serde::de::SeqAccess; -use serde::de::Visitor; -use serde::Deserialize; -use serde::Deserializer; -use serde::Serialize; +use crate::{RoaringBitmap, Value}; +use serde::{ + de::{SeqAccess, Visitor}, + Deserialize, Deserializer, Serialize, +}; +use std::marker::PhantomData; -use crate::RoaringBitmap; - -impl<'de> Deserialize<'de> for RoaringBitmap { +impl<'de, V: Value> Deserialize<'de> for RoaringBitmap { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { - struct BitmapVisitor; + struct BitmapVisitor { + value_type: PhantomData, + } - impl<'de> Visitor<'de> for BitmapVisitor { - type Value = RoaringBitmap; + impl<'de, V: Value> Visitor<'de> for BitmapVisitor { + type Value = RoaringBitmap; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("roaring bitmap") } - fn visit_bytes(self, bytes: &[u8]) -> Result + fn visit_bytes(self, bytes: &[u8]) -> Result, E> where E: serde::de::Error, { @@ -29,7 +30,7 @@ impl<'de> Deserialize<'de> for RoaringBitmap { // in some case bytes will be serialized as a sequence thus we need to accept both // even if it means non optimal performance - fn visit_seq(self, mut seq: A) -> Result + fn visit_seq(self, mut seq: A) -> Result, A::Error> where A: SeqAccess<'de>, { @@ -41,11 +42,11 @@ impl<'de> Deserialize<'de> for RoaringBitmap { } } - deserializer.deserialize_bytes(BitmapVisitor) + deserializer.deserialize_bytes(BitmapVisitor { value_type: PhantomData }) } } -impl Serialize for RoaringBitmap { +impl Serialize for RoaringBitmap { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, @@ -59,13 +60,13 @@ impl Serialize for RoaringBitmap { #[cfg(test)] mod test { - use crate::RoaringBitmap; + use crate::Roaring32; use proptest::prelude::*; proptest! { #[test] fn test_serde_json( - bitmap in RoaringBitmap::arbitrary(), + bitmap in Roaring32::arbitrary() ) { let json = serde_json::to_vec(&bitmap).unwrap(); prop_assert_eq!(bitmap, serde_json::from_slice(&json).unwrap()); @@ -73,7 +74,7 @@ mod test { #[test] fn test_bincode( - bitmap in RoaringBitmap::arbitrary(), + bitmap in Roaring32::arbitrary() ) { let buffer = bincode::serialize(&bitmap).unwrap(); prop_assert_eq!(bitmap, bincode::deserialize(&buffer).unwrap()); diff --git a/src/bitmap/serialization.rs b/src/core/serialization.rs similarity index 73% rename from src/bitmap/serialization.rs rename to src/core/serialization.rs index 6ae84df41..e044b45be 100644 --- a/src/bitmap/serialization.rs +++ b/src/core/serialization.rs @@ -1,35 +1,35 @@ +use super::{ + container::{Container, ARRAY_LIMIT}, + store::{ArrayStore, BitmapStore, Store, BITMAP_LENGTH}, +}; +use crate::{ContainerKey, RoaringBitmap, Value}; use bytemuck::cast_slice_mut; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; -use std::convert::{Infallible, TryFrom}; -use std::error::Error; -use std::io; -use std::ops::RangeInclusive; - -use crate::bitmap::container::{Container, ARRAY_LIMIT}; -use crate::bitmap::store::{ArrayStore, BitmapStore, Store, BITMAP_LENGTH}; -use crate::RoaringBitmap; +use std::{ + convert::{Infallible, TryFrom}, + error::Error, + io, mem, + ops::RangeInclusive, +}; +const COOKIE_HEADER_SIZE: usize = 8; // In bytes. const SERIAL_COOKIE_NO_RUNCONTAINER: u32 = 12346; const SERIAL_COOKIE: u16 = 12347; const NO_OFFSET_THRESHOLD: usize = 4; -// Sizes of header structures -const DESCRIPTION_BYTES: usize = 4; -const OFFSET_BYTES: usize = 4; - -impl RoaringBitmap { +impl RoaringBitmap { /// Return the size in bytes of the serialized output. /// This is compatible with the official C/C++, Java and Go implementations. /// /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let rb1: RoaringBitmap = (1..4).collect(); + /// let rb1: Roaring32 = (1..4).collect(); /// let mut bytes = Vec::with_capacity(rb1.serialized_size()); /// rb1.serialize_into(&mut bytes).unwrap(); - /// let rb2 = RoaringBitmap::deserialize_from(&bytes[..]).unwrap(); + /// let rb2 = Roaring32::deserialize_from(&bytes[..]).unwrap(); /// /// assert_eq!(rb1, rb2); /// ``` @@ -37,14 +37,25 @@ impl RoaringBitmap { let container_sizes: usize = self .containers .iter() - .map(|container| match container.store { - Store::Array(ref values) => 8 + values.len() as usize * 2, - Store::Bitmap(..) => 8 + 8 * 1024, + .map(|container| { + // Descriptive header: key + cardinality. + let key_size = V::Key::size(); + let card_size = mem::size_of::(); + // Offset header. + let offset_size = mem::size_of::(); + + key_size + + card_size + + offset_size + + match container.store { + Store::Array(ref values) => values.len() as usize * mem::size_of::(), + Store::Bitmap(..) => 1024 * mem::size_of::(), + } }) .sum(); - // header + container sizes - 8 + container_sizes + // Cookie header + container sizes + COOKIE_HEADER_SIZE + container_sizes } /// Serialize this bitmap into [the standard Roaring on-disk format][format]. @@ -55,12 +66,12 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let rb1: RoaringBitmap = (1..4).collect(); + /// let rb1: Roaring32 = (1..4).collect(); /// let mut bytes = vec![]; /// rb1.serialize_into(&mut bytes).unwrap(); - /// let rb2 = RoaringBitmap::deserialize_from(&bytes[..]).unwrap(); + /// let rb2 = Roaring32::deserialize_from(&bytes[..]).unwrap(); /// /// assert_eq!(rb1, rb2); /// ``` @@ -69,19 +80,26 @@ impl RoaringBitmap { writer.write_u32::(self.containers.len() as u32)?; for container in &self.containers { - writer.write_u16::(container.key)?; + container.key.write(&mut writer)?; writer.write_u16::((container.len() - 1) as u16)?; } - let mut offset = 8 + 8 * self.containers.len() as u32; + // Descriptive header: key + cardinality. + let key_size = V::Key::size(); + let card_size = mem::size_of::(); + // Offset header. + let offset_size = mem::size_of::(); + + let mut offset = + COOKIE_HEADER_SIZE + (key_size + card_size + offset_size) * self.containers.len(); for container in &self.containers { - writer.write_u32::(offset)?; + writer.write_u32::(offset as u32)?; match container.store { Store::Array(ref values) => { - offset += values.len() as u32 * 2; + offset += values.len() as usize * mem::size_of::(); } Store::Bitmap(..) => { - offset += 8 * 1024; + offset += 1024 * mem::size_of::(); } } } @@ -115,16 +133,16 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let rb1: RoaringBitmap = (1..4).collect(); + /// let rb1: Roaring32 = (1..4).collect(); /// let mut bytes = vec![]; /// rb1.serialize_into(&mut bytes).unwrap(); - /// let rb2 = RoaringBitmap::deserialize_from(&bytes[..]).unwrap(); + /// let rb2 = Roaring32::deserialize_from(&bytes[..]).unwrap(); /// /// assert_eq!(rb1, rb2); /// ``` - pub fn deserialize_from(reader: R) -> io::Result { + pub fn deserialize_from(reader: R) -> io::Result> { RoaringBitmap::deserialize_from_impl(reader, ArrayStore::try_from, BitmapStore::try_from) } @@ -138,16 +156,16 @@ impl RoaringBitmap { /// # Examples /// /// ```rust - /// use roaring::RoaringBitmap; + /// use roaring::Roaring32; /// - /// let rb1: RoaringBitmap = (1..4).collect(); + /// let rb1: Roaring32 = (1..4).collect(); /// let mut bytes = vec![]; /// rb1.serialize_into(&mut bytes).unwrap(); - /// let rb2 = RoaringBitmap::deserialize_unchecked_from(&bytes[..]).unwrap(); + /// let rb2 = Roaring32::deserialize_unchecked_from(&bytes[..]).unwrap(); /// /// assert_eq!(rb1, rb2); /// ``` - pub fn deserialize_unchecked_from(reader: R) -> io::Result { + pub fn deserialize_unchecked_from(reader: R) -> io::Result> { RoaringBitmap::deserialize_from_impl::( reader, |values| Ok(ArrayStore::from_vec_unchecked(values)), @@ -159,7 +177,7 @@ impl RoaringBitmap { mut reader: R, a: A, b: B, - ) -> io::Result + ) -> io::Result> where R: io::Read, A: Fn(Vec) -> Result, @@ -189,17 +207,19 @@ impl RoaringBitmap { None }; - if size > u16::MAX as usize + 1 { + if size > V::max_containers() { return Err(io::Error::new(io::ErrorKind::Other, "size is greater than supported")); } // Read the container descriptions - let mut description_bytes = vec![0u8; size * DESCRIPTION_BYTES]; + let key_size = V::Key::size(); + let card_size = mem::size_of::(); + let mut description_bytes = vec![0u8; size * (key_size + card_size)]; reader.read_exact(&mut description_bytes)?; let mut description_bytes = &description_bytes[..]; if has_offsets { - let mut offsets = vec![0u8; size * OFFSET_BYTES]; + let mut offsets = vec![0u8; size * mem::size_of::()]; reader.read_exact(&mut offsets)?; drop(offsets); // Not useful when deserializing into memory } @@ -208,7 +228,7 @@ impl RoaringBitmap { // Read each container for i in 0..size { - let key = description_bytes.read_u16::()?; + let key = ::read(&mut description_bytes)?; let cardinality = u64::from(description_bytes.read_u16::()?) + 1; // If the run container bitmap is present, check if this container is a run container @@ -254,17 +274,15 @@ impl RoaringBitmap { #[cfg(test)] mod test { - use crate::RoaringBitmap; + use crate::Roaring32; use proptest::prelude::*; proptest! { #[test] - fn test_serialization( - bitmap in RoaringBitmap::arbitrary(), - ) { + fn test_serialization(bitmap in Roaring32::arbitrary()) { let mut buffer = Vec::new(); bitmap.serialize_into(&mut buffer).unwrap(); - prop_assert_eq!(bitmap, RoaringBitmap::deserialize_from(buffer.as_slice()).unwrap()); + prop_assert_eq!(bitmap, Roaring32::deserialize_from(buffer.as_slice()).unwrap()); } } } diff --git a/src/bitmap/store/array_store/mod.rs b/src/core/store/array_store/mod.rs similarity index 99% rename from src/bitmap/store/array_store/mod.rs rename to src/core/store/array_store/mod.rs index a121c1038..18802174c 100644 --- a/src/bitmap/store/array_store/mod.rs +++ b/src/core/store/array_store/mod.rs @@ -2,15 +2,14 @@ mod scalar; mod vector; mod visitor; -use crate::bitmap::store::array_store::visitor::{CardinalityCounter, VecWriter}; +use super::array_store::visitor::{CardinalityCounter, VecWriter}; +use super::bitmap_store::{bit, key, BitmapStore, BITMAP_LENGTH}; use std::cmp::Ordering; use std::cmp::Ordering::*; use std::convert::{TryFrom, TryInto}; use std::fmt::{Display, Formatter}; use std::ops::{BitAnd, BitAndAssign, BitOr, BitXor, RangeInclusive, Sub, SubAssign}; -use super::bitmap_store::{bit, key, BitmapStore, BITMAP_LENGTH}; - #[derive(Clone, Eq, PartialEq)] pub struct ArrayStore { vec: Vec, @@ -408,7 +407,7 @@ impl BitXor for &ArrayStore { #[cfg(test)] mod tests { use super::*; - use crate::bitmap::store::Store; + use crate::core::store::Store; fn into_vec(s: Store) -> Vec { match s { diff --git a/src/bitmap/store/array_store/scalar.rs b/src/core/store/array_store/scalar.rs similarity index 97% rename from src/bitmap/store/array_store/scalar.rs rename to src/core/store/array_store/scalar.rs index 455afdae6..e2b61f690 100644 --- a/src/bitmap/store/array_store/scalar.rs +++ b/src/core/store/array_store/scalar.rs @@ -1,6 +1,6 @@ //! Scalar arithmetic binary set operations on `ArrayStore`'s inner types -use crate::bitmap::store::array_store::visitor::BinaryOperationVisitor; +use super::visitor::BinaryOperationVisitor; use std::cmp::Ordering::*; #[inline] diff --git a/src/bitmap/store/array_store/vector.rs b/src/core/store/array_store/vector.rs similarity index 99% rename from src/bitmap/store/array_store/vector.rs rename to src/core/store/array_store/vector.rs index 14f3f0359..74c9604ad 100644 --- a/src/bitmap/store/array_store/vector.rs +++ b/src/core/store/array_store/vector.rs @@ -444,7 +444,7 @@ fn matrix_cmp_u16(a: Simd, b: Simd) -> Mask { | a.simd_eq(b.rotate_lanes_left::<7>()) } -use crate::bitmap::store::array_store::visitor::BinaryOperationVisitor; +use crate::core::store::array_store::visitor::BinaryOperationVisitor; use core::simd::{Swizzle2, Which, Which::First as A, Which::Second as B}; /// Append to vectors to an imaginary 16 lane vector, shift the lanes right by 1, then diff --git a/src/bitmap/store/array_store/visitor.rs b/src/core/store/array_store/visitor.rs similarity index 97% rename from src/bitmap/store/array_store/visitor.rs rename to src/core/store/array_store/visitor.rs index 5ee84b324..6757cfaea 100644 --- a/src/bitmap/store/array_store/visitor.rs +++ b/src/core/store/array_store/visitor.rs @@ -1,5 +1,5 @@ #[cfg(feature = "simd")] -use crate::bitmap::store::array_store::vector::swizzle_to_front; +use crate::core::store::array_store::vector::swizzle_to_front; /// This visitor pattern allows multiple different algorithms to be written over the same data /// For example: vectorized algorithms can pass a visitor off to a scalar algorithm to finish off diff --git a/src/bitmap/store/bitmap_store.rs b/src/core/store/bitmap_store.rs similarity index 99% rename from src/bitmap/store/bitmap_store.rs rename to src/core/store/bitmap_store.rs index e1e332bd4..b608578dd 100644 --- a/src/bitmap/store/bitmap_store.rs +++ b/src/core/store/bitmap_store.rs @@ -385,7 +385,7 @@ impl Display for Error { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self.kind { ErrorKind::Cardinality { expected, actual } => { - write!(f, "Expected cardinality was {} but was {}", expected, actual) + write!(f, "Expected cardinality was {expected} but was {actual}") } } } diff --git a/src/bitmap/store/mod.rs b/src/core/store/mod.rs similarity index 99% rename from src/bitmap/store/mod.rs rename to src/core/store/mod.rs index b3ff3e53b..cb0330316 100644 --- a/src/bitmap/store/mod.rs +++ b/src/core/store/mod.rs @@ -13,7 +13,7 @@ use self::Store::{Array, Bitmap}; pub use self::array_store::ArrayStore; pub use self::bitmap_store::{BitmapIter, BitmapStore}; -use crate::bitmap::container::ARRAY_LIMIT; +use crate::core::container::ARRAY_LIMIT; #[derive(Clone)] pub enum Store { diff --git a/src/lib.rs b/src/lib.rs index e87e4fdda..cd9333c05 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,14 +18,18 @@ extern crate byteorder; use std::error::Error; use std::fmt; -/// A compressed bitmap using the [Roaring bitmap compression scheme](https://roaringbitmap.org/). -pub mod bitmap; +mod core; /// A compressed bitmap with u64 values. Implemented as a `BTreeMap` of `RoaringBitmap`s. -pub mod treemap; +// pub mod treemap; +// pub use treemap::RoaringTreemap; +mod value; +pub use value::{ContainerKey, Value, ValueRange}; -pub use bitmap::RoaringBitmap; -pub use treemap::RoaringTreemap; +mod roaring32; +pub use roaring32::Roaring32; + +pub use self::core::RoaringBitmap; /// An error type that is returned when an iterator isn't sorted. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -48,7 +52,7 @@ impl fmt::Display for NonSortedIntegers { impl Error for NonSortedIntegers {} -/// A [`Iterator::collect`] blanket implementation that provides extra methods for [`RoaringBitmap`] +/// A [`Iterator::collect`] blanket implementation that provides extra methods for [`Roaring32`] /// and [`RoaringTreemap`]. /// /// When merging multiple bitmap with the same operation it's usually faster to call the @@ -56,12 +60,12 @@ impl Error for NonSortedIntegers {} /// /// # Examples /// ``` -/// use roaring::{MultiOps, RoaringBitmap}; +/// use roaring::{MultiOps, Roaring32}; /// /// let bitmaps = [ -/// RoaringBitmap::from_iter(0..10), -/// RoaringBitmap::from_iter(10..20), -/// RoaringBitmap::from_iter(20..30), +/// Roaring32::from_iter(0..10), +/// Roaring32::from_iter(10..20), +/// Roaring32::from_iter(20..30), /// ]; /// /// // Stop doing this diff --git a/src/roaring32.rs b/src/roaring32.rs new file mode 100644 index 000000000..7133380ae --- /dev/null +++ b/src/roaring32.rs @@ -0,0 +1,147 @@ +use crate::{ContainerKey, RoaringBitmap, Value, ValueRange}; +use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; +use std::{ + io, + ops::{Bound, RangeBounds, RangeInclusive}, +}; + +/// A compressed bitmap for 32-bit values. +/// +/// # Examples +/// +/// ```rust +/// use roaring::Roaring32; +/// +/// let mut rb = Roaring32::new(); +/// +/// // insert all primes less than 10 +/// rb.insert(2); +/// rb.insert(3); +/// rb.insert(5); +/// rb.insert(7); +/// println!("total bits set to true: {}", rb.len()); +/// ``` +pub type Roaring32 = RoaringBitmap; + +impl Value for u32 { + type Key = u16; + type Range = RangeInclusive; + + fn split(self) -> (Self::Key, u16) { + ((self >> 16) as Self::Key, self as u16) + } + + fn join(key: Self::Key, index: u16) -> Self { + (u32::from(key) << 16) + u32::from(index) + } + + fn range(range: impl RangeBounds) -> Option { + let start: u32 = match range.start_bound() { + Bound::Included(&i) => i, + Bound::Excluded(&i) => i.checked_add(1)?, + Bound::Unbounded => 0, + }; + let end: u32 = match range.end_bound() { + Bound::Included(&i) => i, + Bound::Excluded(&i) => i.checked_sub(1)?, + Bound::Unbounded => u32::MAX, + }; + + if end < start { + return None; + } + + Some(start..=end) + } + + fn max_containers() -> usize { + usize::from(Self::Key::MAX) + 1 + } +} + +impl ContainerKey for u16 { + #[inline(always)] + fn size() -> usize { + std::mem::size_of::() + } + + fn write(self, writer: &mut impl WriteBytesExt) -> io::Result<()> { + writer.write_u16::(self) + } + + fn read(reader: &mut impl ReadBytesExt) -> io::Result { + reader.read_u16::() + } +} + +impl ValueRange for RangeInclusive { + type KeyIterator = RangeInclusive; + + fn start(&self) -> (::Key, u16) { + self.start().split() + } + + fn end(&self) -> (::Key, u16) { + self.end().split() + } + + fn containers_count(&self) -> usize { + let start = ValueRange::start(self).0; + let end = ValueRange::end(self).0; + (end - start) as usize + 1 + } + + fn keys(self) -> Self::KeyIterator { + let start = ValueRange::start(&self).0; + let end = ValueRange::end(&self).0; + start..=end + } +} + +#[cfg(test)] +mod test { + use super::*; + use std::ops::Bound; + + #[test] + fn split() { + assert_eq!((0x0000u16, 0x0000u16), 0x0000_0000u32.split()); + assert_eq!((0x0000u16, 0x0001u16), 0x0000_0001u32.split()); + assert_eq!((0x0000u16, 0xFFFEu16), 0x0000_FFFEu32.split()); + assert_eq!((0x0000u16, 0xFFFFu16), 0x0000_FFFFu32.split()); + assert_eq!((0x0001u16, 0x0000u16), 0x0001_0000u32.split()); + assert_eq!((0x0001u16, 0x0001u16), 0x0001_0001u32.split()); + assert_eq!((0xFFFFu16, 0xFFFEu16), 0xFFFF_FFFEu32.split()); + assert_eq!((0xFFFFu16, 0xFFFFu16), 0xFFFF_FFFFu32.split()); + } + + #[test] + fn join() { + assert_eq!(0x0000_0000u32, u32::join(0x0000u16, 0x0000u16)); + assert_eq!(0x0000_0001u32, u32::join(0x0000u16, 0x0001u16)); + assert_eq!(0x0000_FFFEu32, u32::join(0x0000u16, 0xFFFEu16)); + assert_eq!(0x0000_FFFFu32, u32::join(0x0000u16, 0xFFFFu16)); + assert_eq!(0x0001_0000u32, u32::join(0x0001u16, 0x0000u16)); + assert_eq!(0x0001_0001u32, u32::join(0x0001u16, 0x0001u16)); + assert_eq!(0xFFFF_FFFEu32, u32::join(0xFFFFu16, 0xFFFEu16)); + assert_eq!(0xFFFF_FFFFu32, u32::join(0xFFFFu16, 0xFFFFu16)); + } + + #[test] + #[allow(clippy::reversed_empty_ranges)] + fn range() { + assert_eq!(Some(1..=5), u32::range(1..6)); + assert_eq!(Some(1..=u32::MAX), u32::range(1..)); + assert_eq!(Some(0..=u32::MAX), u32::range(..)); + assert_eq!(Some(16..=16), u32::range(16..=16)); + assert_eq!(Some(11..=19), u32::range((Bound::Excluded(10), Bound::Excluded(20)))); + + assert_eq!(None, u32::range(0..0)); + assert_eq!(None, u32::range(5..5)); + assert_eq!(None, u32::range(1..0)); + assert_eq!(None, u32::range(10..5)); + assert_eq!(None, u32::range((Bound::Excluded(u32::MAX), Bound::Included(u32::MAX)))); + assert_eq!(None, u32::range((Bound::Excluded(u32::MAX), Bound::Included(u32::MAX)))); + assert_eq!(None, u32::range((Bound::Excluded(0), Bound::Included(0)))); + } +} diff --git a/src/value.rs b/src/value.rs new file mode 100644 index 000000000..e0b3bd2b6 --- /dev/null +++ b/src/value.rs @@ -0,0 +1,54 @@ +use byteorder::{ReadBytesExt, WriteBytesExt}; +use std::{fmt, io, ops::RangeBounds}; + +/// A Roaring Bitmap value. +/// +/// Internally, a value is split into a container key and a container index. +pub trait Value: fmt::Debug + Copy + Ord + Into { + /// Type for the container key. + type Key: ContainerKey; + /// Type for a range of values. + type Range: ValueRange; + + /// Splits the values into a (key, index) pair. + fn split(self) -> (Self::Key, u16); + + /// Returns the original value from a (key, index) pair. + fn join(key: Self::Key, index: u16) -> Self; + + /// Returns a range of value from the givem bounds. + fn range(range: impl RangeBounds) -> Option; + + /// Return the number of containers used to cover every possible values. + fn max_containers() -> usize; +} + +/// Key for a Roaring Bitmap container. +pub trait ContainerKey: fmt::Debug + Copy + Ord { + /// Returns the size (in byte) of the key. + fn size() -> usize; + + /// Writes the container key to the given writer. + fn write(self, writer: &mut impl WriteBytesExt) -> io::Result<()>; + + /// Reads the container key from the given reader. + fn read(reader: &mut impl ReadBytesExt) -> io::Result; +} + +/// A range of value to insert. +pub trait ValueRange { + /// Iterator over the keys covered by the values. + type KeyIterator: Iterator; + + /// Returns the start of the value range. + fn start(&self) -> (K, u16); + + /// Returns the end of the value range. + fn end(&self) -> (K, u16); + + /// Returns the number of containers covered by the range. + fn containers_count(&self) -> usize; + + /// Returns an iterator over the container keys. + fn keys(self) -> Self::KeyIterator; +} diff --git a/tests/clone.rs b/tests/clone.rs index 9c485b44a..a027d772e 100644 --- a/tests/clone.rs +++ b/tests/clone.rs @@ -1,10 +1,9 @@ -extern crate roaring; -use roaring::RoaringBitmap; +use roaring::Roaring32; #[test] #[allow(clippy::redundant_clone)] fn array() { - let original = (0..2000).collect::(); + let original = (0..2000).collect::(); let clone = original.clone(); assert_eq!(clone, original); @@ -13,7 +12,7 @@ fn array() { #[test] #[allow(clippy::redundant_clone)] fn bitmap() { - let original = (0..6000).collect::(); + let original = (0..6000).collect::(); let clone = original.clone(); assert_eq!(clone, original); @@ -22,10 +21,8 @@ fn bitmap() { #[test] #[allow(clippy::redundant_clone)] fn arrays() { - let original = (0..2000) - .chain(1_000_000..1_002_000) - .chain(2_000_000..2_001_000) - .collect::(); + let original = + (0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000).collect::(); let clone = original.clone(); assert_eq!(clone, original); @@ -34,10 +31,8 @@ fn arrays() { #[test] #[allow(clippy::redundant_clone)] fn bitmaps() { - let original = (0..6000) - .chain(1_000_000..1_012_000) - .chain(2_000_000..2_010_000) - .collect::(); + let original = + (0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000).collect::(); let clone = original.clone(); assert_eq!(clone, original); diff --git a/tests/difference_with.rs b/tests/difference_with.rs index a3b6743f7..2c156b1e1 100644 --- a/tests/difference_with.rs +++ b/tests/difference_with.rs @@ -1,11 +1,10 @@ -extern crate roaring; -use roaring::RoaringBitmap; +use roaring::Roaring32; #[test] fn array() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..3000).collect::(); - let bitmap3 = (0..1000).collect::(); + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..3000).collect::(); + let bitmap3 = (0..1000).collect::(); bitmap1 -= bitmap2; @@ -14,19 +13,19 @@ fn array() { #[test] fn no_difference() { - let mut bitmap1 = (1..3).collect::(); - let bitmap2 = (1..3).collect::(); + let mut bitmap1 = (1..3).collect::(); + let bitmap2 = (1..3).collect::(); bitmap1 -= bitmap2; - assert_eq!(bitmap1, RoaringBitmap::new()); + assert_eq!(bitmap1, Roaring32::new()); } #[test] fn array_and_bitmap() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..8000).collect::(); - let bitmap3 = (0..1000).collect::(); + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..8000).collect::(); + let bitmap3 = (0..1000).collect::(); bitmap1 -= bitmap2; @@ -35,9 +34,9 @@ fn array_and_bitmap() { #[test] fn bitmap_to_bitmap() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (6000..18000).collect::(); - let bitmap3 = (0..6000).collect::(); + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (6000..18000).collect::(); + let bitmap3 = (0..6000).collect::(); bitmap1 -= bitmap2; @@ -46,9 +45,9 @@ fn bitmap_to_bitmap() { #[test] fn bitmap_to_array() { - let mut bitmap1 = (0..6000).collect::(); - let bitmap2 = (3000..9000).collect::(); - let bitmap3 = (0..3000).collect::(); + let mut bitmap1 = (0..6000).collect::(); + let bitmap2 = (3000..9000).collect::(); + let bitmap3 = (0..3000).collect::(); bitmap1 -= bitmap2; @@ -57,9 +56,9 @@ fn bitmap_to_array() { #[test] fn bitmap_and_array_to_bitmap() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (9000..12000).collect::(); - let bitmap3 = (0..9000).collect::(); + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (9000..12000).collect::(); + let bitmap3 = (0..9000).collect::(); bitmap1 -= bitmap2; @@ -68,9 +67,9 @@ fn bitmap_and_array_to_bitmap() { #[test] fn bitmap_and_array_to_array() { - let mut bitmap1 = (0..6000).collect::(); - let bitmap2 = (3000..6000).collect::(); - let bitmap3 = (0..3000).collect::(); + let mut bitmap1 = (0..6000).collect::(); + let bitmap2 = (3000..6000).collect::(); + let bitmap3 = (0..3000).collect::(); bitmap1 -= bitmap2; @@ -79,15 +78,11 @@ fn bitmap_and_array_to_array() { #[test] fn arrays() { - let mut bitmap1 = (0..2000) - .chain(1_000_000..1_002_000) - .chain(2_000_000..2_001_000) - .collect::(); - let bitmap2 = (1000..3000) - .chain(1_001_000..1_003_000) - .chain(2_000_000..2_001_000) - .collect::(); - let bitmap3 = (0..1000).chain(1_000_000..1_001_000).collect::(); + let mut bitmap1 = + (0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000).collect::(); + let bitmap2 = + (1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000).collect::(); + let bitmap3 = (0..1000).chain(1_000_000..1_001_000).collect::(); bitmap1 -= bitmap2; @@ -96,15 +91,11 @@ fn arrays() { #[test] fn arrays_removing_one_whole_container() { - let mut bitmap1 = (0..2000) - .chain(1_000_000..1_002_000) - .chain(2_000_000..2_001_000) - .collect::(); - let bitmap2 = (0..3000) - .chain(1_001_000..1_003_000) - .chain(2_000_000..2_001_000) - .collect::(); - let bitmap3 = (1_000_000..1_001_000).collect::(); + let mut bitmap1 = + (0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000).collect::(); + let bitmap2 = + (0..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000).collect::(); + let bitmap3 = (1_000_000..1_001_000).collect::(); bitmap1 -= bitmap2; @@ -113,15 +104,11 @@ fn arrays_removing_one_whole_container() { #[test] fn bitmaps() { - let mut bitmap1 = (0..6000) - .chain(1_000_000..1_012_000) - .chain(2_000_000..2_010_000) - .collect::(); - let bitmap2 = (3000..9000) - .chain(1_006_000..1_018_000) - .chain(2_000_000..2_010_000) - .collect::(); - let bitmap3 = (0..3000).chain(1_000_000..1_006_000).collect::(); + let mut bitmap1 = + (0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000).collect::(); + let bitmap2 = + (3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000).collect::(); + let bitmap3 = (0..3000).chain(1_000_000..1_006_000).collect::(); bitmap1 -= bitmap2; diff --git a/tests/intersect_with.rs b/tests/intersect_with.rs index 2f3296b1c..e65ddd1b4 100644 --- a/tests/intersect_with.rs +++ b/tests/intersect_with.rs @@ -1,11 +1,10 @@ -extern crate roaring; -use roaring::RoaringBitmap; +use roaring::Roaring32; #[test] fn array() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..3000).collect::(); - let bitmap3 = (1000..2000).collect::(); + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..3000).collect::(); + let bitmap3 = (1000..2000).collect::(); bitmap1 &= bitmap2; @@ -14,19 +13,19 @@ fn array() { #[test] fn no_intersection() { - let mut bitmap1 = (0..2).collect::(); - let bitmap2 = (3..4).collect::(); + let mut bitmap1 = (0..2).collect::(); + let bitmap2 = (3..4).collect::(); bitmap1 &= bitmap2; - assert_eq!(bitmap1, RoaringBitmap::new()); + assert_eq!(bitmap1, Roaring32::new()); } #[test] fn array_and_bitmap() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..8000).collect::(); - let bitmap3 = (1000..2000).collect::(); + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..8000).collect::(); + let bitmap3 = (1000..2000).collect::(); bitmap1 &= bitmap2; @@ -35,9 +34,9 @@ fn array_and_bitmap() { #[test] fn bitmap_to_bitmap() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (6000..18000).collect::(); - let bitmap3 = (6000..12000).collect::(); + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (6000..18000).collect::(); + let bitmap3 = (6000..12000).collect::(); bitmap1 &= bitmap2; @@ -46,9 +45,9 @@ fn bitmap_to_bitmap() { #[test] fn bitmap_to_array() { - let mut bitmap1 = (0..6000).collect::(); - let bitmap2 = (3000..9000).collect::(); - let bitmap3 = (3000..6000).collect::(); + let mut bitmap1 = (0..6000).collect::(); + let bitmap2 = (3000..9000).collect::(); + let bitmap3 = (3000..6000).collect::(); bitmap1 &= bitmap2; @@ -57,9 +56,9 @@ fn bitmap_to_array() { #[test] fn bitmap_and_array() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (7000..9000).collect::(); - let bitmap3 = (7000..9000).collect::(); + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (7000..9000).collect::(); + let bitmap3 = (7000..9000).collect::(); bitmap1 &= bitmap2; @@ -68,15 +67,11 @@ fn bitmap_and_array() { #[test] fn arrays() { - let mut bitmap1 = (0..2000) - .chain(1_000_000..1_002_000) - .chain(3_000_000..3_001_000) - .collect::(); - let bitmap2 = (1000..3000) - .chain(1_001_000..1_003_000) - .chain(2_000_000..2_001_000) - .collect::(); - let bitmap3 = (1000..2000).chain(1_001_000..1_002_000).collect::(); + let mut bitmap1 = + (0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000).collect::(); + let bitmap2 = + (1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000).collect::(); + let bitmap3 = (1000..2000).chain(1_001_000..1_002_000).collect::(); bitmap1 &= bitmap2; @@ -85,15 +80,11 @@ fn arrays() { #[test] fn bitmaps() { - let mut bitmap1 = (0..6000) - .chain(1_000_000..1_012_000) - .chain(3_000_000..3_010_000) - .collect::(); - let bitmap2 = (3000..9000) - .chain(1_006_000..1_018_000) - .chain(2_000_000..2_010_000) - .collect::(); - let bitmap3 = (3000..6000).chain(1_006_000..1_012_000).collect::(); + let mut bitmap1 = + (0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000).collect::(); + let bitmap2 = + (3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000).collect::(); + let bitmap3 = (3000..6000).chain(1_006_000..1_012_000).collect::(); bitmap1 &= bitmap2; diff --git a/tests/is_disjoint.rs b/tests/is_disjoint.rs index 51a22d02f..9ef3e2de4 100644 --- a/tests/is_disjoint.rs +++ b/tests/is_disjoint.rs @@ -1,70 +1,61 @@ -extern crate roaring; -use roaring::RoaringBitmap; +use roaring::Roaring32; #[test] fn array() { - let bitmap1 = (0..2000).collect::(); - let bitmap2 = (4000..6000).collect::(); + let bitmap1 = (0..2000).collect::(); + let bitmap2 = (4000..6000).collect::(); assert!(bitmap1.is_disjoint(&bitmap2)); } #[test] fn array_not() { - let bitmap1 = (0..4000).collect::(); - let bitmap2 = (2000..6000).collect::(); + let bitmap1 = (0..4000).collect::(); + let bitmap2 = (2000..6000).collect::(); assert!(!bitmap1.is_disjoint(&bitmap2)); } #[test] fn bitmap() { - let bitmap1 = (0..6000).collect::(); - let bitmap2 = (10000..16000).collect::(); + let bitmap1 = (0..6000).collect::(); + let bitmap2 = (10000..16000).collect::(); assert!(bitmap1.is_disjoint(&bitmap2)); } #[test] fn bitmap_not() { - let bitmap1 = (0..10000).collect::(); - let bitmap2 = (5000..15000).collect::(); + let bitmap1 = (0..10000).collect::(); + let bitmap2 = (5000..15000).collect::(); assert!(!bitmap1.is_disjoint(&bitmap2)); } #[test] fn arrays() { - let bitmap1 = (0..2000) - .chain(1_000_000..1_002_000) - .chain(2_000_000..2_002_000) - .collect::(); - let bitmap2 = (100_000..102_000).chain(1_100_000..1_102_000).collect::(); + let bitmap1 = + (0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_002_000).collect::(); + let bitmap2 = (100_000..102_000).chain(1_100_000..1_102_000).collect::(); assert!(bitmap1.is_disjoint(&bitmap2)); } #[test] fn arrays_not() { - let bitmap1 = (0..2_000) - .chain(1_000_000..1_002_000) - .chain(2_000_000..2_002_000) - .collect::(); - let bitmap2 = (100_000..102_000).chain(1_001_000..1_003_000).collect::(); + let bitmap1 = + (0..2_000).chain(1_000_000..1_002_000).chain(2_000_000..2_002_000).collect::(); + let bitmap2 = (100_000..102_000).chain(1_001_000..1_003_000).collect::(); assert!(!bitmap1.is_disjoint(&bitmap2)); } #[test] fn bitmaps() { - let bitmap1 = (0..6000) - .chain(1_000_000..1_006_000) - .chain(2_000_000..2_006_000) - .collect::(); - let bitmap2 = (100_000..106_000).chain(1_100_000..1_106_000).collect::(); + let bitmap1 = + (0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_006_000).collect::(); + let bitmap2 = (100_000..106_000).chain(1_100_000..1_106_000).collect::(); assert!(bitmap1.is_disjoint(&bitmap2)); } #[test] fn bitmaps_not() { - let bitmap1 = (0..6000) - .chain(1_000_000..1_006_000) - .chain(2_000_000..2_006_000) - .collect::(); - let bitmap2 = (100_000..106_000).chain(1_004_000..1_008_000).collect::(); + let bitmap1 = + (0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_006_000).collect::(); + let bitmap2 = (100_000..106_000).chain(1_004_000..1_008_000).collect::(); assert!(!bitmap1.is_disjoint(&bitmap2)); } diff --git a/tests/is_subset.rs b/tests/is_subset.rs index 1d19ac870..3edbcfe8f 100644 --- a/tests/is_subset.rs +++ b/tests/is_subset.rs @@ -1,82 +1,79 @@ -extern crate roaring; -use roaring::RoaringBitmap; +use roaring::Roaring32; #[test] fn array_not() { - let sup = (0..2000).collect::(); - let sub = (1000..3000).collect::(); + let sup = (0..2000).collect::(); + let sub = (1000..3000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn array() { - let sup = (0..4000).collect::(); - let sub = (2000..3000).collect::(); + let sup = (0..4000).collect::(); + let sub = (2000..3000).collect::(); assert!(sub.is_subset(&sup)); } #[test] fn array_bitmap_not() { - let sup = (0..2000).collect::(); - let sub = (1000..15000).collect::(); + let sup = (0..2000).collect::(); + let sub = (1000..15000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn bitmap_not() { - let sup = (0..6000).collect::(); - let sub = (4000..10000).collect::(); + let sup = (0..6000).collect::(); + let sub = (4000..10000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn bitmap() { - let sup = (0..20000).collect::(); - let sub = (5000..15000).collect::(); + let sup = (0..20000).collect::(); + let sub = (5000..15000).collect::(); assert!(sub.is_subset(&sup)); } #[test] fn bitmap_array_not() { - let sup = (0..20000).collect::(); - let sub = (19000..21000).collect::(); + let sup = (0..20000).collect::(); + let sub = (19000..21000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn bitmap_array() { - let sup = (0..20000).collect::(); - let sub = (18000..20000).collect::(); + let sup = (0..20000).collect::(); + let sub = (18000..20000).collect::(); assert!(sub.is_subset(&sup)); } #[test] fn arrays_not() { - let sup = (0..2000).chain(1_000_000..1_002_000).collect::(); - let sub = (100_000..102_000).chain(1_100_000..1_102_000).collect::(); + let sup = (0..2000).chain(1_000_000..1_002_000).collect::(); + let sub = (100_000..102_000).chain(1_100_000..1_102_000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn arrays() { - let sup = (0..3000).chain(100_000..103_000).collect::(); - let sub = (0..2000).chain(100_000..102_000).collect::(); + let sup = (0..3000).chain(100_000..103_000).collect::(); + let sub = (0..2000).chain(100_000..102_000).collect::(); assert!(sub.is_subset(&sup)); } #[test] fn bitmaps_not() { - let sup = (0..6000) - .chain(1_000_000..1_006_000) - .chain(2_000_000..2_010_000) - .collect::(); - let sub = (100_000..106_000).chain(1_100_000..1_106_000).collect::(); + let sup = + (0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_010_000).collect::(); + let sub = (100_000..106_000).chain(1_100_000..1_106_000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn bitmaps() { - let sup = (0..1_000_000).chain(2_000_000..2_010_000).collect::(); - let sub = (0..10_000).chain(500_000..510_000).collect::(); + let sup = (0..1_000_000).chain(2_000_000..2_010_000).collect::(); + let sub = (0..10_000).chain(500_000..510_000).collect::(); assert!(sub.is_subset(&sup)); } diff --git a/tests/iter.rs b/tests/iter.rs index 14746ea9b..2ad389721 100644 --- a/tests/iter.rs +++ b/tests/iter.rs @@ -1,15 +1,12 @@ -use proptest::arbitrary::any; -use proptest::collection::btree_set; -use proptest::proptest; +use proptest::{arbitrary::any, collection::btree_set, proptest}; +use roaring::Roaring32; use std::iter::FromIterator; -use roaring::RoaringBitmap; - #[test] fn range() { - let original = (0..2000).collect::(); - let clone = RoaringBitmap::from_iter(&original); - let clone2 = RoaringBitmap::from_iter(original.clone()); + let original = (0..2000).collect::(); + let clone = Roaring32::from_iter(&original); + let clone2 = Roaring32::from_iter(original.clone()); assert_eq!(clone, original); assert_eq!(clone2, original); @@ -17,17 +14,17 @@ fn range() { #[test] fn array() { - let original = (0..5).collect::(); - let clone = RoaringBitmap::from([0, 1, 2, 3, 4]); + let original = (0..5).collect::(); + let clone = Roaring32::from([0, 1, 2, 3, 4]); assert_eq!(clone, original); } #[test] fn bitmap() { - let original = (0..100_000).collect::(); - let clone = RoaringBitmap::from_iter(&original); - let clone2 = RoaringBitmap::from_iter(original.clone()); + let original = (0..100_000).collect::(); + let clone = Roaring32::from_iter(&original); + let clone2 = Roaring32::from_iter(original.clone()); assert_eq!(clone, original); assert_eq!(clone2, original); @@ -35,12 +32,10 @@ fn bitmap() { #[test] fn arrays() { - let original = (0..2000) - .chain(1_000_000..1_002_000) - .chain(2_000_000..2_001_000) - .collect::(); - let clone = RoaringBitmap::from_iter(&original); - let clone2 = RoaringBitmap::from_iter(original.clone()); + let original = + (0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000).collect::(); + let clone = Roaring32::from_iter(&original); + let clone2 = Roaring32::from_iter(original.clone()); assert_eq!(clone, original); assert_eq!(clone2, original); @@ -48,12 +43,10 @@ fn arrays() { #[test] fn bitmaps() { - let original = (0..100_000) - .chain(1_000_000..1_012_000) - .chain(2_000_000..2_010_000) - .collect::(); - let clone = RoaringBitmap::from_iter(&original); - let clone2 = RoaringBitmap::from_iter(original.clone()); + let original = + (0..100_000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000).collect::(); + let clone = Roaring32::from_iter(&original); + let clone2 = Roaring32::from_iter(original.clone()); assert_eq!(clone, original); assert_eq!(clone2, original); @@ -62,7 +55,7 @@ fn bitmaps() { proptest! { #[test] fn iter(values in btree_set(any::(), ..=10_000)) { - let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); + let bitmap = Roaring32::from_sorted_iter(values.iter().cloned()).unwrap(); // Iterator::eq != PartialEq::eq - cannot use assert_eq macro assert!(values.into_iter().eq(bitmap)); } @@ -71,7 +64,7 @@ proptest! { #[test] fn rev_array() { let values = 0..100; - let bitmap = values.clone().collect::(); + let bitmap = values.clone().collect::(); assert!(values.into_iter().rev().eq(bitmap.iter().rev())); } @@ -79,7 +72,7 @@ fn rev_array() { #[test] fn rev_bitmap() { let values = 0..=100_000; - let bitmap = values.clone().collect::(); + let bitmap = values.clone().collect::(); assert!(values.into_iter().rev().eq(bitmap.iter().rev())); } @@ -87,7 +80,7 @@ fn rev_bitmap() { proptest! { #[test] fn rev_iter(values in btree_set(any::(), ..=10_000)) { - let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); + let bitmap = Roaring32::from_sorted_iter(values.iter().cloned()).unwrap(); assert!(values.into_iter().rev().eq(bitmap.iter().rev())); } @@ -98,8 +91,8 @@ fn from_iter() { // This test verifies that the public API allows conversion from iterators // with u32 as well as &u32 elements. let vals = vec![1, 5, 10000]; - let a = RoaringBitmap::from_iter(vals.iter()); - let b = RoaringBitmap::from_iter(vals); + let a = Roaring32::from_iter(vals.iter()); + let b = Roaring32::from_iter(vals); assert_eq!(a, b); } @@ -137,7 +130,7 @@ fn outside_in_iterator() { #[test] fn interleaved_array() { let values = 0..100; - let bitmap = values.clone().collect::(); + let bitmap = values.clone().collect::(); assert!(outside_in(values).eq(outside_in(bitmap))); } @@ -145,7 +138,7 @@ fn interleaved_array() { #[test] fn interleaved_bitmap() { let values = 0..=4097; - let bitmap = values.clone().collect::(); + let bitmap = values.clone().collect::(); assert!(outside_in(values).eq(outside_in(bitmap))); } @@ -153,7 +146,7 @@ fn interleaved_bitmap() { proptest! { #[test] fn interleaved_iter(values in btree_set(any::(), 50_000..=100_000)) { - let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); + let bitmap = Roaring32::from_sorted_iter(values.iter().cloned()).unwrap(); assert!(outside_in(values).eq(outside_in(bitmap))); } diff --git a/tests/lib.rs b/tests/lib.rs index 5fcf4a2fc..b09e2e87a 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,9 +1,8 @@ -extern crate roaring; -use roaring::RoaringBitmap; +use roaring::Roaring32; #[test] fn smoke() { - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); assert_eq!(bitmap.len(), 0); assert!(bitmap.is_empty()); bitmap.remove(0); @@ -38,9 +37,9 @@ fn remove_range() { let ranges = [0u32, 1, 63, 64, 65, 100, 4096 - 1, 4096, 4096 + 1, 65536 - 1, 65536, 65536 + 1]; for (i, &a) in ranges.iter().enumerate() { for &b in &ranges[i..] { - let mut bitmap = (0..=65536).collect::(); + let mut bitmap = (0..=65536).collect::(); assert_eq!(bitmap.remove_range(a..b), u64::from(b - a)); - assert_eq!(bitmap, (0..a).chain(b..=65536).collect::()); + assert_eq!(bitmap, (0..a).chain(b..=65536).collect::()); } } } @@ -48,7 +47,7 @@ fn remove_range() { #[test] #[allow(clippy::range_plus_one)] // remove_range needs an exclusive range fn remove_range_array() { - let mut bitmap = (0..1000).collect::(); + let mut bitmap = (0..1000).collect::(); for i in 0..1000 { assert_eq!(bitmap.remove_range(i..i), 0); assert_eq!(bitmap.remove_range(i..i + 1), 1); @@ -56,13 +55,13 @@ fn remove_range_array() { // insert 0, 2, 4, .. // remove [0, 2), [2, 4), .. - let mut bitmap = (0..1000).map(|x| x * 2).collect::(); + let mut bitmap = (0..1000).map(|x| x * 2).collect::(); for i in 0..1000 { assert_eq!(bitmap.remove_range(i * 2..(i + 1) * 2), 1); } // remove [0, 2), [2, 4), .. - let mut bitmap = (0..1000).collect::(); + let mut bitmap = (0..1000).collect::(); for i in 0..1000 / 2 { assert_eq!(bitmap.remove_range(i * 2..(i + 1) * 2), 2); } @@ -71,7 +70,7 @@ fn remove_range_array() { #[test] #[allow(clippy::range_plus_one)] // remove_range needs an exclusive range fn remove_range_bitmap() { - let mut bitmap = (0..4096 + 1000).collect::(); + let mut bitmap = (0..4096 + 1000).collect::(); for i in 0..1000 { assert_eq!(bitmap.remove_range(i..i), 0); assert_eq!(bitmap.remove_range(i..i + 1), 1); @@ -79,19 +78,19 @@ fn remove_range_bitmap() { // insert 0, 2, 4, .. // remove [0, 2), [2, 4), .. - let mut bitmap = ((0..4096 + 1000).map(|x| x * 2)).collect::(); + let mut bitmap = ((0..4096 + 1000).map(|x| x * 2)).collect::(); for i in 0..1000 { assert_eq!(bitmap.remove_range(i * 2..(i + 1) * 2), 1); } // remove [0, 2), [2, 4), .. - let mut bitmap = (0..4096 + 1000).collect::(); + let mut bitmap = (0..4096 + 1000).collect::(); for i in 0..1000 / 2 { assert_eq!(bitmap.remove_range(i * 2..(i + 1) * 2), 2); } // remove [1, 3), [3, 5), .. - let mut bitmap = (0..4096 + 1000).collect::(); + let mut bitmap = (0..4096 + 1000).collect::(); for i in 0..1000 / 2 { assert_eq!(bitmap.remove_range(i * 2 + 1..(i + 1) * 2 + 1), 2); } @@ -99,7 +98,7 @@ fn remove_range_bitmap() { #[test] fn to_bitmap() { - let bitmap = (0..5000).collect::(); + let bitmap = (0..5000).collect::(); assert_eq!(bitmap.len(), 5000); for i in 1..5000 { assert!(bitmap.contains(i)); @@ -109,7 +108,7 @@ fn to_bitmap() { #[test] fn to_array() { - let mut bitmap = (0..5000).collect::(); + let mut bitmap = (0..5000).collect::(); for i in 3000..5000 { bitmap.remove(i); } diff --git a/tests/ops.rs b/tests/ops.rs index a4cb40df1..0c91a85ae 100644 --- a/tests/ops.rs +++ b/tests/ops.rs @@ -1,11 +1,10 @@ -extern crate roaring; -use roaring::RoaringBitmap; +use roaring::Roaring32; #[test] fn or() { - let mut rb1 = (1..4).collect::(); - let rb2 = (3..6).collect::(); - let rb3 = (1..6).collect::(); + let mut rb1 = (1..4).collect::(); + let rb2 = (3..6).collect::(); + let rb3 = (1..6).collect::(); assert_eq!(rb3, &rb1 | &rb2); assert_eq!(rb3, &rb1 | rb2.clone()); @@ -21,9 +20,9 @@ fn or() { #[test] fn and() { - let mut rb1 = (1..4).collect::(); - let rb2 = (3..6).collect::(); - let rb3 = (3..4).collect::(); + let mut rb1 = (1..4).collect::(); + let rb2 = (3..6).collect::(); + let rb3 = (3..4).collect::(); assert_eq!(rb3, &rb1 & &rb2); assert_eq!(rb3, &rb1 & rb2.clone()); @@ -39,9 +38,9 @@ fn and() { #[test] fn sub() { - let mut rb1 = (1..4000).collect::(); - let rb2 = (3..5000).collect::(); - let rb3 = (1..3).collect::(); + let mut rb1 = (1..4000).collect::(); + let rb2 = (3..5000).collect::(); + let rb3 = (1..3).collect::(); assert_eq!(rb3, &rb1 - &rb2); assert_eq!(rb3, &rb1 - rb2.clone()); @@ -57,10 +56,10 @@ fn sub() { #[test] fn xor() { - let mut rb1 = (1..4).collect::(); - let rb2 = (3..6).collect::(); - let rb3 = (1..3).chain(4..6).collect::(); - let rb4 = (0..0).collect::(); + let mut rb1 = (1..4).collect::(); + let rb2 = (3..6).collect::(); + let rb3 = (1..3).chain(4..6).collect::(); + let rb4 = (0..0).collect::(); assert_eq!(rb3, &rb1 ^ &rb2); assert_eq!(rb3, &rb1 ^ rb2.clone()); diff --git a/tests/push.rs b/tests/push.rs index e617c493e..fd3bc98da 100644 --- a/tests/push.rs +++ b/tests/push.rs @@ -1,5 +1,4 @@ -extern crate roaring; -use roaring::{RoaringBitmap, RoaringTreemap}; +use roaring::Roaring32; use std::iter::FromIterator; /// macro created to reduce code duplication @@ -21,18 +20,18 @@ macro_rules! test_from_sorted_iter { #[test] fn append() { - test_from_sorted_iter!((0..1_000_000).map(|x| 13 * x).collect::>(), RoaringBitmap); - test_from_sorted_iter!(vec![1, 2, 4, 5, 7, 8, 9], RoaringBitmap); + test_from_sorted_iter!((0..1_000_000).map(|x| 13 * x).collect::>(), Roaring32); + test_from_sorted_iter!(vec![1, 2, 4, 5, 7, 8, 9], Roaring32); } #[test] fn append_empty() { - assert_eq!(RoaringBitmap::new().append(vec![]), Ok(0u64)) + assert_eq!(Roaring32::new().append(vec![]), Ok(0u64)) } #[test] fn append_error() { - match [100u32].iter().cloned().collect::().append(vec![10, 20, 0]) { + match [100u32].iter().cloned().collect::().append(vec![10, 20, 0]) { Ok(_) => { panic!("The 0th element in the iterator was < the max of the bitmap") } @@ -41,7 +40,7 @@ fn append_error() { } } - match [100u32].iter().cloned().collect::().append(vec![200, 201, 201]) { + match [100u32].iter().cloned().collect::().append(vec![200, 201, 201]) { Ok(_) => { panic!("The 3rd element in the iterator was < 2nd") } @@ -51,8 +50,8 @@ fn append_error() { } } -#[test] -fn append_tree() { - test_from_sorted_iter!((0..1_000_000).map(|x| 13 * x).collect::>(), RoaringTreemap); - test_from_sorted_iter!(vec![1, 2, 4, 5, 7, 8, 9], RoaringTreemap); -} +// #[test] +// fn append_tree() { +// test_from_sorted_iter!((0..1_000_000).map(|x| 13 * x).collect::>(), RoaringTreemap); +// test_from_sorted_iter!(vec![1, 2, 4, 5, 7, 8, 9], RoaringTreemap); +// } diff --git a/tests/range_checks.rs b/tests/range_checks.rs index 7903eed26..603f5846d 100644 --- a/tests/range_checks.rs +++ b/tests/range_checks.rs @@ -1,10 +1,9 @@ -use proptest::collection::hash_set; -use proptest::prelude::*; -use roaring::RoaringBitmap; +use proptest::{collection::hash_set, prelude::*}; +use roaring::Roaring32; #[test] fn u32_max() { - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); bitmap.insert(u32::MAX); assert!(bitmap.contains_range(u32::MAX..=u32::MAX)); assert!(!bitmap.contains_range(u32::MAX - 1..=u32::MAX)); @@ -27,7 +26,7 @@ proptest! { let range = start..end; let inverse_empty_range = (start+len)..start; - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); bitmap.insert_range(range.clone()); assert!(bitmap.contains_range(range.clone())); assert!(bitmap.contains_range(inverse_empty_range.clone())); @@ -54,7 +53,7 @@ proptest! { start in 1..=262_143_u32, len in 0..=262_143_u32, ) { - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); let end = start + len; let half = start + len / 2; bitmap.insert_range(start..end); diff --git a/tests/rank.rs b/tests/rank.rs index 94883779a..71f80c96b 100644 --- a/tests/rank.rs +++ b/tests/rank.rs @@ -1,12 +1,12 @@ -extern crate roaring; - -use proptest::collection::{btree_set, vec}; -use proptest::prelude::*; -use roaring::RoaringBitmap; +use proptest::{ + collection::{btree_set, vec}, + prelude::*, +}; +use roaring::Roaring32; #[test] fn rank() { - let mut bitmap = RoaringBitmap::from_sorted_iter(0..2000).unwrap(); + let mut bitmap = Roaring32::from_sorted_iter(0..2000).unwrap(); bitmap.insert_range(200_000..210_000); // No matching container @@ -25,7 +25,7 @@ fn rank() { #[test] fn rank_array() { - let bitmap = RoaringBitmap::from_sorted_iter(0..2000).unwrap(); + let bitmap = Roaring32::from_sorted_iter(0..2000).unwrap(); // No matching container assert_eq!(bitmap.rank(u32::MAX), 2000); @@ -39,7 +39,7 @@ fn rank_array() { #[test] fn rank_bitmap() { - let bitmap = RoaringBitmap::from_sorted_iter(0..5000).unwrap(); + let bitmap = Roaring32::from_sorted_iter(0..5000).unwrap(); // key: 0, bit: 0 assert_eq!(bitmap.rank(0), 1); @@ -65,7 +65,7 @@ proptest! { values in btree_set(..=262_143_u32, ..=1000), checks in vec(..=262_143_u32, ..=100) ){ - let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); + let bitmap = Roaring32::from_sorted_iter(values.iter().cloned()).unwrap(); for i in checks { let expected = values.iter().take_while(|&&x| x <= i).count() as u64; assert_eq!(bitmap.rank(i), expected); diff --git a/tests/select.rs b/tests/select.rs index 6abaee300..0dd4cddc6 100644 --- a/tests/select.rs +++ b/tests/select.rs @@ -1,19 +1,16 @@ -extern crate roaring; - -use proptest::collection::btree_set; -use proptest::prelude::*; -use roaring::RoaringBitmap; +use proptest::{collection::btree_set, prelude::*}; +use roaring::Roaring32; #[test] fn select() { - let bitmap = (0..2000).collect::(); + let bitmap = (0..2000).collect::(); assert_eq!(bitmap.select(0), Some(0)); } #[test] fn select_array() { - let bitmap = (0..2000).collect::(); + let bitmap = (0..2000).collect::(); assert_eq!(bitmap.select(0), Some(0)); assert_eq!(bitmap.select(100), Some(100)); @@ -24,7 +21,7 @@ fn select_array() { #[test] fn select_bitmap() { - let bitmap = (0..100_000).collect::(); + let bitmap = (0..100_000).collect::(); assert_eq!(bitmap.select(0), Some(0)); assert_eq!(bitmap.select(63), Some(63)); @@ -34,7 +31,7 @@ fn select_bitmap() { #[test] fn select_empty() { - let bitmap = RoaringBitmap::new(); + let bitmap = Roaring32::new(); assert_eq!(bitmap.select(0), None); assert_eq!(bitmap.select(1024), None); @@ -44,7 +41,7 @@ fn select_empty() { proptest! { #[test] fn proptest_select(values in btree_set(any::(), 1000)) { - let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); + let bitmap = Roaring32::from_sorted_iter(values.iter().cloned()).unwrap(); for (i, value) in values.iter().cloned().enumerate() { prop_assert_eq!(bitmap.select(i as u32), Some(value)); } diff --git a/tests/serialization.rs b/tests/serialization.rs index 42efdd439..259b6e961 100644 --- a/tests/serialization.rs +++ b/tests/serialization.rs @@ -1,35 +1,33 @@ -extern crate roaring; - -use roaring::RoaringBitmap; +use roaring::Roaring32; // Test data from https://github.com/RoaringBitmap/RoaringFormatSpec/tree/master/testdata static BITMAP_WITHOUT_RUNS: &[u8] = include_bytes!("bitmapwithoutruns.bin"); static BITMAP_WITH_RUNS: &[u8] = include_bytes!("bitmapwithruns.bin"); -fn test_data_bitmap() -> RoaringBitmap { +fn test_data_bitmap() -> Roaring32 { (0..100) .map(|i| i * 1000) .chain((100_000..200_000).map(|i| i * 3)) .chain(700_000..800_000) - .collect::() + .collect::() } -fn serialize_and_deserialize(bitmap: &RoaringBitmap) -> RoaringBitmap { +fn serialize_and_deserialize(bitmap: &Roaring32) -> Roaring32 { let mut buffer = vec![]; bitmap.serialize_into(&mut buffer).unwrap(); assert_eq!(buffer.len(), bitmap.serialized_size()); - RoaringBitmap::deserialize_from(&buffer[..]).unwrap() + Roaring32::deserialize_from(&buffer[..]).unwrap() } #[test] fn test_deserialize_without_runs_from_provided_data() { - assert_eq!(RoaringBitmap::deserialize_from(BITMAP_WITHOUT_RUNS).unwrap(), test_data_bitmap()); + assert_eq!(Roaring32::deserialize_from(BITMAP_WITHOUT_RUNS).unwrap(), test_data_bitmap()); } #[test] fn test_deserialize_with_runs_from_provided_data() { assert_eq!( - RoaringBitmap::deserialize_from(&mut &BITMAP_WITH_RUNS[..]).unwrap(), + Roaring32::deserialize_from(&mut &BITMAP_WITH_RUNS[..]).unwrap(), test_data_bitmap() ); } @@ -44,42 +42,42 @@ fn test_serialize_into_provided_data() { #[test] fn test_empty() { - let original = RoaringBitmap::new(); + let original = Roaring32::new(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_one() { - let original = (1..2).collect::(); + let original = (1..2).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_array() { - let original = (1000..3000).collect::(); + let original = (1000..3000).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_array_boundary() { - let original = (1000..5096).collect::(); + let original = (1000..5096).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_bitmap_boundary() { - let original = (1000..5097).collect::(); + let original = (1000..5097).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_bitmap_high16bits() { - let mut bitmap = RoaringBitmap::new(); + let mut bitmap = Roaring32::new(); for i in 0..1 << 16 { let value = i << 16; bitmap.insert(value); @@ -88,35 +86,35 @@ fn test_bitmap_high16bits() { let mut buffer = vec![]; bitmap.serialize_into(&mut buffer).unwrap(); - let new = RoaringBitmap::deserialize_from(&buffer[..]); + let new = Roaring32::deserialize_from(&buffer[..]); assert!(new.is_ok()); assert_eq!(bitmap, new.unwrap()); } #[test] fn test_bitmap() { - let original = (1000..6000).collect::(); + let original = (1000..6000).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_arrays() { - let original = (1000..3000).chain(70000..74000).collect::(); + let original = (1000..3000).chain(70000..74000).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_bitmaps() { - let original = (1000..6000).chain(70000..77000).collect::(); + let original = (1000..6000).chain(70000..77000).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_mixed() { - let original = (1000..3000).chain(70000..77000).collect::(); + let original = (1000..3000).chain(70000..77000).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } @@ -535,7 +533,7 @@ fn test_strange() { 6684416, 6684424, 6684472, 6684563, 6684574, 6684575, 6684576, 6684577, 6684601, 6684635, 6684636, 6684639, 6684640, 6684641, 6684642, 6684666, 108658947, ]; - let original = ARRAY.iter().cloned().collect::(); + let original = ARRAY.iter().cloned().collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } diff --git a/tests/size_hint.rs b/tests/size_hint.rs index 00159be73..250b935d3 100644 --- a/tests/size_hint.rs +++ b/tests/size_hint.rs @@ -1,9 +1,8 @@ -extern crate roaring; -use roaring::RoaringBitmap; +use roaring::Roaring32; #[test] fn array() { - let bitmap = (0..2000).collect::(); + let bitmap = (0..2000).collect::(); let mut iter = bitmap.iter(); assert_eq!((2000, Some(2000)), iter.size_hint()); iter.by_ref().take(1000).for_each(drop); @@ -14,7 +13,7 @@ fn array() { #[test] fn bitmap() { - let bitmap = (0..6000).collect::(); + let bitmap = (0..6000).collect::(); let mut iter = bitmap.iter(); assert_eq!((6000, Some(6000)), iter.size_hint()); iter.by_ref().take(3000).for_each(drop); @@ -25,10 +24,8 @@ fn bitmap() { #[test] fn arrays() { - let bitmap = (0..2000) - .chain(1_000_000..1_002_000) - .chain(2_000_000..2_001_000) - .collect::(); + let bitmap = + (0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000).collect::(); let mut iter = bitmap.iter(); assert_eq!((5000, Some(5000)), iter.size_hint()); iter.by_ref().take(3000).for_each(drop); @@ -39,10 +36,8 @@ fn arrays() { #[test] fn bitmaps() { - let bitmap = (0..6000) - .chain(1_000_000..1_012_000) - .chain(2_000_000..2_010_000) - .collect::(); + let bitmap = + (0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000).collect::(); let mut iter = bitmap.iter(); assert_eq!((28000, Some(28000)), iter.size_hint()); iter.by_ref().take(2000).for_each(drop); diff --git a/tests/symmetric_difference_with.rs b/tests/symmetric_difference_with.rs index d9c2bf5a5..b9501b187 100644 --- a/tests/symmetric_difference_with.rs +++ b/tests/symmetric_difference_with.rs @@ -1,11 +1,10 @@ -extern crate roaring; -use roaring::RoaringBitmap; +use roaring::Roaring32; #[test] fn array() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..3000).collect::(); - let bitmap3 = (0..1000).chain(2000..3000).collect::(); + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..3000).collect::(); + let bitmap3 = (0..1000).chain(2000..3000).collect::(); bitmap1 ^= bitmap2; @@ -14,19 +13,19 @@ fn array() { #[test] fn no_symmetric_difference() { - let mut bitmap1 = (0..2).collect::(); - let bitmap2 = (0..2).collect::(); + let mut bitmap1 = (0..2).collect::(); + let bitmap2 = (0..2).collect::(); bitmap1 ^= bitmap2; - assert_eq!(bitmap1, RoaringBitmap::new()); + assert_eq!(bitmap1, Roaring32::new()); } #[test] fn array_and_bitmap() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..8000).collect::(); - let bitmap3 = (0..1000).chain(2000..8000).collect::(); + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..8000).collect::(); + let bitmap3 = (0..1000).chain(2000..8000).collect::(); bitmap1 ^= bitmap2; @@ -35,9 +34,9 @@ fn array_and_bitmap() { #[test] fn bitmap_to_bitmap() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (6000..18000).collect::(); - let bitmap3 = (0..6000).chain(12000..18000).collect::(); + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (6000..18000).collect::(); + let bitmap3 = (0..6000).chain(12000..18000).collect::(); bitmap1 ^= bitmap2; @@ -46,9 +45,9 @@ fn bitmap_to_bitmap() { #[test] fn bitmap_to_array() { - let mut bitmap1 = (0..6000).collect::(); - let bitmap2 = (2000..7000).collect::(); - let bitmap3 = (0..2000).chain(6000..7000).collect::(); + let mut bitmap1 = (0..6000).collect::(); + let bitmap2 = (2000..7000).collect::(); + let bitmap3 = (0..2000).chain(6000..7000).collect::(); bitmap1 ^= bitmap2; @@ -57,9 +56,9 @@ fn bitmap_to_array() { #[test] fn bitmap_and_array_to_bitmap() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (11000..14000).collect::(); - let bitmap3 = (0..11000).chain(12000..14000).collect::(); + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (11000..14000).collect::(); + let bitmap3 = (0..11000).chain(12000..14000).collect::(); bitmap1 ^= bitmap2; @@ -68,9 +67,9 @@ fn bitmap_and_array_to_bitmap() { #[test] fn bitmap_and_array_to_array() { - let mut bitmap1 = (0..6000).collect::(); - let bitmap2 = (3000..7000).collect::(); - let bitmap3 = (0..3000).chain(6000..7000).collect::(); + let mut bitmap1 = (0..6000).collect::(); + let bitmap2 = (3000..7000).collect::(); + let bitmap3 = (0..3000).chain(6000..7000).collect::(); bitmap1 ^= bitmap2; @@ -79,21 +78,17 @@ fn bitmap_and_array_to_array() { #[test] fn arrays() { - let mut bitmap1 = (0..2000) - .chain(1_000_000..1_002_000) - .chain(3_000_000..3_001_000) - .collect::(); - let bitmap2 = (1000..3000) - .chain(1_001_000..1_003_000) - .chain(2_000_000..2_000_001) - .collect::(); + let mut bitmap1 = + (0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000).collect::(); + let bitmap2 = + (1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_000_001).collect::(); let bitmap3 = (0..1000) .chain(1_000_000..1_001_000) .chain(2000..3000) .chain(1_002_000..1_003_000) .chain(2_000_000..2_000_001) .chain(3_000_000..3_001_000) - .collect::(); + .collect::(); bitmap1 ^= bitmap2; @@ -102,21 +97,17 @@ fn arrays() { #[test] fn bitmaps() { - let mut bitmap1 = (0..6000) - .chain(1_000_000..1_012_000) - .chain(3_000_000..3_010_000) - .collect::(); - let bitmap2 = (3000..7000) - .chain(1_006_000..1_018_000) - .chain(2_000_000..2_010_000) - .collect::(); + let mut bitmap1 = + (0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000).collect::(); + let bitmap2 = + (3000..7000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000).collect::(); let bitmap3 = (0..3000) .chain(1_000_000..1_006_000) .chain(6000..7000) .chain(1_012_000..1_018_000) .chain(2_000_000..2_010_000) .chain(3_000_000..3_010_000) - .collect::(); + .collect::(); bitmap1 ^= bitmap2; diff --git a/tests/treemap_clone.rs b/tests/treemap_clone.rs index ddeb84984..88e64d062 100644 --- a/tests/treemap_clone.rs +++ b/tests/treemap_clone.rs @@ -1,40 +1,40 @@ -extern crate roaring; -use roaring::RoaringTreemap; - -#[test] -#[allow(clippy::redundant_clone)] -fn array() { - let original = (0..2000).collect::(); - let clone = original.clone(); - - assert_eq!(clone, original); -} - -#[test] -#[allow(clippy::redundant_clone)] -fn bitmap() { - let original = (0..6000).collect::(); - let clone = original.clone(); - - assert_eq!(clone, original); -} - -#[test] -#[allow(clippy::redundant_clone)] -fn arrays() { - let original = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) - .collect::(); - let clone = original.clone(); - - assert_eq!(clone, original); -} - -#[test] -#[allow(clippy::redundant_clone)] -fn bitmaps() { - let original = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) - .collect::(); - let clone = original.clone(); - - assert_eq!(clone, original); -} +// extern crate roaring; +// use roaring::RoaringTreemap; + +// #[test] +// #[allow(clippy::redundant_clone)] +// fn array() { +// let original = (0..2000).collect::(); +// let clone = original.clone(); + +// assert_eq!(clone, original); +// } + +// #[test] +// #[allow(clippy::redundant_clone)] +// fn bitmap() { +// let original = (0..6000).collect::(); +// let clone = original.clone(); + +// assert_eq!(clone, original); +// } + +// #[test] +// #[allow(clippy::redundant_clone)] +// fn arrays() { +// let original = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) +// .collect::(); +// let clone = original.clone(); + +// assert_eq!(clone, original); +// } + +// #[test] +// #[allow(clippy::redundant_clone)] +// fn bitmaps() { +// let original = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) +// .collect::(); +// let clone = original.clone(); + +// assert_eq!(clone, original); +// } diff --git a/tests/treemap_difference_with.rs b/tests/treemap_difference_with.rs index 91d4cd352..d2389a03c 100644 --- a/tests/treemap_difference_with.rs +++ b/tests/treemap_difference_with.rs @@ -1,117 +1,117 @@ -extern crate roaring; -use roaring::RoaringTreemap; +// extern crate roaring; +// use roaring::RoaringTreemap; -#[test] -fn array() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..3000).collect::(); - let bitmap3 = (0..1000).collect::(); +// #[test] +// fn array() { +// let mut bitmap1 = (0..2000).collect::(); +// let bitmap2 = (1000..3000).collect::(); +// let bitmap3 = (0..1000).collect::(); - bitmap1 -= bitmap2; +// bitmap1 -= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn no_difference() { - let mut bitmap1 = (1..3).collect::(); - let bitmap2 = (1..3).collect::(); +// #[test] +// fn no_difference() { +// let mut bitmap1 = (1..3).collect::(); +// let bitmap2 = (1..3).collect::(); - bitmap1 -= bitmap2; +// bitmap1 -= bitmap2; - assert_eq!(bitmap1, RoaringTreemap::new()); -} +// assert_eq!(bitmap1, RoaringTreemap::new()); +// } -#[test] -fn array_and_bitmap() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..8000).collect::(); - let bitmap3 = (0..1000).collect::(); +// #[test] +// fn array_and_bitmap() { +// let mut bitmap1 = (0..2000).collect::(); +// let bitmap2 = (1000..8000).collect::(); +// let bitmap3 = (0..1000).collect::(); - bitmap1 -= bitmap2; +// bitmap1 -= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn bitmap_to_bitmap() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (6000..18000).collect::(); - let bitmap3 = (0..6000).collect::(); +// #[test] +// fn bitmap_to_bitmap() { +// let mut bitmap1 = (0..12000).collect::(); +// let bitmap2 = (6000..18000).collect::(); +// let bitmap3 = (0..6000).collect::(); - bitmap1 -= bitmap2; +// bitmap1 -= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn bitmap_to_array() { - let mut bitmap1 = (0..6000).collect::(); - let bitmap2 = (3000..9000).collect::(); - let bitmap3 = (0..3000).collect::(); +// #[test] +// fn bitmap_to_array() { +// let mut bitmap1 = (0..6000).collect::(); +// let bitmap2 = (3000..9000).collect::(); +// let bitmap3 = (0..3000).collect::(); - bitmap1 -= bitmap2; +// bitmap1 -= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn bitmap_and_array_to_bitmap() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (9000..12000).collect::(); - let bitmap3 = (0..9000).collect::(); +// #[test] +// fn bitmap_and_array_to_bitmap() { +// let mut bitmap1 = (0..12000).collect::(); +// let bitmap2 = (9000..12000).collect::(); +// let bitmap3 = (0..9000).collect::(); - bitmap1 -= bitmap2; +// bitmap1 -= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn bitmap_and_array_to_array() { - let mut bitmap1 = (0..6000).collect::(); - let bitmap2 = (3000..6000).collect::(); - let bitmap3 = (0..3000).collect::(); +// #[test] +// fn bitmap_and_array_to_array() { +// let mut bitmap1 = (0..6000).collect::(); +// let bitmap2 = (3000..6000).collect::(); +// let bitmap3 = (0..3000).collect::(); - bitmap1 -= bitmap2; +// bitmap1 -= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn arrays() { - let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) - .collect::(); - let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) - .collect::(); - let bitmap3 = ((0..1000).chain(1_000_000..1_001_000)).collect::(); +// #[test] +// fn arrays() { +// let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) +// .collect::(); +// let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) +// .collect::(); +// let bitmap3 = ((0..1000).chain(1_000_000..1_001_000)).collect::(); - bitmap1 -= bitmap2; +// bitmap1 -= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn arrays_removing_one_whole_container() { - let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) - .collect::(); - let bitmap2 = ((0..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) - .collect::(); - let bitmap3 = (1_000_000..1_001_000).collect::(); +// #[test] +// fn arrays_removing_one_whole_container() { +// let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) +// .collect::(); +// let bitmap2 = ((0..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) +// .collect::(); +// let bitmap3 = (1_000_000..1_001_000).collect::(); - bitmap1 -= bitmap2; +// bitmap1 -= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn bitmaps() { - let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) - .collect::(); - let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) - .collect::(); - let bitmap3 = ((0..3000).chain(1_000_000..1_006_000)).collect::(); +// #[test] +// fn bitmaps() { +// let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) +// .collect::(); +// let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) +// .collect::(); +// let bitmap3 = ((0..3000).chain(1_000_000..1_006_000)).collect::(); - bitmap1 -= bitmap2; +// bitmap1 -= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } diff --git a/tests/treemap_intersect_with.rs b/tests/treemap_intersect_with.rs index a794a6c3e..c739c3c8c 100644 --- a/tests/treemap_intersect_with.rs +++ b/tests/treemap_intersect_with.rs @@ -1,93 +1,93 @@ -extern crate roaring; -use roaring::RoaringTreemap; +// extern crate roaring; +// use roaring::RoaringTreemap; -#[test] -fn array() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..3000).collect::(); - let bitmap3 = (1000..2000).collect::(); +// #[test] +// fn array() { +// let mut bitmap1 = (0..2000).collect::(); +// let bitmap2 = (1000..3000).collect::(); +// let bitmap3 = (1000..2000).collect::(); - bitmap1 &= bitmap2; +// bitmap1 &= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn no_intersection() { - let mut bitmap1 = (0..2).collect::(); - let bitmap2 = (3..4).collect::(); +// #[test] +// fn no_intersection() { +// let mut bitmap1 = (0..2).collect::(); +// let bitmap2 = (3..4).collect::(); - bitmap1 &= bitmap2; +// bitmap1 &= bitmap2; - assert_eq!(bitmap1, RoaringTreemap::new()); -} +// assert_eq!(bitmap1, RoaringTreemap::new()); +// } -#[test] -fn array_and_bitmap() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..8000).collect::(); - let bitmap3 = (1000..2000).collect::(); +// #[test] +// fn array_and_bitmap() { +// let mut bitmap1 = (0..2000).collect::(); +// let bitmap2 = (1000..8000).collect::(); +// let bitmap3 = (1000..2000).collect::(); - bitmap1 &= bitmap2; +// bitmap1 &= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn bitmap_to_bitmap() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (6000..18000).collect::(); - let bitmap3 = (6000..12000).collect::(); +// #[test] +// fn bitmap_to_bitmap() { +// let mut bitmap1 = (0..12000).collect::(); +// let bitmap2 = (6000..18000).collect::(); +// let bitmap3 = (6000..12000).collect::(); - bitmap1 &= bitmap2; +// bitmap1 &= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn bitmap_to_array() { - let mut bitmap1 = (0..6000).collect::(); - let bitmap2 = (3000..9000).collect::(); - let bitmap3 = (3000..6000).collect::(); +// #[test] +// fn bitmap_to_array() { +// let mut bitmap1 = (0..6000).collect::(); +// let bitmap2 = (3000..9000).collect::(); +// let bitmap3 = (3000..6000).collect::(); - bitmap1 &= bitmap2; +// bitmap1 &= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn bitmap_and_array() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (7000..9000).collect::(); - let bitmap3 = (7000..9000).collect::(); +// #[test] +// fn bitmap_and_array() { +// let mut bitmap1 = (0..12000).collect::(); +// let bitmap2 = (7000..9000).collect::(); +// let bitmap3 = (7000..9000).collect::(); - bitmap1 &= bitmap2; +// bitmap1 &= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn arrays() { - let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)) - .collect::(); - let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) - .collect::(); - let bitmap3 = ((1000..2000).chain(1_001_000..1_002_000)).collect::(); +// #[test] +// fn arrays() { +// let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)) +// .collect::(); +// let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) +// .collect::(); +// let bitmap3 = ((1000..2000).chain(1_001_000..1_002_000)).collect::(); - bitmap1 &= bitmap2; +// bitmap1 &= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } -#[test] -fn bitmaps() { - let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)) - .collect::(); - let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) - .collect::(); - let bitmap3 = ((3000..6000).chain(1_006_000..1_012_000)).collect::(); +// #[test] +// fn bitmaps() { +// let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)) +// .collect::(); +// let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) +// .collect::(); +// let bitmap3 = ((3000..6000).chain(1_006_000..1_012_000)).collect::(); - bitmap1 &= bitmap2; +// bitmap1 &= bitmap2; - assert_eq!(bitmap1, bitmap3); -} +// assert_eq!(bitmap1, bitmap3); +// } diff --git a/tests/treemap_is_disjoint.rs b/tests/treemap_is_disjoint.rs index 0680bf252..a5f0e7ee8 100644 --- a/tests/treemap_is_disjoint.rs +++ b/tests/treemap_is_disjoint.rs @@ -1,62 +1,62 @@ -extern crate roaring; -use roaring::RoaringTreemap; - -#[test] -fn array() { - let bitmap1 = (0..2000).collect::(); - let bitmap2 = (4000..6000).collect::(); - assert!(bitmap1.is_disjoint(&bitmap2)); -} - -#[test] -fn array_not() { - let bitmap1 = (0..4000).collect::(); - let bitmap2 = (2000..6000).collect::(); - assert!(!bitmap1.is_disjoint(&bitmap2)); -} - -#[test] -fn bitmap() { - let bitmap1 = (0..6000).collect::(); - let bitmap2 = (10000..16000).collect::(); - assert!(bitmap1.is_disjoint(&bitmap2)); -} - -#[test] -fn bitmap_not() { - let bitmap1 = (0..10000).collect::(); - let bitmap2 = (5000..15000).collect::(); - assert!(!bitmap1.is_disjoint(&bitmap2)); -} - -#[test] -fn arrays() { - let bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_002_000)) - .collect::(); - let bitmap2 = ((100_000..102_000).chain(1_100_000..1_102_000)).collect::(); - assert!(bitmap1.is_disjoint(&bitmap2)); -} - -#[test] -fn arrays_not() { - let bitmap1 = ((0..2_000).chain(1_000_000..1_002_000).chain(2_000_000..2_002_000)) - .collect::(); - let bitmap2 = ((100_000..102_000).chain(1_001_000..1_003_000)).collect::(); - assert!(!bitmap1.is_disjoint(&bitmap2)); -} - -#[test] -fn bitmaps() { - let bitmap1 = ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_006_000)) - .collect::(); - let bitmap2 = ((100_000..106_000).chain(1_100_000..1_106_000)).collect::(); - assert!(bitmap1.is_disjoint(&bitmap2)); -} - -#[test] -fn bitmaps_not() { - let bitmap1 = ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_006_000)) - .collect::(); - let bitmap2 = ((100_000..106_000).chain(1_004_000..1_008_000)).collect::(); - assert!(!bitmap1.is_disjoint(&bitmap2)); -} +// extern crate roaring; +// use roaring::RoaringTreemap; + +// #[test] +// fn array() { +// let bitmap1 = (0..2000).collect::(); +// let bitmap2 = (4000..6000).collect::(); +// assert!(bitmap1.is_disjoint(&bitmap2)); +// } + +// #[test] +// fn array_not() { +// let bitmap1 = (0..4000).collect::(); +// let bitmap2 = (2000..6000).collect::(); +// assert!(!bitmap1.is_disjoint(&bitmap2)); +// } + +// #[test] +// fn bitmap() { +// let bitmap1 = (0..6000).collect::(); +// let bitmap2 = (10000..16000).collect::(); +// assert!(bitmap1.is_disjoint(&bitmap2)); +// } + +// #[test] +// fn bitmap_not() { +// let bitmap1 = (0..10000).collect::(); +// let bitmap2 = (5000..15000).collect::(); +// assert!(!bitmap1.is_disjoint(&bitmap2)); +// } + +// #[test] +// fn arrays() { +// let bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_002_000)) +// .collect::(); +// let bitmap2 = ((100_000..102_000).chain(1_100_000..1_102_000)).collect::(); +// assert!(bitmap1.is_disjoint(&bitmap2)); +// } + +// #[test] +// fn arrays_not() { +// let bitmap1 = ((0..2_000).chain(1_000_000..1_002_000).chain(2_000_000..2_002_000)) +// .collect::(); +// let bitmap2 = ((100_000..102_000).chain(1_001_000..1_003_000)).collect::(); +// assert!(!bitmap1.is_disjoint(&bitmap2)); +// } + +// #[test] +// fn bitmaps() { +// let bitmap1 = ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_006_000)) +// .collect::(); +// let bitmap2 = ((100_000..106_000).chain(1_100_000..1_106_000)).collect::(); +// assert!(bitmap1.is_disjoint(&bitmap2)); +// } + +// #[test] +// fn bitmaps_not() { +// let bitmap1 = ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_006_000)) +// .collect::(); +// let bitmap2 = ((100_000..106_000).chain(1_004_000..1_008_000)).collect::(); +// assert!(!bitmap1.is_disjoint(&bitmap2)); +// } diff --git a/tests/treemap_is_subset.rs b/tests/treemap_is_subset.rs index 5abb784be..f41908f5c 100644 --- a/tests/treemap_is_subset.rs +++ b/tests/treemap_is_subset.rs @@ -1,80 +1,80 @@ -extern crate roaring; -use roaring::RoaringTreemap; +// extern crate roaring; +// use roaring::RoaringTreemap; -#[test] -fn array_not() { - let sup = (0..2000).collect::(); - let sub = (1000..3000).collect::(); - assert!(!sub.is_subset(&sup)); -} +// #[test] +// fn array_not() { +// let sup = (0..2000).collect::(); +// let sub = (1000..3000).collect::(); +// assert!(!sub.is_subset(&sup)); +// } -#[test] -fn array() { - let sup = (0..4000).collect::(); - let sub = (2000..3000).collect::(); - assert!(sub.is_subset(&sup)); -} +// #[test] +// fn array() { +// let sup = (0..4000).collect::(); +// let sub = (2000..3000).collect::(); +// assert!(sub.is_subset(&sup)); +// } -#[test] -fn array_bitmap_not() { - let sup = (0..2000).collect::(); - let sub = (1000..15000).collect::(); - assert!(!sub.is_subset(&sup)); -} +// #[test] +// fn array_bitmap_not() { +// let sup = (0..2000).collect::(); +// let sub = (1000..15000).collect::(); +// assert!(!sub.is_subset(&sup)); +// } -#[test] -fn bitmap_not() { - let sup = (0..6000).collect::(); - let sub = (4000..10000).collect::(); - assert!(!sub.is_subset(&sup)); -} +// #[test] +// fn bitmap_not() { +// let sup = (0..6000).collect::(); +// let sub = (4000..10000).collect::(); +// assert!(!sub.is_subset(&sup)); +// } -#[test] -fn bitmap() { - let sup = (0..20000).collect::(); - let sub = (5000..15000).collect::(); - assert!(sub.is_subset(&sup)); -} +// #[test] +// fn bitmap() { +// let sup = (0..20000).collect::(); +// let sub = (5000..15000).collect::(); +// assert!(sub.is_subset(&sup)); +// } -#[test] -fn bitmap_array_not() { - let sup = (0..20000).collect::(); - let sub = (19000..21000).collect::(); - assert!(!sub.is_subset(&sup)); -} +// #[test] +// fn bitmap_array_not() { +// let sup = (0..20000).collect::(); +// let sub = (19000..21000).collect::(); +// assert!(!sub.is_subset(&sup)); +// } -#[test] -fn bitmap_array() { - let sup = (0..20000).collect::(); - let sub = (18000..20000).collect::(); - assert!(sub.is_subset(&sup)); -} +// #[test] +// fn bitmap_array() { +// let sup = (0..20000).collect::(); +// let sub = (18000..20000).collect::(); +// assert!(sub.is_subset(&sup)); +// } -#[test] -fn arrays_not() { - let sup = ((0..2000).chain(1_000_000..1_002_000)).collect::(); - let sub = ((100_000..102_000).chain(1_100_000..1_102_000)).collect::(); - assert!(!sub.is_subset(&sup)); -} +// #[test] +// fn arrays_not() { +// let sup = ((0..2000).chain(1_000_000..1_002_000)).collect::(); +// let sub = ((100_000..102_000).chain(1_100_000..1_102_000)).collect::(); +// assert!(!sub.is_subset(&sup)); +// } -#[test] -fn arrays() { - let sup = ((0..3000).chain(100_000..103_000)).collect::(); - let sub = ((0..2000).chain(100_000..102_000)).collect::(); - assert!(sub.is_subset(&sup)); -} +// #[test] +// fn arrays() { +// let sup = ((0..3000).chain(100_000..103_000)).collect::(); +// let sub = ((0..2000).chain(100_000..102_000)).collect::(); +// assert!(sub.is_subset(&sup)); +// } -#[test] -fn bitmaps_not() { - let sup = ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_010_000)) - .collect::(); - let sub = ((100_000..106_000).chain(1_100_000..1_106_000)).collect::(); - assert!(!sub.is_subset(&sup)); -} +// #[test] +// fn bitmaps_not() { +// let sup = ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_010_000)) +// .collect::(); +// let sub = ((100_000..106_000).chain(1_100_000..1_106_000)).collect::(); +// assert!(!sub.is_subset(&sup)); +// } -#[test] -fn bitmaps() { - let sup = ((0..1_000_000).chain(2_000_000..2_010_000)).collect::(); - let sub = ((0..10_000).chain(500_000..510_000)).collect::(); - assert!(sub.is_subset(&sup)); -} +// #[test] +// fn bitmaps() { +// let sup = ((0..1_000_000).chain(2_000_000..2_010_000)).collect::(); +// let sub = ((0..10_000).chain(500_000..510_000)).collect::(); +// assert!(sub.is_subset(&sup)); +// } diff --git a/tests/treemap_iter.rs b/tests/treemap_iter.rs index ddde2efc3..c35fda421 100644 --- a/tests/treemap_iter.rs +++ b/tests/treemap_iter.rs @@ -1,129 +1,129 @@ -extern crate roaring; -mod iter; -use roaring::RoaringTreemap; - -use iter::outside_in; -use proptest::arbitrary::any; -use proptest::collection::btree_set; -use proptest::proptest; -use std::iter::FromIterator; - -#[test] -fn range() { - let original = (0..2000).collect::(); - let clone = RoaringTreemap::from_iter(&original); - let clone2 = RoaringTreemap::from_iter(original.clone()); - - assert_eq!(clone, original); - assert_eq!(clone2, original); -} - -#[test] -fn array() { - let original = (0..5).collect::(); - let clone = RoaringTreemap::from([0, 1, 2, 3, 4]); - - assert_eq!(clone, original); -} - -#[test] -fn bitmap() { - let original = (0..6000).collect::(); - let clone = RoaringTreemap::from_iter(&original); - let clone2 = RoaringTreemap::from_iter(original.clone()); - - assert_eq!(clone, original); - assert_eq!(clone2, original); -} - -#[test] -fn arrays() { - let original = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) - .collect::(); - let clone = RoaringTreemap::from_iter(&original); - let clone2 = RoaringTreemap::from_iter(original.clone()); - - assert_eq!(clone, original); - assert_eq!(clone2, original); -} - -#[test] -fn bitmaps() { - let original = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) - .collect::(); - let clone = RoaringTreemap::from_iter(&original); - let clone2 = RoaringTreemap::from_iter(original.clone()); - - assert_eq!(clone, original); - assert_eq!(clone2, original); -} - -#[test] -fn bitmaps_iterator() { - let original = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) - .collect::(); - let clone = RoaringTreemap::from_bitmaps(original.bitmaps().map(|(p, b)| (p, b.clone()))); - let clone2 = original.bitmaps().map(|(p, b)| (p, b.clone())).collect::(); - - assert_eq!(clone, original); - assert_eq!(clone2, original); -} - -proptest! { - #[test] - fn iter(values in btree_set(any::(), ..=10_000)) { - let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); - - assert!(values.into_iter().eq(bitmap)); - } -} - -#[test] -fn rev() { - let values = (1..3) - .chain(1_000_000..1_012_003) - .chain(2_000_001..2_000_003) - .chain(2_000_000_000_001..2_000_000_000_003); - let bitmap = RoaringTreemap::from_iter(values.clone()); - - assert!(values.into_iter().rev().eq(bitmap.iter().rev())); -} - -proptest! { - #[test] - fn rev_iter(values in btree_set(any::(), ..=10_000)) { - let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); - - assert!(values.into_iter().rev().eq(bitmap.iter().rev())); - } -} - -#[test] -fn from_iter() { - // This test verifies that the public API allows conversion from iterators - // with u64 as well as &u64 elements. - let vals = vec![1, 5, 1_000_000_000_000_000]; - let a = RoaringTreemap::from_iter(vals.iter()); - let b = RoaringTreemap::from_iter(vals); - assert_eq!(a, b); -} - -#[test] -fn interleaved() { - let values = (1..3) - .chain(1_000_000..1_012_003) - .chain(2_000_001..2_000_003) - .chain(2_000_000_000_001..2_000_000_000_003); - let bitmap = RoaringTreemap::from_iter(values.clone()); - - assert!(outside_in(values).eq(outside_in(bitmap))); -} - -proptest! { - #[test] - fn interleaved_iter(values in btree_set(any::(), 50_000..=100_000)) { - let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); - - assert!(outside_in(values).eq(outside_in(bitmap))); - } -} +// extern crate roaring; +// mod iter; +// use roaring::RoaringTreemap; + +// use iter::outside_in; +// use proptest::arbitrary::any; +// use proptest::collection::btree_set; +// use proptest::proptest; +// use std::iter::FromIterator; + +// #[test] +// fn range() { +// let original = (0..2000).collect::(); +// let clone = RoaringTreemap::from_iter(&original); +// let clone2 = RoaringTreemap::from_iter(original.clone()); + +// assert_eq!(clone, original); +// assert_eq!(clone2, original); +// } + +// #[test] +// fn array() { +// let original = (0..5).collect::(); +// let clone = RoaringTreemap::from([0, 1, 2, 3, 4]); + +// assert_eq!(clone, original); +// } + +// #[test] +// fn bitmap() { +// let original = (0..6000).collect::(); +// let clone = RoaringTreemap::from_iter(&original); +// let clone2 = RoaringTreemap::from_iter(original.clone()); + +// assert_eq!(clone, original); +// assert_eq!(clone2, original); +// } + +// #[test] +// fn arrays() { +// let original = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) +// .collect::(); +// let clone = RoaringTreemap::from_iter(&original); +// let clone2 = RoaringTreemap::from_iter(original.clone()); + +// assert_eq!(clone, original); +// assert_eq!(clone2, original); +// } + +// #[test] +// fn bitmaps() { +// let original = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) +// .collect::(); +// let clone = RoaringTreemap::from_iter(&original); +// let clone2 = RoaringTreemap::from_iter(original.clone()); + +// assert_eq!(clone, original); +// assert_eq!(clone2, original); +// } + +// #[test] +// fn bitmaps_iterator() { +// let original = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) +// .collect::(); +// let clone = RoaringTreemap::from_bitmaps(original.bitmaps().map(|(p, b)| (p, b.clone()))); +// let clone2 = original.bitmaps().map(|(p, b)| (p, b.clone())).collect::(); + +// assert_eq!(clone, original); +// assert_eq!(clone2, original); +// } + +// proptest! { +// #[test] +// fn iter(values in btree_set(any::(), ..=10_000)) { +// let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); + +// assert!(values.into_iter().eq(bitmap)); +// } +// } + +// #[test] +// fn rev() { +// let values = (1..3) +// .chain(1_000_000..1_012_003) +// .chain(2_000_001..2_000_003) +// .chain(2_000_000_000_001..2_000_000_000_003); +// let bitmap = RoaringTreemap::from_iter(values.clone()); + +// assert!(values.into_iter().rev().eq(bitmap.iter().rev())); +// } + +// proptest! { +// #[test] +// fn rev_iter(values in btree_set(any::(), ..=10_000)) { +// let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); + +// assert!(values.into_iter().rev().eq(bitmap.iter().rev())); +// } +// } + +// #[test] +// fn from_iter() { +// // This test verifies that the public API allows conversion from iterators +// // with u64 as well as &u64 elements. +// let vals = vec![1, 5, 1_000_000_000_000_000]; +// let a = RoaringTreemap::from_iter(vals.iter()); +// let b = RoaringTreemap::from_iter(vals); +// assert_eq!(a, b); +// } + +// #[test] +// fn interleaved() { +// let values = (1..3) +// .chain(1_000_000..1_012_003) +// .chain(2_000_001..2_000_003) +// .chain(2_000_000_000_001..2_000_000_000_003); +// let bitmap = RoaringTreemap::from_iter(values.clone()); + +// assert!(outside_in(values).eq(outside_in(bitmap))); +// } + +// proptest! { +// #[test] +// fn interleaved_iter(values in btree_set(any::(), 50_000..=100_000)) { +// let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); + +// assert!(outside_in(values).eq(outside_in(bitmap))); +// } +// } diff --git a/tests/treemap_lib.rs b/tests/treemap_lib.rs index 0c302af9b..60211c88b 100644 --- a/tests/treemap_lib.rs +++ b/tests/treemap_lib.rs @@ -1,119 +1,119 @@ -extern crate roaring; -use roaring::RoaringTreemap; +// extern crate roaring; +// use roaring::RoaringTreemap; -#[test] -fn smoke() { - let mut bitmap = RoaringTreemap::new(); - assert_eq!(bitmap.len(), 0); - assert!(bitmap.is_empty()); - bitmap.remove(0); - assert_eq!(bitmap.len(), 0); - assert!(bitmap.is_empty()); - bitmap.insert(1); - assert!(bitmap.contains(1)); - assert_eq!(bitmap.len(), 1); - assert!(!bitmap.is_empty()); - bitmap.insert(u64::MAX - 2); - assert!(bitmap.contains(u64::MAX - 2)); - assert_eq!(bitmap.len(), 2); - bitmap.insert(u64::MAX); - assert!(bitmap.contains(u64::MAX)); - assert_eq!(bitmap.len(), 3); - bitmap.insert(2); - assert!(bitmap.contains(2)); - assert_eq!(bitmap.len(), 4); - bitmap.remove(2); - assert!(!bitmap.contains(2)); - assert_eq!(bitmap.len(), 3); - assert!(!bitmap.contains(0)); - assert!(bitmap.contains(1)); - assert!(!bitmap.contains(100)); - assert!(bitmap.contains(u64::MAX - 2)); - assert!(!bitmap.contains(u64::MAX - 1)); - assert!(bitmap.contains(u64::MAX)); -} +// #[test] +// fn smoke() { +// let mut bitmap = RoaringTreemap::new(); +// assert_eq!(bitmap.len(), 0); +// assert!(bitmap.is_empty()); +// bitmap.remove(0); +// assert_eq!(bitmap.len(), 0); +// assert!(bitmap.is_empty()); +// bitmap.insert(1); +// assert!(bitmap.contains(1)); +// assert_eq!(bitmap.len(), 1); +// assert!(!bitmap.is_empty()); +// bitmap.insert(u64::MAX - 2); +// assert!(bitmap.contains(u64::MAX - 2)); +// assert_eq!(bitmap.len(), 2); +// bitmap.insert(u64::MAX); +// assert!(bitmap.contains(u64::MAX)); +// assert_eq!(bitmap.len(), 3); +// bitmap.insert(2); +// assert!(bitmap.contains(2)); +// assert_eq!(bitmap.len(), 4); +// bitmap.remove(2); +// assert!(!bitmap.contains(2)); +// assert_eq!(bitmap.len(), 3); +// assert!(!bitmap.contains(0)); +// assert!(bitmap.contains(1)); +// assert!(!bitmap.contains(100)); +// assert!(bitmap.contains(u64::MAX - 2)); +// assert!(!bitmap.contains(u64::MAX - 1)); +// assert!(bitmap.contains(u64::MAX)); +// } -#[test] -fn insert_range() { - let ranges = 0..0x1000; - const SIGMA: u64 = u32::MAX as u64; +// #[test] +// fn insert_range() { +// let ranges = 0..0x1000; +// const SIGMA: u64 = u32::MAX as u64; - let mut bitmap = RoaringTreemap::new(); - assert_eq!(bitmap.insert_range(ranges), 0x1000); - assert_eq!(bitmap.len(), 0x1000); - assert_eq!(bitmap.max(), Some(0xFFF)); +// let mut bitmap = RoaringTreemap::new(); +// assert_eq!(bitmap.insert_range(ranges), 0x1000); +// assert_eq!(bitmap.len(), 0x1000); +// assert_eq!(bitmap.max(), Some(0xFFF)); - assert_eq!(bitmap.insert_range(u32::MAX as u64 - 1..u32::MAX as u64 + 1), 2); - assert!(bitmap.contains(2)); - assert!(bitmap.contains(0xFFF)); - assert!(!bitmap.contains(0x1000)); +// assert_eq!(bitmap.insert_range(u32::MAX as u64 - 1..u32::MAX as u64 + 1), 2); +// assert!(bitmap.contains(2)); +// assert!(bitmap.contains(0xFFF)); +// assert!(!bitmap.contains(0x1000)); - bitmap.clear(); - bitmap.insert_range(2 * SIGMA..=4 * SIGMA); +// bitmap.clear(); +// bitmap.insert_range(2 * SIGMA..=4 * SIGMA); - assert_eq!(bitmap.min(), Some(2 * SIGMA)); - assert_eq!(bitmap.max(), Some(4 * SIGMA)); +// assert_eq!(bitmap.min(), Some(2 * SIGMA)); +// assert_eq!(bitmap.max(), Some(4 * SIGMA)); - assert!(bitmap.contains(3 * SIGMA)); -} +// assert!(bitmap.contains(3 * SIGMA)); +// } -#[test] -fn remove_range() { - let ranges = [0u64, 1, 63, 64, 65, 100, 4096 - 1, 4096, 4096 + 1, 65536 - 1]; - for (i, &a) in ranges.iter().enumerate() { - for &b in &ranges[i..] { - let mut bitmap = (0..=65536).collect::(); - assert_eq!(bitmap.remove_range(a..b), (b - a)); - assert_eq!(bitmap, ((0..a).chain(b..=65536)).collect::()); - } - } -} +// #[test] +// fn remove_range() { +// let ranges = [0u64, 1, 63, 64, 65, 100, 4096 - 1, 4096, 4096 + 1, 65536 - 1]; +// for (i, &a) in ranges.iter().enumerate() { +// for &b in &ranges[i..] { +// let mut bitmap = (0..=65536).collect::(); +// assert_eq!(bitmap.remove_range(a..b), (b - a)); +// assert_eq!(bitmap, ((0..a).chain(b..=65536)).collect::()); +// } +// } +// } -#[test] -fn test_max() { - let mut bitmap = RoaringTreemap::new(); - assert_eq!(bitmap.max(), None); - bitmap.insert(0); - assert_eq!(bitmap.max(), Some(0)); - bitmap.insert(1); - assert_eq!(bitmap.max(), Some(1)); - bitmap.insert(u64::MAX); - assert_eq!(bitmap.max(), Some(u64::MAX)); -} +// #[test] +// fn test_max() { +// let mut bitmap = RoaringTreemap::new(); +// assert_eq!(bitmap.max(), None); +// bitmap.insert(0); +// assert_eq!(bitmap.max(), Some(0)); +// bitmap.insert(1); +// assert_eq!(bitmap.max(), Some(1)); +// bitmap.insert(u64::MAX); +// assert_eq!(bitmap.max(), Some(u64::MAX)); +// } -#[test] -fn test_min() { - let mut bitmap = RoaringTreemap::new(); - assert_eq!(bitmap.min(), None); - bitmap.insert(u64::MAX); - assert_eq!(bitmap.min(), Some(u64::MAX)); - bitmap.insert(1); - assert_eq!(bitmap.min(), Some(1)); - bitmap.insert(0); - assert_eq!(bitmap.min(), Some(0)); -} +// #[test] +// fn test_min() { +// let mut bitmap = RoaringTreemap::new(); +// assert_eq!(bitmap.min(), None); +// bitmap.insert(u64::MAX); +// assert_eq!(bitmap.min(), Some(u64::MAX)); +// bitmap.insert(1); +// assert_eq!(bitmap.min(), Some(1)); +// bitmap.insert(0); +// assert_eq!(bitmap.min(), Some(0)); +// } -#[test] -fn to_bitmap() { - let bitmap = (0..5000).collect::(); - assert_eq!(bitmap.len(), 5000); - for i in 1..5000 { - assert!(bitmap.contains(i)); - } - assert!(!bitmap.contains(5001)); -} +// #[test] +// fn to_bitmap() { +// let bitmap = (0..5000).collect::(); +// assert_eq!(bitmap.len(), 5000); +// for i in 1..5000 { +// assert!(bitmap.contains(i)); +// } +// assert!(!bitmap.contains(5001)); +// } -#[test] -fn to_array() { - let mut bitmap = (0..5000).collect::(); - for i in 3000..5000 { - bitmap.remove(i); - } - assert_eq!(bitmap.len(), 3000); - for i in 0..3000 { - assert!(bitmap.contains(i)); - } - for i in 3000..5000 { - assert!(!bitmap.contains(i)); - } -} +// #[test] +// fn to_array() { +// let mut bitmap = (0..5000).collect::(); +// for i in 3000..5000 { +// bitmap.remove(i); +// } +// assert_eq!(bitmap.len(), 3000); +// for i in 0..3000 { +// assert!(bitmap.contains(i)); +// } +// for i in 3000..5000 { +// assert!(!bitmap.contains(i)); +// } +// } diff --git a/tests/treemap_ops.rs b/tests/treemap_ops.rs index 39375ee73..9512159b9 100644 --- a/tests/treemap_ops.rs +++ b/tests/treemap_ops.rs @@ -1,78 +1,78 @@ -extern crate roaring; -use roaring::RoaringTreemap; - -#[test] -fn or() { - let mut rb1 = (1..4).collect::(); - let rb2 = (3..6).collect::(); - let rb3 = (1..6).collect::(); - - assert_eq!(rb3, &rb1 | &rb2); - assert_eq!(rb3, &rb1 | rb2.clone()); - assert_eq!(rb3, rb1.clone() | &rb2); - assert_eq!(rb3, rb1.clone() | rb2.clone()); - assert_eq!(rb3.len(), rb1.union_len(&rb2)); - - rb1 |= &rb2; - rb1 |= rb2; - - assert_eq!(rb3, rb1); -} - -#[test] -fn and() { - let mut rb1 = (1..4).collect::(); - let rb2 = (3..6).collect::(); - let rb3 = (3..4).collect::(); - - assert_eq!(rb3, &rb1 & &rb2); - assert_eq!(rb3, &rb1 & rb2.clone()); - assert_eq!(rb3, rb1.clone() & &rb2); - assert_eq!(rb3, rb1.clone() & rb2.clone()); - assert_eq!(rb3.len(), rb1.intersection_len(&rb2)); - - rb1 &= &rb2; - rb1 &= rb2; - - assert_eq!(rb3, rb1); -} - -#[test] -fn sub() { - let mut rb1 = (1..4).collect::(); - let rb2 = (3..6).collect::(); - let rb3 = (1..3).collect::(); - - assert_eq!(rb3, &rb1 - &rb2); - assert_eq!(rb3, &rb1 - rb2.clone()); - assert_eq!(rb3, rb1.clone() - &rb2); - assert_eq!(rb3, rb1.clone() - rb2.clone()); - assert_eq!(rb3.len(), rb1.difference_len(&rb2)); - - rb1 -= &rb2; - rb1 -= rb2; - - assert_eq!(rb3, rb1); -} - -#[test] -fn xor() { - let mut rb1 = (1..4).collect::(); - let rb2 = (3..6).collect::(); - let rb3 = ((1..3).chain(4..6)).collect::(); - let rb4 = (0..0).collect::(); - - assert_eq!(rb3, &rb1 ^ &rb2); - assert_eq!(rb3, &rb1 ^ rb2.clone()); - assert_eq!(rb3, rb1.clone() ^ &rb2); - assert_eq!(rb3, rb1.clone() ^ rb2.clone()); - assert_eq!(rb3.len(), rb1.symmetric_difference_len(&rb2)); - - rb1 ^= &rb2; - - assert_eq!(rb3, rb1); - - rb1 ^= rb3; - - assert_eq!(rb4, rb1); -} +// extern crate roaring; +// use roaring::RoaringTreemap; + +// #[test] +// fn or() { +// let mut rb1 = (1..4).collect::(); +// let rb2 = (3..6).collect::(); +// let rb3 = (1..6).collect::(); + +// assert_eq!(rb3, &rb1 | &rb2); +// assert_eq!(rb3, &rb1 | rb2.clone()); +// assert_eq!(rb3, rb1.clone() | &rb2); +// assert_eq!(rb3, rb1.clone() | rb2.clone()); +// assert_eq!(rb3.len(), rb1.union_len(&rb2)); + +// rb1 |= &rb2; +// rb1 |= rb2; + +// assert_eq!(rb3, rb1); +// } + +// #[test] +// fn and() { +// let mut rb1 = (1..4).collect::(); +// let rb2 = (3..6).collect::(); +// let rb3 = (3..4).collect::(); + +// assert_eq!(rb3, &rb1 & &rb2); +// assert_eq!(rb3, &rb1 & rb2.clone()); +// assert_eq!(rb3, rb1.clone() & &rb2); +// assert_eq!(rb3, rb1.clone() & rb2.clone()); +// assert_eq!(rb3.len(), rb1.intersection_len(&rb2)); + +// rb1 &= &rb2; +// rb1 &= rb2; + +// assert_eq!(rb3, rb1); +// } + +// #[test] +// fn sub() { +// let mut rb1 = (1..4).collect::(); +// let rb2 = (3..6).collect::(); +// let rb3 = (1..3).collect::(); + +// assert_eq!(rb3, &rb1 - &rb2); +// assert_eq!(rb3, &rb1 - rb2.clone()); +// assert_eq!(rb3, rb1.clone() - &rb2); +// assert_eq!(rb3, rb1.clone() - rb2.clone()); +// assert_eq!(rb3.len(), rb1.difference_len(&rb2)); + +// rb1 -= &rb2; +// rb1 -= rb2; + +// assert_eq!(rb3, rb1); +// } + +// #[test] +// fn xor() { +// let mut rb1 = (1..4).collect::(); +// let rb2 = (3..6).collect::(); +// let rb3 = ((1..3).chain(4..6)).collect::(); +// let rb4 = (0..0).collect::(); + +// assert_eq!(rb3, &rb1 ^ &rb2); +// assert_eq!(rb3, &rb1 ^ rb2.clone()); +// assert_eq!(rb3, rb1.clone() ^ &rb2); +// assert_eq!(rb3, rb1.clone() ^ rb2.clone()); +// assert_eq!(rb3.len(), rb1.symmetric_difference_len(&rb2)); + +// rb1 ^= &rb2; + +// assert_eq!(rb3, rb1); + +// rb1 ^= rb3; + +// assert_eq!(rb4, rb1); +// } diff --git a/tests/treemap_rank.rs b/tests/treemap_rank.rs index c05b4e6ea..71984cbcd 100644 --- a/tests/treemap_rank.rs +++ b/tests/treemap_rank.rs @@ -1,54 +1,54 @@ -extern crate roaring; - -use proptest::collection::{btree_set, vec}; -use proptest::prelude::*; -use roaring::RoaringTreemap; -use std::ops::RangeInclusive; - -const BITMAP_MAX: u64 = u32::MAX as u64; - -#[test] -fn rank_roaring_bitmaps() { - // A treemap with two roaring bitmaps. - // The lower one contains one array container with the highest 1000 values - // The higher one contains one bitmap at with the lowest 5000 values - let treemap = RoaringTreemap::from_sorted_iter(BITMAP_MAX - 1000..BITMAP_MAX + 5000).unwrap(); - - // start of treemap - assert_eq!(treemap.rank(0), 0); - - // low boundary - assert_eq!(treemap.rank(BITMAP_MAX - 1002), 0); - assert_eq!(treemap.rank(BITMAP_MAX - 1001), 0); - assert_eq!(treemap.rank(BITMAP_MAX - 1000), 1); - - // middle range (spans two roaring bitmaps) - assert_eq!(treemap.rank(BITMAP_MAX - 1), 1000); - assert_eq!(treemap.rank(BITMAP_MAX), 1001); - assert_eq!(treemap.rank(BITMAP_MAX + 1), 1002); - - // high boundary - assert_eq!(treemap.rank(BITMAP_MAX + 4998), 5999); - assert_eq!(treemap.rank(BITMAP_MAX + 4999), 6000); - assert_eq!(treemap.rank(BITMAP_MAX + 5000), 6000); - - // end of treemap - assert_eq!(treemap.rank(u64::MAX), 6000); -} - -// A range that spans 2 roaring bitmaps with 2 containers each -const PROP_RANGE: RangeInclusive = BITMAP_MAX - (1 << 17)..=BITMAP_MAX + (1 << 17); - -proptest! { - #[test] - fn proptest_rank( - values in btree_set(PROP_RANGE, ..=1000), - checks in vec(PROP_RANGE, ..=100) - ){ - let treemap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); - for i in checks { - let expected = values.iter().take_while(|&&x| x <= i).count() as u64; - assert_eq!(treemap.rank(i), expected); - } - } -} +// extern crate roaring; + +// use proptest::collection::{btree_set, vec}; +// use proptest::prelude::*; +// use roaring::RoaringTreemap; +// use std::ops::RangeInclusive; + +// const BITMAP_MAX: u64 = u32::MAX as u64; + +// #[test] +// fn rank_roaring_bitmaps() { +// // A treemap with two roaring bitmaps. +// // The lower one contains one array container with the highest 1000 values +// // The higher one contains one bitmap at with the lowest 5000 values +// let treemap = RoaringTreemap::from_sorted_iter(BITMAP_MAX - 1000..BITMAP_MAX + 5000).unwrap(); + +// // start of treemap +// assert_eq!(treemap.rank(0), 0); + +// // low boundary +// assert_eq!(treemap.rank(BITMAP_MAX - 1002), 0); +// assert_eq!(treemap.rank(BITMAP_MAX - 1001), 0); +// assert_eq!(treemap.rank(BITMAP_MAX - 1000), 1); + +// // middle range (spans two roaring bitmaps) +// assert_eq!(treemap.rank(BITMAP_MAX - 1), 1000); +// assert_eq!(treemap.rank(BITMAP_MAX), 1001); +// assert_eq!(treemap.rank(BITMAP_MAX + 1), 1002); + +// // high boundary +// assert_eq!(treemap.rank(BITMAP_MAX + 4998), 5999); +// assert_eq!(treemap.rank(BITMAP_MAX + 4999), 6000); +// assert_eq!(treemap.rank(BITMAP_MAX + 5000), 6000); + +// // end of treemap +// assert_eq!(treemap.rank(u64::MAX), 6000); +// } + +// // A range that spans 2 roaring bitmaps with 2 containers each +// const PROP_RANGE: RangeInclusive = BITMAP_MAX - (1 << 17)..=BITMAP_MAX + (1 << 17); + +// proptest! { +// #[test] +// fn proptest_rank( +// values in btree_set(PROP_RANGE, ..=1000), +// checks in vec(PROP_RANGE, ..=100) +// ){ +// let treemap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); +// for i in checks { +// let expected = values.iter().take_while(|&&x| x <= i).count() as u64; +// assert_eq!(treemap.rank(i), expected); +// } +// } +// } diff --git a/tests/treemap_select.rs b/tests/treemap_select.rs index a568cefeb..312bc4ea2 100644 --- a/tests/treemap_select.rs +++ b/tests/treemap_select.rs @@ -1,44 +1,44 @@ -extern crate roaring; - -use proptest::collection::btree_set; -use proptest::prelude::*; -use roaring::RoaringTreemap; - -#[test] -fn select() { - let bitmap = (0..2000).collect::(); - - assert_eq!(bitmap.select(0), Some(0)); -} - -#[test] -fn select_multiple_bitmap() { - let mut bitmap = (0..100_000).collect::(); - bitmap.append(u32::MAX as u64..u32::MAX as u64 + 100_000).expect("sorted integers"); - - assert_eq!(bitmap.select(0), Some(0)); - assert_eq!(bitmap.select(99_999), Some(99_999)); - assert_eq!(bitmap.select(100_000), Some(u32::MAX as u64)); - assert_eq!(bitmap.select(199_999), Some(u32::MAX as u64 + 99_999)); - assert_eq!(bitmap.select(200_000), None); - assert_eq!(bitmap.select(u64::MAX), None); -} - -#[test] -fn select_empty() { - let bitmap = RoaringTreemap::new(); - - assert_eq!(bitmap.select(0), None); - assert_eq!(bitmap.select(1024), None); - assert_eq!(bitmap.select(u64::MAX), None); -} - -proptest! { - #[test] - fn proptest_select(values in btree_set(any::(), 1000)) { - let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); - for (i, value) in values.iter().cloned().enumerate() { - prop_assert_eq!(bitmap.select(i as u64), Some(value)); - } - } -} +// extern crate roaring; + +// use proptest::collection::btree_set; +// use proptest::prelude::*; +// use roaring::RoaringTreemap; + +// #[test] +// fn select() { +// let bitmap = (0..2000).collect::(); + +// assert_eq!(bitmap.select(0), Some(0)); +// } + +// #[test] +// fn select_multiple_bitmap() { +// let mut bitmap = (0..100_000).collect::(); +// bitmap.append(u32::MAX as u64..u32::MAX as u64 + 100_000).expect("sorted integers"); + +// assert_eq!(bitmap.select(0), Some(0)); +// assert_eq!(bitmap.select(99_999), Some(99_999)); +// assert_eq!(bitmap.select(100_000), Some(u32::MAX as u64)); +// assert_eq!(bitmap.select(199_999), Some(u32::MAX as u64 + 99_999)); +// assert_eq!(bitmap.select(200_000), None); +// assert_eq!(bitmap.select(u64::MAX), None); +// } + +// #[test] +// fn select_empty() { +// let bitmap = RoaringTreemap::new(); + +// assert_eq!(bitmap.select(0), None); +// assert_eq!(bitmap.select(1024), None); +// assert_eq!(bitmap.select(u64::MAX), None); +// } + +// proptest! { +// #[test] +// fn proptest_select(values in btree_set(any::(), 1000)) { +// let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); +// for (i, value) in values.iter().cloned().enumerate() { +// prop_assert_eq!(bitmap.select(i as u64), Some(value)); +// } +// } +// } diff --git a/tests/treemap_serialization.rs b/tests/treemap_serialization.rs index bf38bb3d6..303ff7b3d 100644 --- a/tests/treemap_serialization.rs +++ b/tests/treemap_serialization.rs @@ -1,44 +1,44 @@ -use roaring::RoaringTreemap; -use std::iter::FromIterator; - -fn serialize_deserialize(dataset: Dataset) -where - Dataset: IntoIterator, - I: Iterator, -{ - let rb = RoaringTreemap::from_iter(dataset); - - let mut buffer = vec![]; - rb.serialize_into(&mut buffer).unwrap(); - - assert_eq!(buffer.len(), rb.serialized_size()); - - let new_rb = RoaringTreemap::deserialize_from(&buffer[..]).unwrap(); - - assert_eq!(rb, new_rb); -} - -#[test] -fn empty() { - serialize_deserialize(vec![]) -} - -#[test] -fn basic() { - serialize_deserialize(vec![1, 2, 3, 4, 5, 100, 1000]) -} - -#[test] -fn basic_2() { - serialize_deserialize(vec![1, 2, 3, 4, 5, 100, 1000, 10000, 100000, 1000000]) -} - -#[test] -fn basic_3() { - let u32max = u32::MAX as u64; - serialize_deserialize( - vec![1, 2, 3, 4, 5, 100, 1000, 10000, 100000, 1000000, u32max + 10, u32max << 10] - .into_iter() - .chain(u32max..(u32max + 2 * (1 << 16))), - ) -} +// use roaring::RoaringTreemap; +// use std::iter::FromIterator; + +// fn serialize_deserialize(dataset: Dataset) +// where +// Dataset: IntoIterator, +// I: Iterator, +// { +// let rb = RoaringTreemap::from_iter(dataset); + +// let mut buffer = vec![]; +// rb.serialize_into(&mut buffer).unwrap(); + +// assert_eq!(buffer.len(), rb.serialized_size()); + +// let new_rb = RoaringTreemap::deserialize_from(&buffer[..]).unwrap(); + +// assert_eq!(rb, new_rb); +// } + +// #[test] +// fn empty() { +// serialize_deserialize(vec![]) +// } + +// #[test] +// fn basic() { +// serialize_deserialize(vec![1, 2, 3, 4, 5, 100, 1000]) +// } + +// #[test] +// fn basic_2() { +// serialize_deserialize(vec![1, 2, 3, 4, 5, 100, 1000, 10000, 100000, 1000000]) +// } + +// #[test] +// fn basic_3() { +// let u32max = u32::MAX as u64; +// serialize_deserialize( +// vec![1, 2, 3, 4, 5, 100, 1000, 10000, 100000, 1000000, u32max + 10, u32max << 10] +// .into_iter() +// .chain(u32max..(u32max + 2 * (1 << 16))), +// ) +// } diff --git a/tests/treemap_size_hint.rs b/tests/treemap_size_hint.rs index 186464d0b..367fd671c 100644 --- a/tests/treemap_size_hint.rs +++ b/tests/treemap_size_hint.rs @@ -1,52 +1,52 @@ -extern crate roaring; -use roaring::RoaringTreemap; +// extern crate roaring; +// use roaring::RoaringTreemap; -#[test] -fn array() { - let bitmap = (0..2000).collect::(); - let mut iter = bitmap.iter(); - assert_eq!((2000, Some(2000)), iter.size_hint()); - iter.by_ref().take(1000).for_each(drop); - assert_eq!((1000, Some(1000)), iter.size_hint()); - iter.by_ref().for_each(drop); - assert_eq!((0, Some(0)), iter.size_hint()); -} +// #[test] +// fn array() { +// let bitmap = (0..2000).collect::(); +// let mut iter = bitmap.iter(); +// assert_eq!((2000, Some(2000)), iter.size_hint()); +// iter.by_ref().take(1000).for_each(drop); +// assert_eq!((1000, Some(1000)), iter.size_hint()); +// iter.by_ref().for_each(drop); +// assert_eq!((0, Some(0)), iter.size_hint()); +// } -#[test] -fn bitmap() { - let bitmap = (0..6000).collect::(); - let mut iter = bitmap.iter(); - assert_eq!((6000, Some(6000)), iter.size_hint()); - iter.by_ref().take(3000).for_each(drop); - assert_eq!((3000, Some(3000)), iter.size_hint()); - iter.by_ref().for_each(drop); - assert_eq!((0, Some(0)), iter.size_hint()); -} +// #[test] +// fn bitmap() { +// let bitmap = (0..6000).collect::(); +// let mut iter = bitmap.iter(); +// assert_eq!((6000, Some(6000)), iter.size_hint()); +// iter.by_ref().take(3000).for_each(drop); +// assert_eq!((3000, Some(3000)), iter.size_hint()); +// iter.by_ref().for_each(drop); +// assert_eq!((0, Some(0)), iter.size_hint()); +// } -#[test] -fn arrays() { - let bitmap = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) - .collect::(); - let mut iter = bitmap.iter(); - assert_eq!((5000, Some(5000)), iter.size_hint()); - iter.by_ref().take(3000).for_each(drop); - assert_eq!((2000, Some(2000)), iter.size_hint()); - iter.by_ref().for_each(drop); - assert_eq!((0, Some(0)), iter.size_hint()); -} +// #[test] +// fn arrays() { +// let bitmap = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) +// .collect::(); +// let mut iter = bitmap.iter(); +// assert_eq!((5000, Some(5000)), iter.size_hint()); +// iter.by_ref().take(3000).for_each(drop); +// assert_eq!((2000, Some(2000)), iter.size_hint()); +// iter.by_ref().for_each(drop); +// assert_eq!((0, Some(0)), iter.size_hint()); +// } -#[test] -fn bitmaps() { - let bitmap = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) - .collect::(); - let mut iter = bitmap.iter(); - assert_eq!((28000, Some(28000)), iter.size_hint()); - iter.by_ref().take(2000).for_each(drop); - assert_eq!((26000, Some(26000)), iter.size_hint()); - iter.by_ref().take(5000).for_each(drop); - assert_eq!((21000, Some(21000)), iter.size_hint()); - iter.by_ref().take(20000).for_each(drop); - assert_eq!((1000, Some(1000)), iter.size_hint()); - iter.by_ref().for_each(drop); - assert_eq!((0, Some(0)), iter.size_hint()); -} +// #[test] +// fn bitmaps() { +// let bitmap = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) +// .collect::(); +// let mut iter = bitmap.iter(); +// assert_eq!((28000, Some(28000)), iter.size_hint()); +// iter.by_ref().take(2000).for_each(drop); +// assert_eq!((26000, Some(26000)), iter.size_hint()); +// iter.by_ref().take(5000).for_each(drop); +// assert_eq!((21000, Some(21000)), iter.size_hint()); +// iter.by_ref().take(20000).for_each(drop); +// assert_eq!((1000, Some(1000)), iter.size_hint()); +// iter.by_ref().for_each(drop); +// assert_eq!((0, Some(0)), iter.size_hint()); +// } diff --git a/tests/treemap_symmetric_difference_with.rs b/tests/treemap_symmetric_difference_with.rs index 2dba2bf5e..176527da3 100644 --- a/tests/treemap_symmetric_difference_with.rs +++ b/tests/treemap_symmetric_difference_with.rs @@ -1,116 +1,116 @@ -extern crate roaring; -use roaring::RoaringTreemap; +// extern crate roaring; +// use roaring::RoaringTreemap; -#[test] -fn array() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..3000).collect::(); - let bitmap3 = ((0..1000).chain(2000..3000)).collect::(); - - bitmap1 ^= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} - -#[test] -fn no_symmetric_difference() { - let mut bitmap1 = (0..2).collect::(); - let bitmap2 = (0..2).collect::(); - - bitmap1 ^= bitmap2; - - assert_eq!(bitmap1, RoaringTreemap::new()); -} - -#[test] -fn array_and_bitmap() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..8000).collect::(); - let bitmap3 = ((0..1000).chain(2000..8000)).collect::(); - - bitmap1 ^= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} - -#[test] -fn bitmap_to_bitmap() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (6000..18000).collect::(); - let bitmap3 = ((0..6000).chain(12000..18000)).collect::(); - - bitmap1 ^= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} - -#[test] -fn bitmap_to_array() { - let mut bitmap1 = (0..6000).collect::(); - let bitmap2 = (2000..7000).collect::(); - let bitmap3 = ((0..2000).chain(6000..7000)).collect::(); - - bitmap1 ^= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} - -#[test] -fn bitmap_and_array_to_bitmap() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (11000..14000).collect::(); - let bitmap3 = ((0..11000).chain(12000..14000)).collect::(); - - bitmap1 ^= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} - -#[test] -fn bitmap_and_array_to_array() { - let mut bitmap1 = (0..6000).collect::(); - let bitmap2 = (3000..7000).collect::(); - let bitmap3 = ((0..3000).chain(6000..7000)).collect::(); - - bitmap1 ^= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} - -#[test] -fn arrays() { - let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)) - .collect::(); - let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_000_001)) - .collect::(); - let bitmap3 = ((0..1000) - .chain(1_000_000..1_001_000) - .chain(2000..3000) - .chain(1_002_000..1_003_000) - .chain(2_000_000..2_000_001) - .chain(3_000_000..3_001_000)) - .collect::(); - - bitmap1 ^= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} - -#[test] -fn bitmaps() { - let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)) - .collect::(); - let bitmap2 = ((3000..7000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) - .collect::(); - let bitmap3 = ((0..3000) - .chain(1_000_000..1_006_000) - .chain(6000..7000) - .chain(1_012_000..1_018_000) - .chain(2_000_000..2_010_000) - .chain(3_000_000..3_010_000)) - .collect::(); - - bitmap1 ^= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} +// #[test] +// fn array() { +// let mut bitmap1 = (0..2000).collect::(); +// let bitmap2 = (1000..3000).collect::(); +// let bitmap3 = ((0..1000).chain(2000..3000)).collect::(); + +// bitmap1 ^= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } + +// #[test] +// fn no_symmetric_difference() { +// let mut bitmap1 = (0..2).collect::(); +// let bitmap2 = (0..2).collect::(); + +// bitmap1 ^= bitmap2; + +// assert_eq!(bitmap1, RoaringTreemap::new()); +// } + +// #[test] +// fn array_and_bitmap() { +// let mut bitmap1 = (0..2000).collect::(); +// let bitmap2 = (1000..8000).collect::(); +// let bitmap3 = ((0..1000).chain(2000..8000)).collect::(); + +// bitmap1 ^= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } + +// #[test] +// fn bitmap_to_bitmap() { +// let mut bitmap1 = (0..12000).collect::(); +// let bitmap2 = (6000..18000).collect::(); +// let bitmap3 = ((0..6000).chain(12000..18000)).collect::(); + +// bitmap1 ^= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } + +// #[test] +// fn bitmap_to_array() { +// let mut bitmap1 = (0..6000).collect::(); +// let bitmap2 = (2000..7000).collect::(); +// let bitmap3 = ((0..2000).chain(6000..7000)).collect::(); + +// bitmap1 ^= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } + +// #[test] +// fn bitmap_and_array_to_bitmap() { +// let mut bitmap1 = (0..12000).collect::(); +// let bitmap2 = (11000..14000).collect::(); +// let bitmap3 = ((0..11000).chain(12000..14000)).collect::(); + +// bitmap1 ^= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } + +// #[test] +// fn bitmap_and_array_to_array() { +// let mut bitmap1 = (0..6000).collect::(); +// let bitmap2 = (3000..7000).collect::(); +// let bitmap3 = ((0..3000).chain(6000..7000)).collect::(); + +// bitmap1 ^= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } + +// #[test] +// fn arrays() { +// let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)) +// .collect::(); +// let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_000_001)) +// .collect::(); +// let bitmap3 = ((0..1000) +// .chain(1_000_000..1_001_000) +// .chain(2000..3000) +// .chain(1_002_000..1_003_000) +// .chain(2_000_000..2_000_001) +// .chain(3_000_000..3_001_000)) +// .collect::(); + +// bitmap1 ^= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } + +// #[test] +// fn bitmaps() { +// let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)) +// .collect::(); +// let bitmap2 = ((3000..7000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) +// .collect::(); +// let bitmap3 = ((0..3000) +// .chain(1_000_000..1_006_000) +// .chain(6000..7000) +// .chain(1_012_000..1_018_000) +// .chain(2_000_000..2_010_000) +// .chain(3_000_000..3_010_000)) +// .collect::(); + +// bitmap1 ^= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } diff --git a/tests/treemap_union_with.rs b/tests/treemap_union_with.rs index e370b6abb..374a4dbd3 100644 --- a/tests/treemap_union_with.rs +++ b/tests/treemap_union_with.rs @@ -1,91 +1,91 @@ -extern crate roaring; -use roaring::RoaringTreemap; - -#[test] -fn array_to_array() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..3000).collect::(); - let bitmap3 = (0..3000).collect::(); - - bitmap1 |= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} - -#[test] -fn array_to_bitmap() { - let mut bitmap1 = (0..4000).collect::(); - let bitmap2 = (4000..8000).collect::(); - let bitmap3 = (0..8000).collect::(); - - bitmap1 |= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} - -#[test] -fn array_and_bitmap() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..8000).collect::(); - let bitmap3 = (0..8000).collect::(); - - bitmap1 |= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} - -#[test] -fn bitmap() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (6000..18000).collect::(); - let bitmap3 = (0..18000).collect::(); - - bitmap1 |= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} - -#[test] -fn bitmap_and_array() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (10000..13000).collect::(); - let bitmap3 = (0..13000).collect::(); - - bitmap1 |= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} - -#[test] -fn arrays() { - let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)) - .collect::(); - let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) - .collect::(); - let bitmap3 = ((0..3000) - .chain(1_000_000..1_003_000) - .chain(2_000_000..2_001_000) - .chain(3_000_000..3_001_000)) - .collect::(); - - bitmap1 |= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} - -#[test] -fn bitmaps() { - let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)) - .collect::(); - let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) - .collect::(); - let bitmap3 = ((0..9000) - .chain(1_000_000..1_018_000) - .chain(2_000_000..2_010_000) - .chain(3_000_000..3_010_000)) - .collect::(); - - bitmap1 |= bitmap2; - - assert_eq!(bitmap1, bitmap3); -} +// extern crate roaring; +// use roaring::RoaringTreemap; + +// #[test] +// fn array_to_array() { +// let mut bitmap1 = (0..2000).collect::(); +// let bitmap2 = (1000..3000).collect::(); +// let bitmap3 = (0..3000).collect::(); + +// bitmap1 |= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } + +// #[test] +// fn array_to_bitmap() { +// let mut bitmap1 = (0..4000).collect::(); +// let bitmap2 = (4000..8000).collect::(); +// let bitmap3 = (0..8000).collect::(); + +// bitmap1 |= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } + +// #[test] +// fn array_and_bitmap() { +// let mut bitmap1 = (0..2000).collect::(); +// let bitmap2 = (1000..8000).collect::(); +// let bitmap3 = (0..8000).collect::(); + +// bitmap1 |= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } + +// #[test] +// fn bitmap() { +// let mut bitmap1 = (0..12000).collect::(); +// let bitmap2 = (6000..18000).collect::(); +// let bitmap3 = (0..18000).collect::(); + +// bitmap1 |= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } + +// #[test] +// fn bitmap_and_array() { +// let mut bitmap1 = (0..12000).collect::(); +// let bitmap2 = (10000..13000).collect::(); +// let bitmap3 = (0..13000).collect::(); + +// bitmap1 |= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } + +// #[test] +// fn arrays() { +// let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)) +// .collect::(); +// let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) +// .collect::(); +// let bitmap3 = ((0..3000) +// .chain(1_000_000..1_003_000) +// .chain(2_000_000..2_001_000) +// .chain(3_000_000..3_001_000)) +// .collect::(); + +// bitmap1 |= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } + +// #[test] +// fn bitmaps() { +// let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)) +// .collect::(); +// let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) +// .collect::(); +// let bitmap3 = ((0..9000) +// .chain(1_000_000..1_018_000) +// .chain(2_000_000..2_010_000) +// .chain(3_000_000..3_010_000)) +// .collect::(); + +// bitmap1 |= bitmap2; + +// assert_eq!(bitmap1, bitmap3); +// } diff --git a/tests/union_with.rs b/tests/union_with.rs index 765b82951..488c1e5eb 100644 --- a/tests/union_with.rs +++ b/tests/union_with.rs @@ -1,11 +1,10 @@ -extern crate roaring; -use roaring::RoaringBitmap; +use roaring::Roaring32; #[test] fn array_to_array() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..3000).collect::(); - let bitmap3 = (0..3000).collect::(); + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..3000).collect::(); + let bitmap3 = (0..3000).collect::(); bitmap1 |= bitmap2; @@ -14,9 +13,9 @@ fn array_to_array() { #[test] fn array_to_bitmap() { - let mut bitmap1 = (0..4000).collect::(); - let bitmap2 = (4000..8000).collect::(); - let bitmap3 = (0..8000).collect::(); + let mut bitmap1 = (0..4000).collect::(); + let bitmap2 = (4000..8000).collect::(); + let bitmap3 = (0..8000).collect::(); bitmap1 |= bitmap2; @@ -25,9 +24,9 @@ fn array_to_bitmap() { #[test] fn array_and_bitmap() { - let mut bitmap1 = (0..2000).collect::(); - let bitmap2 = (1000..8000).collect::(); - let bitmap3 = (0..8000).collect::(); + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..8000).collect::(); + let bitmap3 = (0..8000).collect::(); bitmap1 |= bitmap2; @@ -36,9 +35,9 @@ fn array_and_bitmap() { #[test] fn bitmap() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (6000..18000).collect::(); - let bitmap3 = (0..18000).collect::(); + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (6000..18000).collect::(); + let bitmap3 = (0..18000).collect::(); bitmap1 |= bitmap2; @@ -47,9 +46,9 @@ fn bitmap() { #[test] fn bitmap_and_array() { - let mut bitmap1 = (0..12000).collect::(); - let bitmap2 = (10000..13000).collect::(); - let bitmap3 = (0..13000).collect::(); + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (10000..13000).collect::(); + let bitmap3 = (0..13000).collect::(); bitmap1 |= bitmap2; @@ -58,19 +57,15 @@ fn bitmap_and_array() { #[test] fn arrays() { - let mut bitmap1 = (0..2000) - .chain(1_000_000..1_002_000) - .chain(3_000_000..3_001_000) - .collect::(); - let bitmap2 = (1000..3000) - .chain(1_001_000..1_003_000) - .chain(2_000_000..2_001_000) - .collect::(); + let mut bitmap1 = + (0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000).collect::(); + let bitmap2 = + (1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000).collect::(); let bitmap3 = (0..3000) .chain(1_000_000..1_003_000) .chain(2_000_000..2_001_000) .chain(3_000_000..3_001_000) - .collect::(); + .collect::(); bitmap1 |= bitmap2; @@ -79,19 +74,15 @@ fn arrays() { #[test] fn bitmaps() { - let mut bitmap1 = (0..6000) - .chain(1_000_000..1_012_000) - .chain(3_000_000..3_010_000) - .collect::(); - let bitmap2 = (3000..9000) - .chain(1_006_000..1_018_000) - .chain(2_000_000..2_010_000) - .collect::(); + let mut bitmap1 = + (0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000).collect::(); + let bitmap2 = + (3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000).collect::(); let bitmap3 = (0..9000) .chain(1_000_000..1_018_000) .chain(2_000_000..2_010_000) .chain(3_000_000..3_010_000) - .collect::(); + .collect::(); bitmap1 |= bitmap2; From 10e6ecdcc961bfbe79cd1e8e91ddb8e2ed82bf13 Mon Sep 17 00:00:00 2001 From: Sylvain Laperche Date: Fri, 11 Aug 2023 21:40:27 +0200 Subject: [PATCH 2/4] replace RoaringTreemap by TwoLevelRoaringBitmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Benchmark results on insert_range (only bench available for 64-bit): group roaring64 treemap ----- --------- ------- from_empty_1000 1.00 87.6±4.76ns 10.6 GElem/sec 1.65 144.2±1.28ns 6.5 GElem/sec from_empty_10000 1.00 166.8±9.32ns 55.8 GElem/sec 1.28 213.6±7.26ns 43.6 GElem/sec from_empty_8589934590 1.01 151.5±0.99ms 52.8 GElem/sec 1.00 149.7±1.00ms 53.5 GElem/sec pre_populated_1000 1.00 139.3±19.83ns 6.7 GElem/sec 1.30 180.8±20.70ns 5.2 GElem/sec pre_populated_10000 1.00 235.4±83.29ns 39.6 GElem/sec 1.26 295.9±106.25ns 31.5 GElem/sec pre_populated_8589934590 1.00 74.8±2.56ms 107.0 GElem/sec 1.01 75.3±1.82ms 106.3 GElem/sec --- benchmarks/benches/lib.rs | 68 ++- src/lib.rs | 8 +- src/roaring64.rs | 140 +++++ src/treemap/arbitrary.rs | 17 - src/treemap/cmp.rs | 137 ----- src/treemap/fmt.rs | 19 - src/treemap/inherent.rs | 432 --------------- src/treemap/iter.rs | 367 ------------- src/treemap/mod.rs | 41 -- src/treemap/multiops.rs | 377 ------------- src/treemap/ops.rs | 541 ------------------- src/treemap/serde.rs | 82 --- src/treemap/serialization.rs | 135 ----- src/treemap/util.rs | 72 --- tests/push.rs | 12 +- tests/roaring64_clone.rs | 39 ++ tests/roaring64_difference_with.rs | 116 ++++ tests/roaring64_intersect_with.rs | 92 ++++ tests/roaring64_is_disjoint.rs | 61 +++ tests/roaring64_is_subset.rs | 79 +++ tests/roaring64_iter.rs | 115 ++++ tests/roaring64_lib.rs | 118 ++++ tests/roaring64_ops.rs | 77 +++ tests/roaring64_rank.rs | 54 ++ tests/roaring64_select.rs | 41 ++ tests/roaring64_serialization.rs | 44 ++ tests/roaring64_size_hint.rs | 51 ++ tests/roaring64_symmetric_difference_with.rs | 115 ++++ tests/roaring64_union_with.rs | 90 +++ tests/treemap_clone.rs | 40 -- tests/treemap_difference_with.rs | 117 ---- tests/treemap_intersect_with.rs | 93 ---- tests/treemap_is_disjoint.rs | 62 --- tests/treemap_is_subset.rs | 80 --- tests/treemap_iter.rs | 129 ----- tests/treemap_lib.rs | 119 ---- tests/treemap_ops.rs | 78 --- tests/treemap_rank.rs | 54 -- tests/treemap_select.rs | 44 -- tests/treemap_serialization.rs | 44 -- tests/treemap_size_hint.rs | 52 -- tests/treemap_symmetric_difference_with.rs | 116 ---- tests/treemap_union_with.rs | 91 ---- 43 files changed, 1275 insertions(+), 3384 deletions(-) create mode 100644 src/roaring64.rs delete mode 100644 src/treemap/arbitrary.rs delete mode 100644 src/treemap/cmp.rs delete mode 100644 src/treemap/fmt.rs delete mode 100644 src/treemap/inherent.rs delete mode 100644 src/treemap/iter.rs delete mode 100644 src/treemap/mod.rs delete mode 100644 src/treemap/multiops.rs delete mode 100644 src/treemap/ops.rs delete mode 100644 src/treemap/serde.rs delete mode 100644 src/treemap/serialization.rs delete mode 100644 src/treemap/util.rs create mode 100644 tests/roaring64_clone.rs create mode 100644 tests/roaring64_difference_with.rs create mode 100644 tests/roaring64_intersect_with.rs create mode 100644 tests/roaring64_is_disjoint.rs create mode 100644 tests/roaring64_is_subset.rs create mode 100644 tests/roaring64_iter.rs create mode 100644 tests/roaring64_lib.rs create mode 100644 tests/roaring64_ops.rs create mode 100644 tests/roaring64_rank.rs create mode 100644 tests/roaring64_select.rs create mode 100644 tests/roaring64_serialization.rs create mode 100644 tests/roaring64_size_hint.rs create mode 100644 tests/roaring64_symmetric_difference_with.rs create mode 100644 tests/roaring64_union_with.rs delete mode 100644 tests/treemap_clone.rs delete mode 100644 tests/treemap_difference_with.rs delete mode 100644 tests/treemap_intersect_with.rs delete mode 100644 tests/treemap_is_disjoint.rs delete mode 100644 tests/treemap_is_subset.rs delete mode 100644 tests/treemap_iter.rs delete mode 100644 tests/treemap_lib.rs delete mode 100644 tests/treemap_ops.rs delete mode 100644 tests/treemap_rank.rs delete mode 100644 tests/treemap_select.rs delete mode 100644 tests/treemap_serialization.rs delete mode 100644 tests/treemap_size_hint.rs delete mode 100644 tests/treemap_symmetric_difference_with.rs delete mode 100644 tests/treemap_union_with.rs diff --git a/benchmarks/benches/lib.rs b/benchmarks/benches/lib.rs index db75ed2fd..e6e6055b9 100644 --- a/benchmarks/benches/lib.rs +++ b/benchmarks/benches/lib.rs @@ -1,16 +1,14 @@ -use itertools::Itertools; -use std::cmp::Reverse; -use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; - -use criterion::measurement::Measurement; +use crate::datasets::Datasets; use criterion::{ - black_box, criterion_group, criterion_main, BatchSize, BenchmarkGroup, BenchmarkId, Criterion, - Throughput, + black_box, criterion_group, criterion_main, measurement::Measurement, BatchSize, + BenchmarkGroup, BenchmarkId, Criterion, Throughput, +}; +use itertools::Itertools; +use roaring::{MultiOps, Roaring32, Roaring64}; +use std::{ + cmp::Reverse, + ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}, }; - -use roaring::{MultiOps, Roaring32}; - -use crate::datasets::Datasets; mod datasets; @@ -670,29 +668,29 @@ fn insert_range_bitmap(c: &mut Criterion) { } } -// fn insert_range_treemap(c: &mut Criterion) { -// for &size in &[1_000_u64, 10_000u64, 2 * (u32::MAX as u64)] { -// let mut group = c.benchmark_group("insert_range_treemap"); -// group.throughput(criterion::Throughput::Elements(size)); -// group.bench_function(format!("from_empty_{}", size), |b| { -// let bm = RoaringTreemap::new(); -// b.iter_batched( -// || bm.clone(), -// |mut bm| black_box(bm.insert_range(0..size)), -// criterion::BatchSize::SmallInput, -// ) -// }); -// group.bench_function(format!("pre_populated_{}", size), |b| { -// let mut bm = RoaringTreemap::new(); -// bm.insert_range(0..size); -// b.iter_batched( -// || bm.clone(), -// |mut bm| black_box(bm.insert_range(0..size)), -// criterion::BatchSize::SmallInput, -// ) -// }); -// } -// } +fn insert_range_roaring64(c: &mut Criterion) { + for &size in &[1_000_u64, 10_000u64, 2 * (u32::MAX as u64)] { + let mut group = c.benchmark_group("insert_range_roaring64"); + group.throughput(criterion::Throughput::Elements(size)); + group.bench_function(format!("from_empty_{}", size), |b| { + let bm = Roaring64::new(); + b.iter_batched( + || bm.clone(), + |mut bm| black_box(bm.insert_range(0..size)), + criterion::BatchSize::SmallInput, + ) + }); + group.bench_function(format!("pre_populated_{}", size), |b| { + let mut bm = Roaring64::new(); + bm.insert_range(0..size); + b.iter_batched( + || bm.clone(), + |mut bm| black_box(bm.insert_range(0..size)), + criterion::BatchSize::SmallInput, + ) + }); + } +} criterion_group!( benches, @@ -711,7 +709,7 @@ criterion_group!( remove, remove_range_bitmap, insert_range_bitmap, - // insert_range_treemap, + insert_range_roaring64, iteration, is_empty, serialization, diff --git a/src/lib.rs b/src/lib.rs index cd9333c05..4cf29d4f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,15 +20,15 @@ use std::fmt; mod core; -/// A compressed bitmap with u64 values. Implemented as a `BTreeMap` of `RoaringBitmap`s. -// pub mod treemap; -// pub use treemap::RoaringTreemap; mod value; pub use value::{ContainerKey, Value, ValueRange}; mod roaring32; pub use roaring32::Roaring32; +mod roaring64; +pub use roaring64::Roaring64; + pub use self::core::RoaringBitmap; /// An error type that is returned when an iterator isn't sorted. @@ -53,7 +53,7 @@ impl fmt::Display for NonSortedIntegers { impl Error for NonSortedIntegers {} /// A [`Iterator::collect`] blanket implementation that provides extra methods for [`Roaring32`] -/// and [`RoaringTreemap`]. +/// and [`Roaring64`]. /// /// When merging multiple bitmap with the same operation it's usually faster to call the /// method in this trait than to write your own for loop and merging the bitmaps yourself. diff --git a/src/roaring64.rs b/src/roaring64.rs new file mode 100644 index 000000000..d8782847a --- /dev/null +++ b/src/roaring64.rs @@ -0,0 +1,140 @@ +use crate::{ContainerKey, RoaringBitmap, Value, ValueRange}; +use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; +use std::{ + io, + ops::{Bound, RangeBounds, RangeInclusive}, +}; + +/// A compressed bitmap for 64-bit values. +/// +/// # Examples +/// +/// ```rust +/// use roaring::Roaring64; +/// +/// let mut rb = Roaring64::new(); +/// +/// // insert all primes less than 10 +/// rb.insert(2); +/// rb.insert(3); +/// rb.insert(5); +/// rb.insert(7); +/// println!("total bits set to true: {}", rb.len()); +/// ``` +pub type Roaring64 = RoaringBitmap; + +impl Value for u64 { + type Key = u64; + type Range = RangeInclusive; + + fn split(self) -> (Self::Key, u16) { + (self >> 16, self as u16) + } + + fn join(key: Self::Key, index: u16) -> Self { + (key << 16) + u64::from(index) + } + + fn range(range: impl RangeBounds) -> Option { + let start: u64 = match range.start_bound() { + Bound::Included(&i) => i, + Bound::Excluded(&i) => i.checked_add(1)?, + Bound::Unbounded => 0, + }; + let end: u64 = match range.end_bound() { + Bound::Included(&i) => i, + Bound::Excluded(&i) => i.checked_sub(1)?, + Bound::Unbounded => u64::MAX, + }; + + if end < start { + return None; + } + + Some(start..=end) + } + + fn max_containers() -> usize { + // Theoretically, u64::MAX + 1. + // Realistically we're probably capped at usize anyway. + usize::MAX + } +} + +impl ContainerKey for u64 { + #[inline(always)] + fn size() -> usize { + // Key is coded on 48-bit, the 16 upper ones are unused. + 6 + } + + fn write(self, writer: &mut impl WriteBytesExt) -> io::Result<()> { + writer.write_u48::(self) + } + + fn read(reader: &mut impl ReadBytesExt) -> io::Result { + reader.read_u48::() + } +} + +impl ValueRange for RangeInclusive { + type KeyIterator = RangeInclusive; + + fn start(&self) -> (::Key, u16) { + self.start().split() + } + + fn end(&self) -> (::Key, u16) { + self.end().split() + } + + fn containers_count(&self) -> usize { + let start = ValueRange::start(self).0; + let end = ValueRange::end(self).0; + (end - start) as usize + 1 + } + + fn keys(self) -> Self::KeyIterator { + let start = ValueRange::start(&self).0; + let end = ValueRange::end(&self).0; + start..=end + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn split() { + assert_eq!((0x0000_0000_0000u64, 0x0000u16), 0x0000_0000_0000_0000u64.split()); + assert_eq!((0x0000_0000_0000u64, 0x0001u16), 0x0000_0000_0000_0001u64.split()); + assert_eq!((0x0000_0000_FFFFu64, 0xFFFEu16), 0x0000_0000_FFFF_FFFEu64.split()); + assert_eq!((0x0000_0000_FFFFu64, 0xFFFFu16), 0x0000_0000_FFFF_FFFFu64.split()); + assert_eq!((0x0000_0001_0000u64, 0x0000u16), 0x0000_0001_0000_0000u64.split()); + assert_eq!((0x0000_0001_0000u64, 0x0001u16), 0x0000_0001_0000_0001u64.split()); + assert_eq!((0xFFFF_FFFF_FFFFu64, 0xFFFEu16), 0xFFFF_FFFF_FFFF_FFFEu64.split()); + assert_eq!((0xFFFF_FFFF_FFFFu64, 0xFFFFu16), 0xFFFF_FFFF_FFFF_FFFFu64.split()); + } + + #[test] + fn join() { + assert_eq!(0x0000_0000_0000_0000u64, u64::join(0x0000_0000_0000u64, 0x0000u16)); + assert_eq!(0x0000_0000_0000_0001u64, u64::join(0x0000_0000_0000u64, 0x0001u16)); + assert_eq!(0x0000_0000_FFFF_FFFEu64, u64::join(0x0000_0000_FFFFu64, 0xFFFEu16)); + assert_eq!(0x0000_0000_FFFF_FFFFu64, u64::join(0x0000_0000_FFFFu64, 0xFFFFu16)); + assert_eq!(0x0000_0001_0000_0000u64, u64::join(0x0000_0001_0000u64, 0x0000u16)); + assert_eq!(0x0000_0001_0000_0001u64, u64::join(0x0000_0001_0000u64, 0x0001u16)); + assert_eq!(0xFFFF_FFFF_FFFF_FFFEu64, u64::join(0xFFFF_FFFF_FFFFu64, 0xFFFEu16)); + assert_eq!(0xFFFF_FFFF_FFFF_FFFFu64, u64::join(0xFFFF_FFFF_FFFFu64, 0xFFFFu16)); + } + + #[test] + fn range() { + assert_eq!(Some(1..=5), u64::range(1..6)); + assert_eq!(Some(1..=u64::MAX), u64::range(1..)); + assert_eq!(Some(0..=u64::MAX), u64::range(..)); + assert_eq!(None, u64::range(5..5)); + assert_eq!(Some(16..=16), u64::range(16..=16)) + } +} diff --git a/src/treemap/arbitrary.rs b/src/treemap/arbitrary.rs deleted file mode 100644 index c7adb7d5c..000000000 --- a/src/treemap/arbitrary.rs +++ /dev/null @@ -1,17 +0,0 @@ -#[cfg(test)] -mod test { - use crate::{RoaringBitmap, RoaringTreemap}; - use proptest::collection::btree_map; - use proptest::prelude::*; - - impl RoaringTreemap { - prop_compose! { - pub fn arbitrary()(map in btree_map(0u32..=16, RoaringBitmap::arbitrary(), 0usize..=16)) -> RoaringTreemap { - // we’re NEVER supposed to start with a treemap containing empty bitmaps - // Since we can’t configure this in arbitrary we’re simply going to ignore the generated empty bitmaps - let map = map.into_iter().filter(|(_, v)| !v.is_empty()).collect(); - RoaringTreemap { map } - } - } - } -} diff --git a/src/treemap/cmp.rs b/src/treemap/cmp.rs deleted file mode 100644 index c55fd228a..000000000 --- a/src/treemap/cmp.rs +++ /dev/null @@ -1,137 +0,0 @@ -use std::collections::btree_map; -use std::iter::Peekable; - -use crate::RoaringBitmap; -use crate::RoaringTreemap; - -pub(crate) struct Pairs<'a>( - Peekable>, - Peekable>, -); - -impl RoaringTreemap { - pub(crate) fn pairs<'a>(&'a self, other: &'a RoaringTreemap) -> Pairs<'a> { - Pairs(self.map.iter().peekable(), other.map.iter().peekable()) - } - - /// Returns true if the set has no elements in common with other. This is equivalent to - /// checking for an empty intersection. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb1 = RoaringTreemap::new(); - /// let mut rb2 = RoaringTreemap::new(); - /// - /// rb1.insert(1); - /// - /// assert_eq!(rb1.is_disjoint(&rb2), true); - /// - /// rb2.insert(1); - /// - /// assert_eq!(rb1.is_disjoint(&rb2), false); - /// - /// ``` - pub fn is_disjoint(&self, other: &Self) -> bool { - self.pairs(other) - .filter(|&(c1, c2)| c1.is_some() && c2.is_some()) - .all(|(c1, c2)| c1.unwrap().is_disjoint(c2.unwrap())) - } - - /// Returns `true` if this set is a subset of `other`. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb1 = RoaringTreemap::new(); - /// let mut rb2 = RoaringTreemap::new(); - /// - /// rb1.insert(1); - /// - /// assert_eq!(rb1.is_subset(&rb2), false); - /// - /// rb2.insert(1); - /// - /// assert_eq!(rb1.is_subset(&rb2), true); - /// - /// rb1.insert(2); - /// - /// assert_eq!(rb1.is_subset(&rb2), false); - /// ``` - pub fn is_subset(&self, other: &Self) -> bool { - for pair in self.pairs(other) { - match pair { - (None, _) => (), - (_, None) => { - return false; - } - (Some(c1), Some(c2)) => { - if !c1.is_subset(c2) { - return false; - } - } - } - } - true - } - - /// Returns `true` if this set is a superset of `other`. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb1 = RoaringTreemap::new(); - /// let mut rb2 = RoaringTreemap::new(); - /// - /// rb1.insert(1); - /// - /// assert_eq!(rb2.is_superset(&rb1), false); - /// - /// rb2.insert(1); - /// - /// assert_eq!(rb2.is_superset(&rb1), true); - /// - /// rb1.insert(2); - /// - /// assert_eq!(rb2.is_superset(&rb1), false); - /// ``` - pub fn is_superset(&self, other: &Self) -> bool { - other.is_subset(self) - } -} - -impl<'a> Iterator for Pairs<'a> { - type Item = (Option<&'a RoaringBitmap>, Option<&'a RoaringBitmap>); - - fn next(&mut self) -> Option { - enum Which { - Left, - Right, - Both, - None, - } - let which = match (self.0.peek(), self.1.peek()) { - (None, None) => Which::None, - (Some(_), None) => Which::Left, - (None, Some(_)) => Which::Right, - (Some(c1), Some(c2)) => match (c1.0, c2.0) { - (key1, key2) if key1 == key2 => Which::Both, - (key1, key2) if key1 < key2 => Which::Left, - (key1, key2) if key1 > key2 => Which::Right, - (_, _) => unreachable!(), - }, - }; - match which { - Which::Left => Some((self.0.next().map(|e| e.1), None)), - Which::Right => Some((None, self.1.next().map(|e| e.1))), - Which::Both => Some((self.0.next().map(|e| e.1), self.1.next().map(|e| e.1))), - Which::None => None, - } - } -} diff --git a/src/treemap/fmt.rs b/src/treemap/fmt.rs deleted file mode 100644 index 76f6e172c..000000000 --- a/src/treemap/fmt.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::fmt; - -use crate::RoaringTreemap; - -impl fmt::Debug for RoaringTreemap { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.len() < 16 { - write!(f, "RoaringTreemap<{:?}>", self.iter().collect::>()) - } else { - write!( - f, - "RoaringTreemap<{:?} values between {:?} and {:?}>", - self.len(), - self.min().unwrap(), - self.max().unwrap() - ) - } - } -} diff --git a/src/treemap/inherent.rs b/src/treemap/inherent.rs deleted file mode 100644 index aad5f5643..000000000 --- a/src/treemap/inherent.rs +++ /dev/null @@ -1,432 +0,0 @@ -use std::collections::btree_map::{BTreeMap, Entry}; -use std::iter; -use std::ops::RangeBounds; - -use crate::RoaringBitmap; -use crate::RoaringTreemap; - -use super::util; - -impl RoaringTreemap { - /// Creates an empty `RoaringTreemap`. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// let rb = RoaringTreemap::new(); - /// ``` - pub fn new() -> RoaringTreemap { - RoaringTreemap { map: BTreeMap::new() } - } - - /// Creates a full `RoaringTreemap`. - /// - /// # Examples - /// - /// ```rust,ignore - /// use roaring::RoaringTreemap; - /// let rb = RoaringTreemap::full(); - /// ``` - pub fn full() -> RoaringTreemap { - RoaringTreemap { map: (0..=u32::MAX).zip(iter::repeat(RoaringBitmap::full())).collect() } - } - - /// Adds a value to the set. Returns `true` if the value was not already present in the set. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// assert_eq!(rb.insert(3), true); - /// assert_eq!(rb.insert(3), false); - /// assert_eq!(rb.contains(3), true); - /// ``` - pub fn insert(&mut self, value: u64) -> bool { - let (hi, lo) = util::split(value); - self.map.entry(hi).or_default().insert(lo) - } - - /// Inserts a range of values. - /// - /// Returns the number of inserted values. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// rb.insert_range(2..4); - /// assert!(rb.contains(2)); - /// assert!(rb.contains(3)); - /// assert!(!rb.contains(4)); - /// ``` - pub fn insert_range>(&mut self, range: R) -> u64 { - let (start, end) = match util::convert_range_to_inclusive(range) { - Some(range) => (*range.start(), *range.end()), - None => return 0, - }; - - let (start_hi, start_lo) = util::split(start); - let (end_hi, end_lo) = util::split(end); - - let mut counter = 0u64; - - // Split the input range by the leading 32 bits - for hi in start_hi..=end_hi { - let entry = self.map.entry(hi); - - // Calculate the sub-range from the lower 32 bits - counter += if hi == end_hi && hi == start_hi { - entry.or_default().insert_range(start_lo..=end_lo) - } else if hi == start_hi { - entry.or_default().insert_range(start_lo..=u32::MAX) - } else if hi == end_hi { - entry.or_default().insert_range(0..=end_lo) - } else { - // We insert a full bitmap if it doesn't already exist and return the size of it. - // But if the bitmap already exists at this spot we replace it with a full bitmap - // and specify that we didn't inserted the integers from the previous bitmap. - let full_bitmap = RoaringBitmap::full(); - match entry { - Entry::Vacant(entry) => entry.insert(full_bitmap).len(), - Entry::Occupied(mut entry) => { - full_bitmap.len() - entry.insert(full_bitmap).len() - } - } - }; - } - - counter - } - - /// Pushes `value` in the treemap only if it is greater than the current maximum value. - /// - /// Returns whether the value was inserted. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// assert!(rb.push(1)); - /// assert!(rb.push(3)); - /// assert_eq!(rb.push(3), false); - /// assert!(rb.push(5)); - /// - /// assert_eq!(rb.iter().collect::>(), vec![1, 3, 5]); - /// ``` - pub fn push(&mut self, value: u64) -> bool { - let (hi, lo) = util::split(value); - self.map.entry(hi).or_default().push(lo) - } - - /// Pushes `value` in the treemap only if it is greater than the current maximum value. - /// It is up to the caller to have validated index > self.max() - /// - /// # Panics - /// - /// If debug_assertions enabled and index is > self.max() - pub(crate) fn push_unchecked(&mut self, value: u64) { - let (hi, lo) = util::split(value); - // BTreeMap last_mut not stabilized see https://github.com/rust-lang/rust/issues/62924 - match self.map.iter_mut().next_back() { - Some((&key, bitmap)) if key == hi => bitmap.push_unchecked(lo), - Some((&key, _)) if cfg!(debug_assertions) && key > hi => { - panic!("last bitmap key > key of value") - } - _otherwise => { - // The tree is empty - let mut rb = RoaringBitmap::new(); - rb.push_unchecked(lo); - self.map.insert(hi, rb); - } - } - } - - /// Removes a value from the set. Returns `true` if the value was present in the set. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// rb.insert(3); - /// assert_eq!(rb.remove(3), true); - /// assert_eq!(rb.remove(3), false); - /// assert_eq!(rb.contains(3), false); - /// ``` - pub fn remove(&mut self, value: u64) -> bool { - let (hi, lo) = util::split(value); - match self.map.entry(hi) { - Entry::Vacant(_) => false, - Entry::Occupied(mut ent) => { - if ent.get_mut().remove(lo) { - if ent.get().is_empty() { - ent.remove(); - } - true - } else { - false - } - } - } - } - - /// Removes a range of values. - /// Returns the number of removed values. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// rb.insert(2); - /// rb.insert(3); - /// assert_eq!(rb.remove_range(2..4), 2); - /// ``` - pub fn remove_range(&mut self, range: R) -> u64 - where - R: RangeBounds, - { - let (start, end) = match util::convert_range_to_inclusive(range) { - Some(range) => (*range.start(), *range.end()), - None => return 0, - }; - - let (start_container_key, start_index) = util::split(start); - let (end_container_key, end_index) = util::split(end); - - let mut keys_to_remove = Vec::new(); - let mut removed = 0; - - for (&key, rb) in &mut self.map { - if key >= start_container_key && key <= end_container_key { - let a = if key == start_container_key { start_index } else { 0 }; - let b = if key == end_container_key { end_index } else { u32::MAX }; - removed += rb.remove_range(a..=b); - if rb.is_empty() { - keys_to_remove.push(key); - } - } - } - - for key in keys_to_remove { - self.map.remove(&key); - } - - removed - } - - /// Returns `true` if this set contains the specified integer. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// rb.insert(1); - /// assert_eq!(rb.contains(0), false); - /// assert_eq!(rb.contains(1), true); - /// assert_eq!(rb.contains(100), false); - /// ``` - pub fn contains(&self, value: u64) -> bool { - let (hi, lo) = util::split(value); - match self.map.get(&hi) { - None => false, - Some(r) => r.contains(lo), - } - } - - /// Clears all integers in this set. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// rb.insert(1); - /// assert_eq!(rb.contains(1), true); - /// rb.clear(); - /// assert_eq!(rb.contains(1), false); - /// ``` - pub fn clear(&mut self) { - self.map.clear(); - } - - /// Returns `true` if there are no integers in this set. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// assert_eq!(rb.is_empty(), true); - /// - /// rb.insert(3); - /// assert_eq!(rb.is_empty(), false); - /// ``` - pub fn is_empty(&self) -> bool { - self.map.values().all(RoaringBitmap::is_empty) - } - - /// Returns `true` if there are every possible integers in this set. - /// - /// # Examples - /// - /// ```rust,ignore - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::full(); - /// assert!(!rb.is_empty()); - /// assert!(rb.is_full()); - /// ``` - pub fn is_full(&self) -> bool { - self.map.len() == (u32::MAX as usize + 1) && self.map.values().all(RoaringBitmap::is_full) - } - - /// Returns the number of distinct integers added to the set. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// assert_eq!(rb.len(), 0); - /// - /// rb.insert(3); - /// assert_eq!(rb.len(), 1); - /// - /// rb.insert(3); - /// rb.insert(4); - /// assert_eq!(rb.len(), 2); - /// ``` - pub fn len(&self) -> u64 { - self.map.values().map(RoaringBitmap::len).sum() - } - - /// Returns the minimum value in the set (if the set is non-empty). - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// assert_eq!(rb.min(), None); - /// - /// rb.insert(3); - /// rb.insert(4); - /// assert_eq!(rb.min(), Some(3)); - /// ``` - pub fn min(&self) -> Option { - self.map - .iter() - .find(|&(_, rb)| rb.min().is_some()) - .map(|(k, rb)| util::join(*k, rb.min().unwrap())) - } - - /// Returns the maximum value in the set (if the set is non-empty). - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// assert_eq!(rb.max(), None); - /// - /// rb.insert(3); - /// rb.insert(4); - /// assert_eq!(rb.max(), Some(4)); - /// ``` - pub fn max(&self) -> Option { - self.map - .iter() - .rev() - .find(|&(_, rb)| rb.max().is_some()) - .map(|(k, rb)| util::join(*k, rb.max().unwrap())) - } - - /// Returns the number of integers that are <= value. rank(u64::MAX) == len() - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// assert_eq!(rb.rank(0), 0); - /// - /// rb.insert(3); - /// rb.insert(4); - /// assert_eq!(rb.rank(3), 1); - /// assert_eq!(rb.rank(10), 2) - /// ``` - pub fn rank(&self, value: u64) -> u64 { - // if len becomes cached for RoaringTreemap: return len if len > value - - let (hi, lo) = util::split(value); - let mut iter = self.map.range(..=hi).rev(); - - iter.next() - .map(|(&k, bitmap)| if k == hi { bitmap.rank(lo) } else { bitmap.len() }) - .unwrap_or(0) - + iter.map(|(_, bitmap)| bitmap.len()).sum::() - } - - /// Returns the `n`th integer in the set or `None` if `n <= len()` - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// assert_eq!(rb.select(0), None); - /// - /// rb.append(vec![0, 10, 100]); - /// - /// assert_eq!(rb.select(0), Some(0)); - /// assert_eq!(rb.select(1), Some(10)); - /// assert_eq!(rb.select(2), Some(100)); - /// assert_eq!(rb.select(3), None); - /// ``` - pub fn select(&self, mut n: u64) -> Option { - for (&key, bitmap) in &self.map { - let len = bitmap.len(); - if len > n { - return Some((key as u64) << 32 | bitmap.select(n as u32).unwrap() as u64); - } - n -= len; - } - - None - } -} - -impl Default for RoaringTreemap { - fn default() -> RoaringTreemap { - RoaringTreemap::new() - } -} - -impl Clone for RoaringTreemap { - fn clone(&self) -> Self { - RoaringTreemap { map: self.map.clone() } - } - - fn clone_from(&mut self, other: &Self) { - self.map.clone_from(&other.map); - } -} diff --git a/src/treemap/iter.rs b/src/treemap/iter.rs deleted file mode 100644 index 285a0c5ce..000000000 --- a/src/treemap/iter.rs +++ /dev/null @@ -1,367 +0,0 @@ -use std::collections::btree_map; -use std::collections::BTreeMap; -use std::iter::{self, FromIterator}; - -use super::util; -use crate::bitmap::IntoIter as IntoIter32; -use crate::bitmap::Iter as Iter32; -use crate::{NonSortedIntegers, RoaringBitmap, RoaringTreemap}; - -struct To64Iter<'a> { - hi: u32, - inner: Iter32<'a>, -} - -impl<'a> Iterator for To64Iter<'a> { - type Item = u64; - fn next(&mut self) -> Option { - self.inner.next().map(|n| util::join(self.hi, n)) - } -} - -impl DoubleEndedIterator for To64Iter<'_> { - fn next_back(&mut self) -> Option { - self.inner.next_back().map(|n| util::join(self.hi, n)) - } -} - -fn to64iter<'a>(t: (&'a u32, &'a RoaringBitmap)) -> To64Iter<'a> { - To64Iter { hi: *t.0, inner: t.1.iter() } -} - -struct To64IntoIter { - hi: u32, - inner: IntoIter32, -} - -impl Iterator for To64IntoIter { - type Item = u64; - fn next(&mut self) -> Option { - self.inner.next().map(|n| util::join(self.hi, n)) - } -} - -impl DoubleEndedIterator for To64IntoIter { - fn next_back(&mut self) -> Option { - self.inner.next_back().map(|n| util::join(self.hi, n)) - } -} - -fn to64intoiter(t: (u32, RoaringBitmap)) -> To64IntoIter { - To64IntoIter { hi: t.0, inner: t.1.into_iter() } -} - -type InnerIter<'a> = iter::FlatMap< - btree_map::Iter<'a, u32, RoaringBitmap>, - To64Iter<'a>, - fn((&'a u32, &'a RoaringBitmap)) -> To64Iter<'a>, ->; -type InnerIntoIter = iter::FlatMap< - btree_map::IntoIter, - To64IntoIter, - fn((u32, RoaringBitmap)) -> To64IntoIter, ->; - -/// An iterator for `RoaringTreemap`. -pub struct Iter<'a> { - inner: InnerIter<'a>, - size_hint: u64, -} - -/// An iterator for `RoaringTreemap`. -pub struct IntoIter { - inner: InnerIntoIter, - size_hint: u64, -} - -impl<'a> Iter<'a> { - fn new(map: &BTreeMap) -> Iter { - let size_hint: u64 = map.iter().map(|(_, r)| r.len()).sum(); - let i = map.iter().flat_map(to64iter as _); - Iter { inner: i, size_hint } - } -} - -impl IntoIter { - fn new(map: BTreeMap) -> IntoIter { - let size_hint = map.values().map(|r| r.len()).sum(); - let i = map.into_iter().flat_map(to64intoiter as _); - IntoIter { inner: i, size_hint } - } -} - -impl<'a> Iterator for Iter<'a> { - type Item = u64; - - fn next(&mut self) -> Option { - self.size_hint = self.size_hint.saturating_sub(1); - self.inner.next() - } - - fn size_hint(&self) -> (usize, Option) { - if self.size_hint < usize::MAX as u64 { - (self.size_hint as usize, Some(self.size_hint as usize)) - } else { - (usize::MAX, None) - } - } -} - -impl DoubleEndedIterator for Iter<'_> { - fn next_back(&mut self) -> Option { - self.size_hint = self.size_hint.saturating_sub(1); - self.inner.next_back() - } -} - -#[cfg(target_pointer_width = "64")] -impl ExactSizeIterator for Iter<'_> { - fn len(&self) -> usize { - self.size_hint as usize - } -} - -impl Iterator for IntoIter { - type Item = u64; - - fn next(&mut self) -> Option { - self.size_hint = self.size_hint.saturating_sub(1); - self.inner.next() - } - - fn size_hint(&self) -> (usize, Option) { - if self.size_hint < usize::MAX as u64 { - (self.size_hint as usize, Some(self.size_hint as usize)) - } else { - (usize::MAX, None) - } - } -} - -impl DoubleEndedIterator for IntoIter { - fn next_back(&mut self) -> Option { - self.size_hint = self.size_hint.saturating_sub(1); - self.inner.next_back() - } -} - -#[cfg(target_pointer_width = "64")] -impl ExactSizeIterator for IntoIter { - fn len(&self) -> usize { - self.size_hint as usize - } -} - -impl RoaringTreemap { - /// Iterator over each value stored in the RoaringTreemap, guarantees values are ordered by - /// value. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// use std::iter::FromIterator; - /// - /// let bitmap = (1..3).collect::(); - /// let mut iter = bitmap.iter(); - /// - /// assert_eq!(iter.next(), Some(1)); - /// assert_eq!(iter.next(), Some(2)); - /// assert_eq!(iter.next(), None); - /// ``` - pub fn iter(&self) -> Iter { - Iter::new(&self.map) - } - - /// Iterator over pairs of partition number and the corresponding RoaringBitmap. - /// The partition number is defined by the 32 most significant bits of the bit index. - /// - /// # Examples - /// - /// ```rust - /// use roaring::{RoaringBitmap, RoaringTreemap}; - /// use std::iter::FromIterator; - /// - /// let original = (0..6000).collect::(); - /// let mut bitmaps = original.bitmaps(); - /// - /// assert_eq!(bitmaps.next(), Some((0, &(0..6000).collect::()))); - /// assert_eq!(bitmaps.next(), None); - /// ``` - pub fn bitmaps(&self) -> BitmapIter { - BitmapIter(self.map.iter()) - } - - /// Construct a RoaringTreemap from an iterator of partition number and RoaringBitmap pairs. - /// The partition number is defined by the 32 most significant bits of the bit index. - /// Note that repeated partitions, if present, will replace previously set partitions. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// use std::iter::FromIterator; - /// - /// let original = (0..6000).collect::(); - /// let clone = RoaringTreemap::from_bitmaps(original.bitmaps().map(|(p, b)| (p, b.clone()))); - /// - /// assert_eq!(clone, original); - /// ``` - pub fn from_bitmaps>(iterator: I) -> Self { - RoaringTreemap { map: iterator.into_iter().collect() } - } -} - -impl<'a> IntoIterator for &'a RoaringTreemap { - type Item = u64; - type IntoIter = Iter<'a>; - - fn into_iter(self) -> Iter<'a> { - self.iter() - } -} - -impl IntoIterator for RoaringTreemap { - type Item = u64; - type IntoIter = IntoIter; - - fn into_iter(self) -> IntoIter { - IntoIter::new(self.map) - } -} - -impl From<[u64; N]> for RoaringTreemap { - fn from(arr: [u64; N]) -> Self { - RoaringTreemap::from_iter(arr) - } -} - -impl FromIterator for RoaringTreemap { - fn from_iter>(iterator: I) -> RoaringTreemap { - let mut rb = RoaringTreemap::new(); - rb.extend(iterator); - rb - } -} - -impl<'a> FromIterator<&'a u64> for RoaringTreemap { - fn from_iter>(iterator: I) -> RoaringTreemap { - let mut rb = RoaringTreemap::new(); - rb.extend(iterator); - rb - } -} - -impl Extend for RoaringTreemap { - fn extend>(&mut self, iterator: I) { - for value in iterator { - self.insert(value); - } - } -} - -impl<'a> Extend<&'a u64> for RoaringTreemap { - fn extend>(&mut self, iterator: I) { - for value in iterator { - self.insert(*value); - } - } -} - -impl RoaringTreemap { - /// Create the set from a sorted iterator. Values must be sorted and deduplicated. - /// - /// The values of the iterator must be ordered and strictly greater than the greatest value - /// in the set. If a value in the iterator doesn't satisfy this requirement, it is not added - /// and the append operation is stopped. - /// - /// Returns `Ok` with the requested `RoaringTreemap`, `Err` with the number of elements - /// we tried to append before an error occurred. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::from_sorted_iter(0..10).unwrap(); - /// - /// assert!(rb.iter().eq(0..10)); - /// ``` - pub fn from_sorted_iter>( - iterator: I, - ) -> Result { - let mut rt = RoaringTreemap::new(); - rt.append(iterator).map(|_| rt) - } - - /// Extend the set with a sorted iterator. - /// - /// The values of the iterator must be ordered and strictly greater than the greatest value - /// in the set. If a value in the iterator doesn't satisfy this requirement, it is not added - /// and the append operation is stopped. - /// - /// Returns `Ok` with the number of elements appended to the set, `Err` with - /// the number of elements we effectively appended before an error occurred. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let mut rb = RoaringTreemap::new(); - /// rb.append(0..10); - /// - /// assert!(rb.iter().eq(0..10)); - /// ``` - pub fn append>( - &mut self, - iterator: I, - ) -> Result { - let mut iterator = iterator.into_iter(); - let mut prev = match (iterator.next(), self.max()) { - (None, _) => return Ok(0), - (Some(first), Some(max)) if first <= max => { - return Err(NonSortedIntegers { valid_until: 0 }) - } - (Some(first), _) => first, - }; - - // It is now guaranteed that so long as the values of the iterator are - // monotonically increasing they must also be the greatest in the set. - - self.push_unchecked(prev); - - let mut count = 1; - for value in iterator { - if value <= prev { - return Err(NonSortedIntegers { valid_until: count }); - } else { - self.push_unchecked(value); - prev = value; - count += 1; - } - } - - Ok(count) - } -} - -pub struct BitmapIter<'a>(btree_map::Iter<'a, u32, RoaringBitmap>); - -impl<'a> Iterator for BitmapIter<'a> { - type Item = (u32, &'a RoaringBitmap); - - fn next(&mut self) -> Option { - self.0.next().map(|(&p, b)| (p, b)) - } - - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } -} - -impl FromIterator<(u32, RoaringBitmap)> for RoaringTreemap { - fn from_iter>(iterator: I) -> RoaringTreemap { - Self::from_bitmaps(iterator) - } -} diff --git a/src/treemap/mod.rs b/src/treemap/mod.rs deleted file mode 100644 index 036b961a7..000000000 --- a/src/treemap/mod.rs +++ /dev/null @@ -1,41 +0,0 @@ -use crate::RoaringBitmap; -use std::collections::BTreeMap; - -mod fmt; -mod multiops; -mod util; - -// Order of these modules matters as it determines the `impl` blocks order in -// the docs -mod arbitrary; -mod cmp; -mod inherent; -mod iter; -mod ops; -#[cfg(feature = "serde")] -mod serde; -mod serialization; - -pub use self::iter::{IntoIter, Iter}; - -/// A compressed bitmap with u64 values. -/// Implemented as a `BTreeMap` of `RoaringBitmap`s. -/// -/// # Examples -/// -/// ```rust -/// use roaring::RoaringTreemap; -/// -/// let mut rb = RoaringTreemap::new(); -/// -/// // insert all primes less than 10 -/// rb.insert(2); -/// rb.insert(3); -/// rb.insert(5); -/// rb.insert(7); -/// println!("total bits set to true: {}", rb.len()); -/// ``` -#[derive(PartialEq)] -pub struct RoaringTreemap { - map: BTreeMap, -} diff --git a/src/treemap/multiops.rs b/src/treemap/multiops.rs deleted file mode 100644 index 4ad2a8e21..000000000 --- a/src/treemap/multiops.rs +++ /dev/null @@ -1,377 +0,0 @@ -use std::{ - borrow::Borrow, - cmp::Ordering, - collections::{binary_heap::PeekMut, BTreeMap, BinaryHeap}, - mem, -}; - -use crate::{MultiOps, RoaringBitmap, RoaringTreemap}; - -impl MultiOps for I -where - I: IntoIterator, -{ - type Output = RoaringTreemap; - - fn union(self) -> Self::Output { - try_simple_multi_op_owned::<_, _, UnionOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), - ) - .unwrap() - } - - fn intersection(self) -> Self::Output { - try_ordered_multi_op_owned::<_, _, IntersectionOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), - ) - .unwrap() - } - - fn difference(self) -> Self::Output { - try_ordered_multi_op_owned::<_, _, DifferenceOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), - ) - .unwrap() - } - - fn symmetric_difference(self) -> Self::Output { - try_simple_multi_op_owned::<_, _, SymmetricDifferenceOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), - ) - .unwrap() - } -} - -impl MultiOps> for I -where - I: IntoIterator>, -{ - type Output = Result; - - fn union(self) -> Self::Output { - try_simple_multi_op_owned::<_, _, UnionOp>(self) - } - - fn intersection(self) -> Self::Output { - try_ordered_multi_op_owned::<_, _, IntersectionOp>(self) - } - - fn difference(self) -> Self::Output { - try_ordered_multi_op_owned::<_, _, DifferenceOp>(self) - } - - fn symmetric_difference(self) -> Self::Output { - try_simple_multi_op_owned::<_, _, SymmetricDifferenceOp>(self) - } -} - -#[inline] -fn try_simple_multi_op_owned(treemaps: I) -> Result -where - I: IntoIterator>, -{ - let treemaps = treemaps.into_iter().collect::, _>>()?; - - let mut heap: BinaryHeap<_> = treemaps - .into_iter() - .filter_map(|treemap| { - let mut iter = treemap.map.into_iter(); - iter.next().map(|(key, bitmap)| PeekedRoaringBitmap { key, bitmap, iter }) - }) - .collect(); - - let mut bitmaps = Vec::new(); - let mut map = BTreeMap::new(); - - while let Some(mut peek) = heap.peek_mut() { - let (key, bitmap) = match peek.iter.next() { - Some((next_key, next_bitmap)) => { - let key = peek.key; - peek.key = next_key; - let bitmap = mem::replace(&mut peek.bitmap, next_bitmap); - (key, bitmap) - } - None => { - let poped = PeekMut::pop(peek); - (poped.key, poped.bitmap) - } - }; - - if let Some((first_key, _)) = bitmaps.first() { - if *first_key != key { - let current_key = *first_key; - let computed_bitmap = O::op_owned(bitmaps.drain(..).map(|(_, rb)| rb)); - if !computed_bitmap.is_empty() { - map.insert(current_key, computed_bitmap); - } - } - } - - bitmaps.push((key, bitmap)); - } - - if let Some((first_key, _)) = bitmaps.first() { - let current_key = *first_key; - let computed_bitmap = O::op_owned(bitmaps.drain(..).map(|(_, rb)| rb)); - if !computed_bitmap.is_empty() { - map.insert(current_key, computed_bitmap); - } - } - - Ok(RoaringTreemap { map }) -} - -#[inline] -fn try_ordered_multi_op_owned(treemaps: I) -> Result -where - I: IntoIterator>, -{ - let mut treemaps = treemaps.into_iter(); - let mut treemap = match treemaps.next().transpose()? { - Some(treemap) => treemap, - None => return Ok(RoaringTreemap::new()), - }; - let mut treemaps = treemaps.collect::, _>>()?; - - // for each key in the first treemap we're going to find and - // accumulate all the corresponding bitmaps - let keys: Vec<_> = treemap.map.keys().copied().collect(); - for k in keys { - // the unwrap is safe since we're iterating on our keys - let current_bitmap = treemap.map.remove(&k).unwrap(); - let new_bitmap = - O::op_owned(std::iter::once(current_bitmap).chain( - treemaps.iter_mut().map(|treemap| treemap.map.remove(&k).unwrap_or_default()), - )); - if !new_bitmap.is_empty() { - treemap.map.insert(k, new_bitmap); - } - } - - Ok(treemap) -} - -#[inline] -fn try_ordered_multi_op_ref<'a, E: 'a, I, O: Op>(treemaps: I) -> Result -where - I: IntoIterator>, -{ - let mut treemaps = treemaps.into_iter(); - let treemap = match treemaps.next().transpose()? { - Some(treemap) => treemap, - None => return Ok(RoaringTreemap::new()), - }; - let treemaps = treemaps.collect::, _>>()?; - - let mut ret = RoaringTreemap::new(); - - // for each keys in the first treemap we're going find and accumulate all the corresponding bitmaps - let keys: Vec<_> = treemap.map.keys().copied().collect(); - let empty_bitmap = RoaringBitmap::new(); - for k in keys { - // the unwrap is safe since we're iterating on our keys - let current_bitmap = treemap.map.get(&k).unwrap(); - let new_bitmap = O::op_ref( - std::iter::once(current_bitmap) - .chain(treemaps.iter().map(|treemap| treemap.map.get(&k).unwrap_or(&empty_bitmap))), - ); - if !new_bitmap.is_empty() { - ret.map.insert(k, new_bitmap); - } - } - - Ok(ret) -} - -#[inline] -fn try_simple_multi_op_ref<'a, E: 'a, I, O: Op>(treemaps: I) -> Result -where - I: IntoIterator>, -{ - let treemaps = treemaps.into_iter().collect::, E>>()?; - - let mut heap: BinaryHeap<_> = treemaps - .into_iter() - .filter_map(|treemap| { - let mut iter = treemap.map.iter(); - iter.next().map(|(&key, bitmap)| PeekedRoaringBitmap { key, bitmap, iter }) - }) - .collect(); - - let mut bitmaps = Vec::new(); - let mut map = BTreeMap::new(); - - while let Some(mut peek) = heap.peek_mut() { - let (key, bitmap) = match peek.iter.next() { - Some((&next_key, next_bitmap)) => { - let key = peek.key; - peek.key = next_key; - let bitmap = mem::replace(&mut peek.bitmap, next_bitmap); - (key, bitmap) - } - None => { - let poped = PeekMut::pop(peek); - (poped.key, poped.bitmap) - } - }; - - if let Some((first_key, _)) = bitmaps.first() { - if *first_key != key { - let current_key = *first_key; - let computed_bitmap = O::op_ref(bitmaps.drain(..).map(|(_, rb)| rb)); - if !computed_bitmap.is_empty() { - map.insert(current_key, computed_bitmap); - } - } - } - - bitmaps.push((key, bitmap)); - } - - if let Some((first_key, _)) = bitmaps.first() { - let current_key = *first_key; - let computed_bitmap = O::op_ref(bitmaps.drain(..).map(|(_, rb)| rb)); - if !computed_bitmap.is_empty() { - map.insert(current_key, computed_bitmap); - } - } - - Ok(RoaringTreemap { map }) -} - -trait Op { - fn op_owned>(iter: I) -> RoaringBitmap; - fn op_ref<'a, I: IntoIterator>(iter: I) -> RoaringBitmap; -} - -enum UnionOp {} - -impl Op for UnionOp { - fn op_owned>(iter: J) -> RoaringBitmap { - iter.union() - } - - fn op_ref<'a, J: IntoIterator>(iter: J) -> RoaringBitmap { - iter.union() - } -} - -enum IntersectionOp {} - -impl Op for IntersectionOp { - fn op_owned>(iter: J) -> RoaringBitmap { - iter.intersection() - } - - fn op_ref<'a, J: IntoIterator>(iter: J) -> RoaringBitmap { - iter.intersection() - } -} - -enum DifferenceOp {} - -impl Op for DifferenceOp { - fn op_owned>(iter: J) -> RoaringBitmap { - iter.difference() - } - - fn op_ref<'a, J: IntoIterator>(iter: J) -> RoaringBitmap { - iter.difference() - } -} - -enum SymmetricDifferenceOp {} - -impl Op for SymmetricDifferenceOp { - fn op_owned>(iter: J) -> RoaringBitmap { - iter.symmetric_difference() - } - - fn op_ref<'a, J: IntoIterator>(iter: J) -> RoaringBitmap { - iter.symmetric_difference() - } -} - -impl<'a, I> MultiOps<&'a RoaringTreemap> for I -where - I: IntoIterator, -{ - type Output = RoaringTreemap; - - fn union(self) -> Self::Output { - try_simple_multi_op_ref::<_, _, UnionOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), - ) - .unwrap() - } - - fn intersection(self) -> Self::Output { - try_ordered_multi_op_ref::<_, _, IntersectionOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), - ) - .unwrap() - } - - fn difference(self) -> Self::Output { - try_ordered_multi_op_ref::<_, _, DifferenceOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), - ) - .unwrap() - } - - fn symmetric_difference(self) -> Self::Output { - try_simple_multi_op_ref::<_, _, SymmetricDifferenceOp>( - self.into_iter().map(Ok::<_, std::convert::Infallible>), - ) - .unwrap() - } -} - -impl<'a, I, E: 'a> MultiOps> for I -where - I: IntoIterator>, -{ - type Output = Result; - - fn union(self) -> Self::Output { - try_simple_multi_op_ref::<_, _, UnionOp>(self) - } - - fn intersection(self) -> Self::Output { - try_ordered_multi_op_ref::<_, _, IntersectionOp>(self) - } - - fn difference(self) -> Self::Output { - try_ordered_multi_op_ref::<_, _, DifferenceOp>(self) - } - - fn symmetric_difference(self) -> Self::Output { - try_simple_multi_op_ref::<_, _, SymmetricDifferenceOp>(self) - } -} - -struct PeekedRoaringBitmap { - key: u32, - bitmap: R, - iter: I, -} - -impl, I> Ord for PeekedRoaringBitmap { - fn cmp(&self, other: &Self) -> Ordering { - self.key.cmp(&other.key).reverse() - } -} - -impl, I> PartialOrd for PeekedRoaringBitmap { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl, I> Eq for PeekedRoaringBitmap {} - -impl, I> PartialEq for PeekedRoaringBitmap { - fn eq(&self, other: &Self) -> bool { - self.key == other.key - } -} diff --git a/src/treemap/ops.rs b/src/treemap/ops.rs deleted file mode 100644 index 5961c7cf1..000000000 --- a/src/treemap/ops.rs +++ /dev/null @@ -1,541 +0,0 @@ -use std::collections::btree_map::Entry; -use std::mem; -use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; - -use crate::RoaringTreemap; - -impl RoaringTreemap { - /// Computes the len of the union with the specified other treemap without creating a new - /// treemap. - /// - /// This is faster and more space efficient when you're only interested in the cardinality of - /// the union. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let rb1: RoaringTreemap = (1..4).collect(); - /// let rb2: RoaringTreemap = (3..5).collect(); - /// - /// - /// assert_eq!(rb1.union_len(&rb2), (rb1 | rb2).len()); - /// ``` - pub fn union_len(&self, other: &RoaringTreemap) -> u64 { - self.len().wrapping_add(other.len()).wrapping_sub(self.intersection_len(other)) - } - - /// Computes the len of the intersection with the specified other treemap without creating a - /// new treemap. - /// - /// This is faster and more space efficient when you're only interested in the cardinality of - /// the intersection. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let rb1: RoaringTreemap = (1..4).collect(); - /// let rb2: RoaringTreemap = (3..5).collect(); - /// - /// - /// assert_eq!(rb1.intersection_len(&rb2), (rb1 & rb2).len()); - /// ``` - pub fn intersection_len(&self, other: &RoaringTreemap) -> u64 { - self.pairs(other) - .map(|pair| match pair { - (Some(..), None) => 0, - (None, Some(..)) => 0, - (Some(lhs), Some(rhs)) => lhs.intersection_len(rhs), - (None, None) => 0, - }) - .sum() - } - - /// Computes the len of the difference with the specified other treemap without creating a new - /// treemap. - /// - /// This is faster and more space efficient when you're only interested in the cardinality of - /// the difference. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let rb1: RoaringTreemap = (1..4).collect(); - /// let rb2: RoaringTreemap = (3..5).collect(); - /// - /// - /// assert_eq!(rb1.difference_len(&rb2), (rb1 - rb2).len()); - /// ``` - pub fn difference_len(&self, other: &RoaringTreemap) -> u64 { - self.len() - self.intersection_len(other) - } - - /// Computes the len of the symmetric difference with the specified other treemap without - /// creating a new bitmap. - /// - /// This is faster and more space efficient when you're only interested in the cardinality of - /// the symmetric difference. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let rb1: RoaringTreemap = (1..4).collect(); - /// let rb2: RoaringTreemap = (3..5).collect(); - /// - /// - /// assert_eq!(rb1.symmetric_difference_len(&rb2), (rb1 ^ rb2).len()); - /// ``` - pub fn symmetric_difference_len(&self, other: &RoaringTreemap) -> u64 { - let intersection_len = self.intersection_len(other); - - self.len() - .wrapping_add(other.len()) - .wrapping_sub(intersection_len) - .wrapping_sub(intersection_len) - } -} - -impl BitOr for RoaringTreemap { - type Output = RoaringTreemap; - - /// An `union` between two sets. - fn bitor(mut self, rhs: RoaringTreemap) -> RoaringTreemap { - BitOrAssign::bitor_assign(&mut self, rhs); - self - } -} - -impl BitOr<&RoaringTreemap> for RoaringTreemap { - type Output = RoaringTreemap; - - /// An `union` between two sets. - fn bitor(mut self, rhs: &RoaringTreemap) -> RoaringTreemap { - BitOrAssign::bitor_assign(&mut self, rhs); - self - } -} - -impl BitOr for &RoaringTreemap { - type Output = RoaringTreemap; - - /// An `union` between two sets. - fn bitor(self, rhs: RoaringTreemap) -> RoaringTreemap { - BitOr::bitor(rhs, self) - } -} - -impl BitOr<&RoaringTreemap> for &RoaringTreemap { - type Output = RoaringTreemap; - - /// An `union` between two sets. - fn bitor(self, rhs: &RoaringTreemap) -> RoaringTreemap { - if self.len() <= rhs.len() { - BitOr::bitor(rhs.clone(), self) - } else { - BitOr::bitor(self.clone(), rhs) - } - } -} - -impl BitOrAssign for RoaringTreemap { - /// An `union` between two sets. - fn bitor_assign(&mut self, mut rhs: RoaringTreemap) { - // We make sure that we apply the union operation on the biggest map. - if self.len() < rhs.len() { - mem::swap(self, &mut rhs); - } - - for (key, other_rb) in rhs.map { - match self.map.entry(key) { - Entry::Vacant(ent) => { - ent.insert(other_rb); - } - Entry::Occupied(mut ent) => { - BitOrAssign::bitor_assign(ent.get_mut(), other_rb); - } - } - } - } -} - -impl BitOrAssign<&RoaringTreemap> for RoaringTreemap { - /// An `union` between two sets. - fn bitor_assign(&mut self, rhs: &RoaringTreemap) { - for (key, other_rb) in &rhs.map { - match self.map.entry(*key) { - Entry::Vacant(ent) => { - ent.insert(other_rb.clone()); - } - Entry::Occupied(mut ent) => { - BitOrAssign::bitor_assign(ent.get_mut(), other_rb); - } - } - } - } -} - -impl BitAnd for RoaringTreemap { - type Output = RoaringTreemap; - - /// An `intersection` between two sets. - fn bitand(mut self, rhs: RoaringTreemap) -> RoaringTreemap { - BitAndAssign::bitand_assign(&mut self, rhs); - self - } -} - -impl BitAnd<&RoaringTreemap> for RoaringTreemap { - type Output = RoaringTreemap; - - /// An `intersection` between two sets. - fn bitand(mut self, rhs: &RoaringTreemap) -> RoaringTreemap { - BitAndAssign::bitand_assign(&mut self, rhs); - self - } -} - -impl BitAnd for &RoaringTreemap { - type Output = RoaringTreemap; - - /// An `intersection` between two sets. - fn bitand(self, rhs: RoaringTreemap) -> RoaringTreemap { - BitAnd::bitand(rhs, self) - } -} - -impl BitAnd<&RoaringTreemap> for &RoaringTreemap { - type Output = RoaringTreemap; - - /// An `intersection` between two sets. - fn bitand(self, rhs: &RoaringTreemap) -> RoaringTreemap { - if rhs.len() < self.len() { - BitAnd::bitand(self.clone(), rhs) - } else { - BitAnd::bitand(rhs.clone(), self) - } - } -} - -impl BitAndAssign for RoaringTreemap { - /// An `intersection` between two sets. - fn bitand_assign(&mut self, mut rhs: RoaringTreemap) { - // We make sure that we apply the intersection operation on the smallest map. - if rhs.len() < self.len() { - mem::swap(self, &mut rhs); - } - - BitAndAssign::bitand_assign(self, &rhs) - } -} - -impl BitAndAssign<&RoaringTreemap> for RoaringTreemap { - /// An `intersection` between two sets. - fn bitand_assign(&mut self, rhs: &RoaringTreemap) { - let mut keys_to_remove: Vec = Vec::new(); - for (key, self_rb) in &mut self.map { - match rhs.map.get(key) { - Some(other_rb) => { - BitAndAssign::bitand_assign(self_rb, other_rb); - if self_rb.is_empty() { - keys_to_remove.push(*key); - } - } - None => keys_to_remove.push(*key), - } - } - - for key in keys_to_remove { - self.map.remove(&key); - } - } -} - -impl Sub for RoaringTreemap { - type Output = RoaringTreemap; - - /// A `difference` between two sets. - fn sub(mut self, rhs: RoaringTreemap) -> RoaringTreemap { - SubAssign::sub_assign(&mut self, rhs); - self - } -} - -impl Sub<&RoaringTreemap> for RoaringTreemap { - type Output = RoaringTreemap; - - /// A `difference` between two sets. - fn sub(mut self, rhs: &RoaringTreemap) -> RoaringTreemap { - SubAssign::sub_assign(&mut self, rhs); - self - } -} - -impl Sub for &RoaringTreemap { - type Output = RoaringTreemap; - - /// A `difference` between two sets. - fn sub(self, rhs: RoaringTreemap) -> RoaringTreemap { - Sub::sub(self.clone(), rhs) - } -} - -impl Sub<&RoaringTreemap> for &RoaringTreemap { - type Output = RoaringTreemap; - - /// A `difference` between two sets. - fn sub(self, rhs: &RoaringTreemap) -> RoaringTreemap { - Sub::sub(self.clone(), rhs) - } -} - -impl SubAssign for RoaringTreemap { - /// A `difference` between two sets. - fn sub_assign(&mut self, rhs: RoaringTreemap) { - SubAssign::sub_assign(self, &rhs) - } -} - -impl SubAssign<&RoaringTreemap> for RoaringTreemap { - /// A `difference` between two sets. - fn sub_assign(&mut self, rhs: &RoaringTreemap) { - for (key, rhs_rb) in &rhs.map { - match self.map.entry(*key) { - Entry::Vacant(_entry) => (), - Entry::Occupied(mut entry) => { - SubAssign::sub_assign(entry.get_mut(), rhs_rb); - if entry.get().is_empty() { - entry.remove_entry(); - } - } - } - } - } -} - -impl BitXor for RoaringTreemap { - type Output = RoaringTreemap; - - /// A `symmetric difference` between two sets. - fn bitxor(mut self, rhs: RoaringTreemap) -> RoaringTreemap { - BitXorAssign::bitxor_assign(&mut self, rhs); - self - } -} - -impl BitXor<&RoaringTreemap> for RoaringTreemap { - type Output = RoaringTreemap; - - /// A `symmetric difference` between two sets. - fn bitxor(mut self, rhs: &RoaringTreemap) -> RoaringTreemap { - BitXorAssign::bitxor_assign(&mut self, rhs); - self - } -} - -impl BitXor for &RoaringTreemap { - type Output = RoaringTreemap; - - /// A `symmetric difference` between two sets. - fn bitxor(self, rhs: RoaringTreemap) -> RoaringTreemap { - BitXor::bitxor(rhs, self) - } -} - -impl BitXor<&RoaringTreemap> for &RoaringTreemap { - type Output = RoaringTreemap; - - /// A `symmetric difference` between two sets. - fn bitxor(self, rhs: &RoaringTreemap) -> RoaringTreemap { - if self.len() < rhs.len() { - BitXor::bitxor(self, rhs.clone()) - } else { - BitXor::bitxor(self.clone(), rhs) - } - } -} - -impl BitXorAssign for RoaringTreemap { - /// A `symmetric difference` between two sets. - fn bitxor_assign(&mut self, rhs: RoaringTreemap) { - for (key, other_rb) in rhs.map { - match self.map.entry(key) { - Entry::Vacant(entry) => { - entry.insert(other_rb); - } - Entry::Occupied(mut entry) => { - BitXorAssign::bitxor_assign(entry.get_mut(), other_rb); - if entry.get().is_empty() { - entry.remove_entry(); - } - } - } - } - } -} - -impl BitXorAssign<&RoaringTreemap> for RoaringTreemap { - /// A `symmetric difference` between two sets. - fn bitxor_assign(&mut self, rhs: &RoaringTreemap) { - for (key, other_rb) in &rhs.map { - match self.map.entry(*key) { - Entry::Vacant(entry) => { - entry.insert(other_rb.clone()); - } - Entry::Occupied(mut entry) => { - BitXorAssign::bitxor_assign(entry.get_mut(), other_rb); - if entry.get().is_empty() { - entry.remove_entry(); - } - } - } - } - } -} - -#[cfg(test)] -mod test { - use crate::{MultiOps, RoaringTreemap}; - use proptest::prelude::*; - - // fast count tests - proptest! { - #[test] - fn union_len_eq_len_of_materialized_union( - a in RoaringTreemap::arbitrary(), - b in RoaringTreemap::arbitrary() - ) { - prop_assert_eq!(a.union_len(&b), (a | b).len()); - } - - #[test] - fn intersection_len_eq_len_of_materialized_intersection( - a in RoaringTreemap::arbitrary(), - b in RoaringTreemap::arbitrary() - ) { - prop_assert_eq!(a.intersection_len(&b), (a & b).len()); - } - - #[test] - fn difference_len_eq_len_of_materialized_difference( - a in RoaringTreemap::arbitrary(), - b in RoaringTreemap::arbitrary() - ) { - prop_assert_eq!(a.difference_len(&b), (a - b).len()); - } - - #[test] - fn symmetric_difference_len_eq_len_of_materialized_symmetric_difference( - a in RoaringTreemap::arbitrary(), - b in RoaringTreemap::arbitrary() - ) { - prop_assert_eq!(a.symmetric_difference_len(&b), (a ^ b).len()); - } - - #[test] - fn all_union_give_the_same_result( - a in RoaringTreemap::arbitrary(), - b in RoaringTreemap::arbitrary(), - c in RoaringTreemap::arbitrary() - ) { - let mut ref_assign = a.clone(); - ref_assign |= &b; - ref_assign |= &c; - - let mut own_assign = a.clone(); - own_assign |= b.clone(); - own_assign |= c.clone(); - - let ref_inline = &a | &b | &c; - let own_inline = a.clone() | b.clone() | c.clone(); - - let ref_multiop = [&a, &b, &c].union(); - let own_multiop = [a, b.clone(), c.clone()].union(); - - for roar in &[own_assign, ref_inline, own_inline, ref_multiop, own_multiop] { - prop_assert_eq!(&ref_assign, roar); - } - } - - #[test] - fn all_intersection_give_the_same_result( - a in RoaringTreemap::arbitrary(), - b in RoaringTreemap::arbitrary(), - c in RoaringTreemap::arbitrary() - ) { - let mut ref_assign = a.clone(); - ref_assign &= &b; - ref_assign &= &c; - - let mut own_assign = a.clone(); - own_assign &= b.clone(); - own_assign &= c.clone(); - - let ref_inline = &a & &b & &c; - let own_inline = a.clone() & b.clone() & c.clone(); - - let ref_multiop = [&a, &b, &c].intersection(); - let own_multiop = [a, b.clone(), c.clone()].intersection(); - - for roar in &[own_assign, ref_inline, own_inline, ref_multiop, own_multiop] { - prop_assert_eq!(&ref_assign, roar); - } - } - - #[test] - fn all_difference_give_the_same_result( - a in RoaringTreemap::arbitrary(), - b in RoaringTreemap::arbitrary(), - c in RoaringTreemap::arbitrary() - ) { - let mut ref_assign = a.clone(); - ref_assign -= &b; - ref_assign -= &c; - - let mut own_assign = a.clone(); - own_assign -= b.clone(); - own_assign -= c.clone(); - - let ref_inline = &a - &b - &c; - let own_inline = a.clone() - b.clone() - c.clone(); - - let ref_multiop = [&a, &b, &c].difference(); - let own_multiop = [a, b.clone(), c.clone()].difference(); - - for roar in &[own_assign, ref_inline, own_inline, ref_multiop, own_multiop] { - prop_assert_eq!(&ref_assign, roar); - } - } - - #[test] - fn all_symmetric_difference_give_the_same_result( - a in RoaringTreemap::arbitrary(), - b in RoaringTreemap::arbitrary(), - c in RoaringTreemap::arbitrary() - ) { - let mut ref_assign = a.clone(); - ref_assign ^= &b; - ref_assign ^= &c; - - let mut own_assign = a.clone(); - own_assign ^= b.clone(); - own_assign ^= c.clone(); - - let ref_inline = &a ^ &b ^ &c; - let own_inline = a.clone() ^ b.clone() ^ c.clone(); - - let ref_multiop = [&a, &b, &c].symmetric_difference(); - let own_multiop = [a, b.clone(), c.clone()].symmetric_difference(); - - for roar in &[own_assign, ref_inline, own_inline, ref_multiop, own_multiop] { - prop_assert_eq!(&ref_assign, roar); - } - } - } -} diff --git a/src/treemap/serde.rs b/src/treemap/serde.rs deleted file mode 100644 index 67665779f..000000000 --- a/src/treemap/serde.rs +++ /dev/null @@ -1,82 +0,0 @@ -use serde::de::SeqAccess; -use serde::de::Visitor; -use serde::Deserialize; -use serde::Deserializer; -use serde::Serialize; - -use crate::RoaringTreemap; - -impl<'de> Deserialize<'de> for RoaringTreemap { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct TreemapVisitor; - - impl<'de> Visitor<'de> for TreemapVisitor { - type Value = RoaringTreemap; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("roaring bitmap") - } - - fn visit_bytes(self, bytes: &[u8]) -> Result - where - E: serde::de::Error, - { - RoaringTreemap::deserialize_from(bytes).map_err(serde::de::Error::custom) - } - - // in some case bytes will be serialized as a sequence thus we need to accept both - // even if it means non optimal performance - fn visit_seq(self, mut seq: A) -> Result - where - A: SeqAccess<'de>, - { - let mut bytes: Vec = Vec::new(); - while let Some(el) = seq.next_element()? { - bytes.push(el); - } - RoaringTreemap::deserialize_from(&*bytes).map_err(serde::de::Error::custom) - } - } - - deserializer.deserialize_bytes(TreemapVisitor) - } -} - -impl Serialize for RoaringTreemap { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut buf = Vec::new(); - self.serialize_into(&mut buf).map_err(serde::ser::Error::custom)?; - - serializer.serialize_bytes(&buf) - } -} - -#[cfg(test)] -mod test { - use crate::RoaringTreemap; - use proptest::prelude::*; - - proptest! { - #[test] - fn test_serde_json( - treemap in RoaringTreemap::arbitrary(), - ) { - let json = serde_json::to_vec(&treemap).unwrap(); - prop_assert_eq!(treemap, serde_json::from_slice(&json).unwrap()); - } - - #[test] - fn test_bincode( - treemap in RoaringTreemap::arbitrary(), - ) { - let buffer = bincode::serialize(&treemap).unwrap(); - prop_assert_eq!(treemap, bincode::deserialize(&buffer).unwrap()); - } - } -} diff --git a/src/treemap/serialization.rs b/src/treemap/serialization.rs deleted file mode 100644 index 2ab50f8ba..000000000 --- a/src/treemap/serialization.rs +++ /dev/null @@ -1,135 +0,0 @@ -use super::RoaringTreemap; -use crate::RoaringBitmap; -use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; -use std::{io, mem::size_of}; - -impl RoaringTreemap { - /// Return the size in bytes of the serialized output. - /// This is compatible with the official C/C++, Java and Go implementations. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let rb1: RoaringTreemap = (1..4).collect(); - /// let mut bytes = Vec::with_capacity(rb1.serialized_size()); - /// rb1.serialize_into(&mut bytes).unwrap(); - /// let rb2 = RoaringTreemap::deserialize_from(&bytes[..]).unwrap(); - /// - /// assert_eq!(rb1, rb2); - /// ``` - pub fn serialized_size(&self) -> usize { - self.map - .values() - .fold(size_of::(), |acc, bitmap| acc + size_of::() + bitmap.serialized_size()) - } - - /// Serialize this bitmap. - /// This is compatible with the official C/C++, Java and Go implementations. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let rb1: RoaringTreemap = (1..4).collect(); - /// let mut bytes = vec![]; - /// rb1.serialize_into(&mut bytes).unwrap(); - /// let rb2 = RoaringTreemap::deserialize_from(&bytes[..]).unwrap(); - /// - /// assert_eq!(rb1, rb2); - /// ``` - pub fn serialize_into(&self, mut writer: W) -> io::Result<()> { - writer.write_u64::(self.map.len() as u64)?; - - for (key, bitmap) in &self.map { - writer.write_u32::(*key)?; - bitmap.serialize_into(&mut writer)?; - } - - Ok(()) - } - - /// Deserialize a bitmap into memory. - /// - /// This is compatible with the official C/C++, Java and Go implementations. - /// This method checks that all of the internal values are valid. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let rb1: RoaringTreemap = (1..4).collect(); - /// let mut bytes = vec![]; - /// rb1.serialize_into(&mut bytes).unwrap(); - /// let rb2 = RoaringTreemap::deserialize_from(&bytes[..]).unwrap(); - /// - /// assert_eq!(rb1, rb2); - /// ``` - pub fn deserialize_from(reader: R) -> io::Result { - RoaringTreemap::deserialize_from_impl(reader, |reader| { - RoaringBitmap::deserialize_from(reader) - }) - } - - /// Deserialize a bitmap into memory. - /// - /// This is compatible with the official C/C++, Java and Go implementations. - /// This method is memory safe but will not check if the data is a valid bitmap. - /// - /// # Examples - /// - /// ```rust - /// use roaring::RoaringTreemap; - /// - /// let rb1: RoaringTreemap = (1..4).collect(); - /// let mut bytes = vec![]; - /// rb1.serialize_into(&mut bytes).unwrap(); - /// let rb2 = RoaringTreemap::deserialize_unchecked_from(&bytes[..]).unwrap(); - /// - /// assert_eq!(rb1, rb2); - /// ``` - pub fn deserialize_unchecked_from(reader: R) -> io::Result { - RoaringTreemap::deserialize_from_impl(reader, |reader| { - RoaringBitmap::deserialize_unchecked_from(reader) - }) - } - - fn deserialize_from_impl(mut reader: R, mut deserialize_bitmap: F) -> io::Result - where - R: io::Read, - F: FnMut(&mut R) -> io::Result, - { - let size = reader.read_u64::()?; - - let mut s = Self::new(); - - for _ in 0..size { - let key = reader.read_u32::()?; - let bitmap = deserialize_bitmap(&mut reader)?; - - s.map.insert(key, bitmap); - } - - Ok(s) - } -} - -#[cfg(test)] -mod test { - use crate::RoaringTreemap; - use proptest::prelude::*; - - proptest! { - #[test] - fn test_serialization( - treemap in RoaringTreemap::arbitrary(), - ) { - let mut buffer = Vec::new(); - treemap.serialize_into(&mut buffer).unwrap(); - prop_assert_eq!(treemap, RoaringTreemap::deserialize_from(buffer.as_slice()).unwrap()); - } - } -} diff --git a/src/treemap/util.rs b/src/treemap/util.rs deleted file mode 100644 index 88c8ccaef..000000000 --- a/src/treemap/util.rs +++ /dev/null @@ -1,72 +0,0 @@ -use std::ops::{Bound, RangeBounds, RangeInclusive}; - -#[inline] -pub fn split(value: u64) -> (u32, u32) { - ((value >> 32) as u32, value as u32) -} - -#[inline] -pub fn join(high: u32, low: u32) -> u64 { - (u64::from(high) << 32) | u64::from(low) -} - -/// Convert a `RangeBounds` object to `RangeInclusive`, -pub fn convert_range_to_inclusive(range: R) -> Option> -where - R: RangeBounds, -{ - let start: u64 = match range.start_bound() { - Bound::Included(&i) => i, - Bound::Excluded(&u64::MAX) => return None, - Bound::Excluded(&i) => i + 1, - Bound::Unbounded => 0, - }; - let end: u64 = match range.end_bound() { - Bound::Included(&i) => i, - Bound::Excluded(&0) => return None, - Bound::Excluded(&i) => i - 1, - Bound::Unbounded => u64::MAX, - }; - if end < start { - return None; - } - Some(start..=end) -} - -#[cfg(test)] -mod test { - use super::{convert_range_to_inclusive, join, split}; - - #[test] - fn test_split_u64() { - assert_eq!((0x0000_0000u32, 0x0000_0000u32), split(0x0000_0000_0000_0000u64)); - assert_eq!((0x0000_0000u32, 0x0000_0001u32), split(0x0000_0000_0000_0001u64)); - assert_eq!((0x0000_0000u32, 0xFFFF_FFFEu32), split(0x0000_0000_FFFF_FFFEu64)); - assert_eq!((0x0000_0000u32, 0xFFFF_FFFFu32), split(0x0000_0000_FFFF_FFFFu64)); - assert_eq!((0x0000_0001u32, 0x0000_0000u32), split(0x0000_0001_0000_0000u64)); - assert_eq!((0x0000_0001u32, 0x0000_0001u32), split(0x0000_0001_0000_0001u64)); - assert_eq!((0xFFFF_FFFFu32, 0xFFFF_FFFEu32), split(0xFFFF_FFFF_FFFF_FFFEu64)); - assert_eq!((0xFFFF_FFFFu32, 0xFFFF_FFFFu32), split(0xFFFF_FFFF_FFFF_FFFFu64)); - } - - #[test] - fn test_join_u64() { - assert_eq!(0x0000_0000_0000_0000u64, join(0x0000_0000u32, 0x0000_0000u32)); - assert_eq!(0x0000_0000_0000_0001u64, join(0x0000_0000u32, 0x0000_0001u32)); - assert_eq!(0x0000_0000_FFFF_FFFEu64, join(0x0000_0000u32, 0xFFFF_FFFEu32)); - assert_eq!(0x0000_0000_FFFF_FFFFu64, join(0x0000_0000u32, 0xFFFF_FFFFu32)); - assert_eq!(0x0000_0001_0000_0000u64, join(0x0000_0001u32, 0x0000_0000u32)); - assert_eq!(0x0000_0001_0000_0001u64, join(0x0000_0001u32, 0x0000_0001u32)); - assert_eq!(0xFFFF_FFFF_FFFF_FFFEu64, join(0xFFFF_FFFFu32, 0xFFFF_FFFEu32)); - assert_eq!(0xFFFF_FFFF_FFFF_FFFFu64, join(0xFFFF_FFFFu32, 0xFFFF_FFFFu32)); - } - - #[test] - fn test_convert_range_to_inclusive() { - assert_eq!(Some(1..=5), convert_range_to_inclusive(1..6)); - assert_eq!(Some(1..=u64::MAX), convert_range_to_inclusive(1..)); - assert_eq!(Some(0..=u64::MAX), convert_range_to_inclusive(..)); - assert_eq!(None, convert_range_to_inclusive(5..5)); - assert_eq!(Some(16..=16), convert_range_to_inclusive(16..=16)) - } -} diff --git a/tests/push.rs b/tests/push.rs index fd3bc98da..f8a0e4bdb 100644 --- a/tests/push.rs +++ b/tests/push.rs @@ -1,4 +1,4 @@ -use roaring::Roaring32; +use roaring::{Roaring32, Roaring64}; use std::iter::FromIterator; /// macro created to reduce code duplication @@ -50,8 +50,8 @@ fn append_error() { } } -// #[test] -// fn append_tree() { -// test_from_sorted_iter!((0..1_000_000).map(|x| 13 * x).collect::>(), RoaringTreemap); -// test_from_sorted_iter!(vec![1, 2, 4, 5, 7, 8, 9], RoaringTreemap); -// } +#[test] +fn append_roaring64() { + test_from_sorted_iter!((0..1_000_000).map(|x| 13 * x).collect::>(), Roaring64); + test_from_sorted_iter!(vec![1, 2, 4, 5, 7, 8, 9], Roaring64); +} diff --git a/tests/roaring64_clone.rs b/tests/roaring64_clone.rs new file mode 100644 index 000000000..d3116c126 --- /dev/null +++ b/tests/roaring64_clone.rs @@ -0,0 +1,39 @@ +use roaring::Roaring64; + +#[test] +#[allow(clippy::redundant_clone)] +fn array() { + let original = (0..2000).collect::(); + let clone = original.clone(); + + assert_eq!(clone, original); +} + +#[test] +#[allow(clippy::redundant_clone)] +fn bitmap() { + let original = (0..6000).collect::(); + let clone = original.clone(); + + assert_eq!(clone, original); +} + +#[test] +#[allow(clippy::redundant_clone)] +fn arrays() { + let original = + ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)).collect::(); + let clone = original.clone(); + + assert_eq!(clone, original); +} + +#[test] +#[allow(clippy::redundant_clone)] +fn bitmaps() { + let original = + ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)).collect::(); + let clone = original.clone(); + + assert_eq!(clone, original); +} diff --git a/tests/roaring64_difference_with.rs b/tests/roaring64_difference_with.rs new file mode 100644 index 000000000..5bb15444f --- /dev/null +++ b/tests/roaring64_difference_with.rs @@ -0,0 +1,116 @@ +use roaring::Roaring64; + +#[test] +fn array() { + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..3000).collect::(); + let bitmap3 = (0..1000).collect::(); + + bitmap1 -= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn no_difference() { + let mut bitmap1 = (1..3).collect::(); + let bitmap2 = (1..3).collect::(); + + bitmap1 -= bitmap2; + + assert_eq!(bitmap1, Roaring64::new()); +} + +#[test] +fn array_and_bitmap() { + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..8000).collect::(); + let bitmap3 = (0..1000).collect::(); + + bitmap1 -= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmap_to_bitmap() { + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (6000..18000).collect::(); + let bitmap3 = (0..6000).collect::(); + + bitmap1 -= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmap_to_array() { + let mut bitmap1 = (0..6000).collect::(); + let bitmap2 = (3000..9000).collect::(); + let bitmap3 = (0..3000).collect::(); + + bitmap1 -= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmap_and_array_to_bitmap() { + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (9000..12000).collect::(); + let bitmap3 = (0..9000).collect::(); + + bitmap1 -= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmap_and_array_to_array() { + let mut bitmap1 = (0..6000).collect::(); + let bitmap2 = (3000..6000).collect::(); + let bitmap3 = (0..3000).collect::(); + + bitmap1 -= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn arrays() { + let mut bitmap1 = + ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)).collect::(); + let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) + .collect::(); + let bitmap3 = ((0..1000).chain(1_000_000..1_001_000)).collect::(); + + bitmap1 -= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn arrays_removing_one_whole_container() { + let mut bitmap1 = + ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)).collect::(); + let bitmap2 = + ((0..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)).collect::(); + let bitmap3 = (1_000_000..1_001_000).collect::(); + + bitmap1 -= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmaps() { + let mut bitmap1 = + ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)).collect::(); + let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) + .collect::(); + let bitmap3 = ((0..3000).chain(1_000_000..1_006_000)).collect::(); + + bitmap1 -= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} diff --git a/tests/roaring64_intersect_with.rs b/tests/roaring64_intersect_with.rs new file mode 100644 index 000000000..ba53a8590 --- /dev/null +++ b/tests/roaring64_intersect_with.rs @@ -0,0 +1,92 @@ +use roaring::Roaring64; + +#[test] +fn array() { + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..3000).collect::(); + let bitmap3 = (1000..2000).collect::(); + + bitmap1 &= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn no_intersection() { + let mut bitmap1 = (0..2).collect::(); + let bitmap2 = (3..4).collect::(); + + bitmap1 &= bitmap2; + + assert_eq!(bitmap1, Roaring64::new()); +} + +#[test] +fn array_and_bitmap() { + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..8000).collect::(); + let bitmap3 = (1000..2000).collect::(); + + bitmap1 &= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmap_to_bitmap() { + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (6000..18000).collect::(); + let bitmap3 = (6000..12000).collect::(); + + bitmap1 &= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmap_to_array() { + let mut bitmap1 = (0..6000).collect::(); + let bitmap2 = (3000..9000).collect::(); + let bitmap3 = (3000..6000).collect::(); + + bitmap1 &= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmap_and_array() { + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (7000..9000).collect::(); + let bitmap3 = (7000..9000).collect::(); + + bitmap1 &= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn arrays() { + let mut bitmap1 = + ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)).collect::(); + let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) + .collect::(); + let bitmap3 = ((1000..2000).chain(1_001_000..1_002_000)).collect::(); + + bitmap1 &= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmaps() { + let mut bitmap1 = + ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)).collect::(); + let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) + .collect::(); + let bitmap3 = ((3000..6000).chain(1_006_000..1_012_000)).collect::(); + + bitmap1 &= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} diff --git a/tests/roaring64_is_disjoint.rs b/tests/roaring64_is_disjoint.rs new file mode 100644 index 000000000..3d19dbd2a --- /dev/null +++ b/tests/roaring64_is_disjoint.rs @@ -0,0 +1,61 @@ +use roaring::Roaring64; + +#[test] +fn array() { + let bitmap1 = (0..2000).collect::(); + let bitmap2 = (4000..6000).collect::(); + assert!(bitmap1.is_disjoint(&bitmap2)); +} + +#[test] +fn array_not() { + let bitmap1 = (0..4000).collect::(); + let bitmap2 = (2000..6000).collect::(); + assert!(!bitmap1.is_disjoint(&bitmap2)); +} + +#[test] +fn bitmap() { + let bitmap1 = (0..6000).collect::(); + let bitmap2 = (10000..16000).collect::(); + assert!(bitmap1.is_disjoint(&bitmap2)); +} + +#[test] +fn bitmap_not() { + let bitmap1 = (0..10000).collect::(); + let bitmap2 = (5000..15000).collect::(); + assert!(!bitmap1.is_disjoint(&bitmap2)); +} + +#[test] +fn arrays() { + let bitmap1 = + ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_002_000)).collect::(); + let bitmap2 = ((100_000..102_000).chain(1_100_000..1_102_000)).collect::(); + assert!(bitmap1.is_disjoint(&bitmap2)); +} + +#[test] +fn arrays_not() { + let bitmap1 = + ((0..2_000).chain(1_000_000..1_002_000).chain(2_000_000..2_002_000)).collect::(); + let bitmap2 = ((100_000..102_000).chain(1_001_000..1_003_000)).collect::(); + assert!(!bitmap1.is_disjoint(&bitmap2)); +} + +#[test] +fn bitmaps() { + let bitmap1 = + ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_006_000)).collect::(); + let bitmap2 = ((100_000..106_000).chain(1_100_000..1_106_000)).collect::(); + assert!(bitmap1.is_disjoint(&bitmap2)); +} + +#[test] +fn bitmaps_not() { + let bitmap1 = + ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_006_000)).collect::(); + let bitmap2 = ((100_000..106_000).chain(1_004_000..1_008_000)).collect::(); + assert!(!bitmap1.is_disjoint(&bitmap2)); +} diff --git a/tests/roaring64_is_subset.rs b/tests/roaring64_is_subset.rs new file mode 100644 index 000000000..5eab7486f --- /dev/null +++ b/tests/roaring64_is_subset.rs @@ -0,0 +1,79 @@ +use roaring::Roaring64; + +#[test] +fn array_not() { + let sup = (0..2000).collect::(); + let sub = (1000..3000).collect::(); + assert!(!sub.is_subset(&sup)); +} + +#[test] +fn array() { + let sup = (0..4000).collect::(); + let sub = (2000..3000).collect::(); + assert!(sub.is_subset(&sup)); +} + +#[test] +fn array_bitmap_not() { + let sup = (0..2000).collect::(); + let sub = (1000..15000).collect::(); + assert!(!sub.is_subset(&sup)); +} + +#[test] +fn bitmap_not() { + let sup = (0..6000).collect::(); + let sub = (4000..10000).collect::(); + assert!(!sub.is_subset(&sup)); +} + +#[test] +fn bitmap() { + let sup = (0..20000).collect::(); + let sub = (5000..15000).collect::(); + assert!(sub.is_subset(&sup)); +} + +#[test] +fn bitmap_array_not() { + let sup = (0..20000).collect::(); + let sub = (19000..21000).collect::(); + assert!(!sub.is_subset(&sup)); +} + +#[test] +fn bitmap_array() { + let sup = (0..20000).collect::(); + let sub = (18000..20000).collect::(); + assert!(sub.is_subset(&sup)); +} + +#[test] +fn arrays_not() { + let sup = ((0..2000).chain(1_000_000..1_002_000)).collect::(); + let sub = ((100_000..102_000).chain(1_100_000..1_102_000)).collect::(); + assert!(!sub.is_subset(&sup)); +} + +#[test] +fn arrays() { + let sup = ((0..3000).chain(100_000..103_000)).collect::(); + let sub = ((0..2000).chain(100_000..102_000)).collect::(); + assert!(sub.is_subset(&sup)); +} + +#[test] +fn bitmaps_not() { + let sup = + ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_010_000)).collect::(); + let sub = ((100_000..106_000).chain(1_100_000..1_106_000)).collect::(); + assert!(!sub.is_subset(&sup)); +} + +#[test] +fn bitmaps() { + let sup = ((0..1_000_000).chain(2_000_000..2_010_000)).collect::(); + let sub = ((0..10_000).chain(500_000..510_000)).collect::(); + assert!(sub.is_subset(&sup)); +} diff --git a/tests/roaring64_iter.rs b/tests/roaring64_iter.rs new file mode 100644 index 000000000..c4e6d0b41 --- /dev/null +++ b/tests/roaring64_iter.rs @@ -0,0 +1,115 @@ +mod iter; +use iter::outside_in; + +use proptest::{arbitrary::any, collection::btree_set, proptest}; +use roaring::Roaring64; +use std::iter::FromIterator; + +#[test] +fn range() { + let original = (0..2000).collect::(); + let clone = Roaring64::from_iter(&original); + let clone2 = Roaring64::from_iter(original.clone()); + + assert_eq!(clone, original); + assert_eq!(clone2, original); +} + +#[test] +fn array() { + let original = (0..5).collect::(); + let clone = Roaring64::from([0, 1, 2, 3, 4]); + + assert_eq!(clone, original); +} + +#[test] +fn bitmap() { + let original = (0..6000).collect::(); + let clone = Roaring64::from_iter(&original); + let clone2 = Roaring64::from_iter(original.clone()); + + assert_eq!(clone, original); + assert_eq!(clone2, original); +} + +#[test] +fn arrays() { + let original = + ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)).collect::(); + let clone = Roaring64::from_iter(&original); + let clone2 = Roaring64::from_iter(original.clone()); + + assert_eq!(clone, original); + assert_eq!(clone2, original); +} + +#[test] +fn bitmaps() { + let original = + ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)).collect::(); + let clone = Roaring64::from_iter(&original); + let clone2 = Roaring64::from_iter(original.clone()); + + assert_eq!(clone, original); + assert_eq!(clone2, original); +} + +proptest! { + #[test] + fn iter(values in btree_set(any::(), ..=10_000)) { + let bitmap = Roaring64::from_sorted_iter(values.iter().cloned()).unwrap(); + + assert!(values.into_iter().eq(bitmap)); + } +} + +#[test] +fn rev() { + let values = (1..3) + .chain(1_000_000..1_012_003) + .chain(2_000_001..2_000_003) + .chain(2_000_000_000_001..2_000_000_000_003); + let bitmap = Roaring64::from_iter(values.clone()); + + assert!(values.into_iter().rev().eq(bitmap.iter().rev())); +} + +proptest! { + #[test] + fn rev_iter(values in btree_set(any::(), ..=10_000)) { + let bitmap = Roaring64::from_sorted_iter(values.iter().cloned()).unwrap(); + + assert!(values.into_iter().rev().eq(bitmap.iter().rev())); + } +} + +#[test] +fn from_iter() { + // This test verifies that the public API allows conversion from iterators + // with u64 as well as &u64 elements. + let vals = vec![1, 5, 1_000_000_000_000_000]; + let a = Roaring64::from_iter(vals.iter()); + let b = Roaring64::from_iter(vals); + assert_eq!(a, b); +} + +#[test] +fn interleaved() { + let values = (1..3) + .chain(1_000_000..1_012_003) + .chain(2_000_001..2_000_003) + .chain(2_000_000_000_001..2_000_000_000_003); + let bitmap = Roaring64::from_iter(values.clone()); + + assert!(outside_in(values).eq(outside_in(bitmap))); +} + +proptest! { + #[test] + fn interleaved_iter(values in btree_set(any::(), 50_000..=100_000)) { + let bitmap = Roaring64::from_sorted_iter(values.iter().cloned()).unwrap(); + + assert!(outside_in(values).eq(outside_in(bitmap))); + } +} diff --git a/tests/roaring64_lib.rs b/tests/roaring64_lib.rs new file mode 100644 index 000000000..8d9ea34bd --- /dev/null +++ b/tests/roaring64_lib.rs @@ -0,0 +1,118 @@ +use roaring::Roaring64; + +#[test] +fn smoke() { + let mut bitmap = Roaring64::new(); + assert_eq!(bitmap.len(), 0); + assert!(bitmap.is_empty()); + bitmap.remove(0); + assert_eq!(bitmap.len(), 0); + assert!(bitmap.is_empty()); + bitmap.insert(1); + assert!(bitmap.contains(1)); + assert_eq!(bitmap.len(), 1); + assert!(!bitmap.is_empty()); + bitmap.insert(u64::MAX - 2); + assert!(bitmap.contains(u64::MAX - 2)); + assert_eq!(bitmap.len(), 2); + bitmap.insert(u64::MAX); + assert!(bitmap.contains(u64::MAX)); + assert_eq!(bitmap.len(), 3); + bitmap.insert(2); + assert!(bitmap.contains(2)); + assert_eq!(bitmap.len(), 4); + bitmap.remove(2); + assert!(!bitmap.contains(2)); + assert_eq!(bitmap.len(), 3); + assert!(!bitmap.contains(0)); + assert!(bitmap.contains(1)); + assert!(!bitmap.contains(100)); + assert!(bitmap.contains(u64::MAX - 2)); + assert!(!bitmap.contains(u64::MAX - 1)); + assert!(bitmap.contains(u64::MAX)); +} + +#[test] +fn insert_range() { + let ranges = 0..0x1000; + const SIGMA: u64 = u32::MAX as u64; + + let mut bitmap = Roaring64::new(); + assert_eq!(bitmap.insert_range(ranges), 0x1000); + assert_eq!(bitmap.len(), 0x1000); + assert_eq!(bitmap.max(), Some(0xFFF)); + + assert_eq!(bitmap.insert_range(u32::MAX as u64 - 1..u32::MAX as u64 + 1), 2); + assert!(bitmap.contains(2)); + assert!(bitmap.contains(0xFFF)); + assert!(!bitmap.contains(0x1000)); + + bitmap.clear(); + bitmap.insert_range(2 * SIGMA..=4 * SIGMA); + + assert_eq!(bitmap.min(), Some(2 * SIGMA)); + assert_eq!(bitmap.max(), Some(4 * SIGMA)); + + assert!(bitmap.contains(3 * SIGMA)); +} + +#[test] +fn remove_range() { + let ranges = [0u64, 1, 63, 64, 65, 100, 4096 - 1, 4096, 4096 + 1, 65536 - 1]; + for (i, &a) in ranges.iter().enumerate() { + for &b in &ranges[i..] { + let mut bitmap = (0..=65536).collect::(); + assert_eq!(bitmap.remove_range(a..b), (b - a)); + assert_eq!(bitmap, ((0..a).chain(b..=65536)).collect::()); + } + } +} + +#[test] +fn test_max() { + let mut bitmap = Roaring64::new(); + assert_eq!(bitmap.max(), None); + bitmap.insert(0); + assert_eq!(bitmap.max(), Some(0)); + bitmap.insert(1); + assert_eq!(bitmap.max(), Some(1)); + bitmap.insert(u64::MAX); + assert_eq!(bitmap.max(), Some(u64::MAX)); +} + +#[test] +fn test_min() { + let mut bitmap = Roaring64::new(); + assert_eq!(bitmap.min(), None); + bitmap.insert(u64::MAX); + assert_eq!(bitmap.min(), Some(u64::MAX)); + bitmap.insert(1); + assert_eq!(bitmap.min(), Some(1)); + bitmap.insert(0); + assert_eq!(bitmap.min(), Some(0)); +} + +#[test] +fn to_bitmap() { + let bitmap = (0..5000).collect::(); + assert_eq!(bitmap.len(), 5000); + for i in 1..5000 { + assert!(bitmap.contains(i)); + } + assert!(!bitmap.contains(5001)); +} + +#[test] +fn to_array() { + let mut bitmap = (0..5000).collect::(); + for i in 3000..5000 { + bitmap.remove(i); + } + assert_eq!(bitmap.len(), 3000); + for i in 0..3000 { + assert!(bitmap.contains(i)); + } + for i in 3000..5000 { + assert!(!bitmap.contains(i)); + } +} diff --git a/tests/roaring64_ops.rs b/tests/roaring64_ops.rs new file mode 100644 index 000000000..c8a04b19e --- /dev/null +++ b/tests/roaring64_ops.rs @@ -0,0 +1,77 @@ +use roaring::Roaring64; + +#[test] +fn or() { + let mut rb1 = (1..4).collect::(); + let rb2 = (3..6).collect::(); + let rb3 = (1..6).collect::(); + + assert_eq!(rb3, &rb1 | &rb2); + assert_eq!(rb3, &rb1 | rb2.clone()); + assert_eq!(rb3, rb1.clone() | &rb2); + assert_eq!(rb3, rb1.clone() | rb2.clone()); + assert_eq!(rb3.len(), rb1.union_len(&rb2)); + + rb1 |= &rb2; + rb1 |= rb2; + + assert_eq!(rb3, rb1); +} + +#[test] +fn and() { + let mut rb1 = (1..4).collect::(); + let rb2 = (3..6).collect::(); + let rb3 = (3..4).collect::(); + + assert_eq!(rb3, &rb1 & &rb2); + assert_eq!(rb3, &rb1 & rb2.clone()); + assert_eq!(rb3, rb1.clone() & &rb2); + assert_eq!(rb3, rb1.clone() & rb2.clone()); + assert_eq!(rb3.len(), rb1.intersection_len(&rb2)); + + rb1 &= &rb2; + rb1 &= rb2; + + assert_eq!(rb3, rb1); +} + +#[test] +fn sub() { + let mut rb1 = (1..4).collect::(); + let rb2 = (3..6).collect::(); + let rb3 = (1..3).collect::(); + + assert_eq!(rb3, &rb1 - &rb2); + assert_eq!(rb3, &rb1 - rb2.clone()); + assert_eq!(rb3, rb1.clone() - &rb2); + assert_eq!(rb3, rb1.clone() - rb2.clone()); + assert_eq!(rb3.len(), rb1.difference_len(&rb2)); + + rb1 -= &rb2; + rb1 -= rb2; + + assert_eq!(rb3, rb1); +} + +#[test] +fn xor() { + let mut rb1 = (1..4).collect::(); + let rb2 = (3..6).collect::(); + let rb3 = ((1..3).chain(4..6)).collect::(); + let rb4 = (0..0).collect::(); + + assert_eq!(rb3, &rb1 ^ &rb2); + assert_eq!(rb3, &rb1 ^ rb2.clone()); + assert_eq!(rb3, rb1.clone() ^ &rb2); + assert_eq!(rb3, rb1.clone() ^ rb2.clone()); + assert_eq!(rb3.len(), rb1.symmetric_difference_len(&rb2)); + + rb1 ^= &rb2; + + assert_eq!(rb3, rb1); + + rb1 ^= rb3; + + assert_eq!(rb4, rb1); +} diff --git a/tests/roaring64_rank.rs b/tests/roaring64_rank.rs new file mode 100644 index 000000000..53717940a --- /dev/null +++ b/tests/roaring64_rank.rs @@ -0,0 +1,54 @@ +use proptest::{ + collection::{btree_set, vec}, + prelude::*, +}; +use roaring::Roaring64; +use std::ops::RangeInclusive; + +const BITMAP_MAX: u64 = u32::MAX as u64; + +#[test] +fn rank_roaring_bitmaps() { + // A bitmap with two roaring bitmaps. + // The lower one contains one array container with the highest 1000 values + // The higher one contains one bitmap at with the lowest 5000 values + let bitmap = Roaring64::from_sorted_iter(BITMAP_MAX - 1000..BITMAP_MAX + 5000).unwrap(); + + // start of bitmap + assert_eq!(bitmap.rank(0), 0); + + // low boundary + assert_eq!(bitmap.rank(BITMAP_MAX - 1002), 0); + assert_eq!(bitmap.rank(BITMAP_MAX - 1001), 0); + assert_eq!(bitmap.rank(BITMAP_MAX - 1000), 1); + + // middle range (spans two roaring bitmaps) + assert_eq!(bitmap.rank(BITMAP_MAX - 1), 1000); + assert_eq!(bitmap.rank(BITMAP_MAX), 1001); + assert_eq!(bitmap.rank(BITMAP_MAX + 1), 1002); + + // high boundary + assert_eq!(bitmap.rank(BITMAP_MAX + 4998), 5999); + assert_eq!(bitmap.rank(BITMAP_MAX + 4999), 6000); + assert_eq!(bitmap.rank(BITMAP_MAX + 5000), 6000); + + // end of bitmap + assert_eq!(bitmap.rank(u64::MAX), 6000); +} + +// A range that spans 2 roaring bitmaps with 2 containers each +const PROP_RANGE: RangeInclusive = BITMAP_MAX - (1 << 17)..=BITMAP_MAX + (1 << 17); + +proptest! { + #[test] + fn proptest_rank( + values in btree_set(PROP_RANGE, ..=1000), + checks in vec(PROP_RANGE, ..=100) + ){ + let bitmap = Roaring64::from_sorted_iter(values.iter().cloned()).unwrap(); + for i in checks { + let expected = values.iter().take_while(|&&x| x <= i).count() as u64; + assert_eq!(bitmap.rank(i), expected); + } + } +} diff --git a/tests/roaring64_select.rs b/tests/roaring64_select.rs new file mode 100644 index 000000000..55331ea85 --- /dev/null +++ b/tests/roaring64_select.rs @@ -0,0 +1,41 @@ +use proptest::{collection::btree_set, prelude::*}; +use roaring::Roaring64; + +#[test] +fn select() { + let bitmap = (0..2000).collect::(); + + assert_eq!(bitmap.select(0), Some(0)); +} + +#[test] +fn select_multiple_bitmap() { + let mut bitmap = (0..100_000).collect::(); + bitmap.append(u32::MAX as u64..u32::MAX as u64 + 100_000).expect("sorted integers"); + + assert_eq!(bitmap.select(0), Some(0)); + assert_eq!(bitmap.select(99_999), Some(99_999)); + assert_eq!(bitmap.select(100_000), Some(u32::MAX as u64)); + assert_eq!(bitmap.select(199_999), Some(u32::MAX as u64 + 99_999)); + assert_eq!(bitmap.select(200_000), None); + assert_eq!(bitmap.select(u64::MAX), None); +} + +#[test] +fn select_empty() { + let bitmap = Roaring64::new(); + + assert_eq!(bitmap.select(0), None); + assert_eq!(bitmap.select(1024), None); + assert_eq!(bitmap.select(u64::MAX), None); +} + +proptest! { + #[test] + fn proptest_select(values in btree_set(any::(), 1000)) { + let bitmap = Roaring64::from_sorted_iter(values.iter().cloned()).unwrap(); + for (i, value) in values.iter().cloned().enumerate() { + prop_assert_eq!(bitmap.select(i as u64), Some(value)); + } + } +} diff --git a/tests/roaring64_serialization.rs b/tests/roaring64_serialization.rs new file mode 100644 index 000000000..6af557b23 --- /dev/null +++ b/tests/roaring64_serialization.rs @@ -0,0 +1,44 @@ +use roaring::Roaring64; +use std::iter::FromIterator; + +fn serialize_deserialize(dataset: Dataset) +where + Dataset: IntoIterator, + I: Iterator, +{ + let rb = Roaring64::from_iter(dataset); + + let mut buffer = vec![]; + rb.serialize_into(&mut buffer).unwrap(); + + assert_eq!(buffer.len(), rb.serialized_size()); + + let new_rb = Roaring64::deserialize_from(&buffer[..]).unwrap(); + + assert_eq!(rb, new_rb); +} + +#[test] +fn empty() { + serialize_deserialize(vec![]) +} + +#[test] +fn basic() { + serialize_deserialize(vec![1, 2, 3, 4, 5, 100, 1000]) +} + +#[test] +fn basic_2() { + serialize_deserialize(vec![1, 2, 3, 4, 5, 100, 1000, 10000, 100000, 1000000]) +} + +#[test] +fn basic_3() { + let u32max = u32::MAX as u64; + serialize_deserialize( + vec![1, 2, 3, 4, 5, 100, 1000, 10000, 100000, 1000000, u32max + 10, u32max << 10] + .into_iter() + .chain(u32max..(u32max + 2 * (1 << 16))), + ) +} diff --git a/tests/roaring64_size_hint.rs b/tests/roaring64_size_hint.rs new file mode 100644 index 000000000..475187022 --- /dev/null +++ b/tests/roaring64_size_hint.rs @@ -0,0 +1,51 @@ +use roaring::Roaring64; + +#[test] +fn array() { + let bitmap = (0..2000).collect::(); + let mut iter = bitmap.iter(); + assert_eq!((2000, Some(2000)), iter.size_hint()); + iter.by_ref().take(1000).for_each(drop); + assert_eq!((1000, Some(1000)), iter.size_hint()); + iter.by_ref().for_each(drop); + assert_eq!((0, Some(0)), iter.size_hint()); +} + +#[test] +fn bitmap() { + let bitmap = (0..6000).collect::(); + let mut iter = bitmap.iter(); + assert_eq!((6000, Some(6000)), iter.size_hint()); + iter.by_ref().take(3000).for_each(drop); + assert_eq!((3000, Some(3000)), iter.size_hint()); + iter.by_ref().for_each(drop); + assert_eq!((0, Some(0)), iter.size_hint()); +} + +#[test] +fn arrays() { + let bitmap = + ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)).collect::(); + let mut iter = bitmap.iter(); + assert_eq!((5000, Some(5000)), iter.size_hint()); + iter.by_ref().take(3000).for_each(drop); + assert_eq!((2000, Some(2000)), iter.size_hint()); + iter.by_ref().for_each(drop); + assert_eq!((0, Some(0)), iter.size_hint()); +} + +#[test] +fn bitmaps() { + let bitmap = + ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)).collect::(); + let mut iter = bitmap.iter(); + assert_eq!((28000, Some(28000)), iter.size_hint()); + iter.by_ref().take(2000).for_each(drop); + assert_eq!((26000, Some(26000)), iter.size_hint()); + iter.by_ref().take(5000).for_each(drop); + assert_eq!((21000, Some(21000)), iter.size_hint()); + iter.by_ref().take(20000).for_each(drop); + assert_eq!((1000, Some(1000)), iter.size_hint()); + iter.by_ref().for_each(drop); + assert_eq!((0, Some(0)), iter.size_hint()); +} diff --git a/tests/roaring64_symmetric_difference_with.rs b/tests/roaring64_symmetric_difference_with.rs new file mode 100644 index 000000000..039147e41 --- /dev/null +++ b/tests/roaring64_symmetric_difference_with.rs @@ -0,0 +1,115 @@ +use roaring::Roaring64; + +#[test] +fn array() { + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..3000).collect::(); + let bitmap3 = ((0..1000).chain(2000..3000)).collect::(); + + bitmap1 ^= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn no_symmetric_difference() { + let mut bitmap1 = (0..2).collect::(); + let bitmap2 = (0..2).collect::(); + + bitmap1 ^= bitmap2; + + assert_eq!(bitmap1, Roaring64::new()); +} + +#[test] +fn array_and_bitmap() { + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..8000).collect::(); + let bitmap3 = ((0..1000).chain(2000..8000)).collect::(); + + bitmap1 ^= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmap_to_bitmap() { + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (6000..18000).collect::(); + let bitmap3 = ((0..6000).chain(12000..18000)).collect::(); + + bitmap1 ^= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmap_to_array() { + let mut bitmap1 = (0..6000).collect::(); + let bitmap2 = (2000..7000).collect::(); + let bitmap3 = ((0..2000).chain(6000..7000)).collect::(); + + bitmap1 ^= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmap_and_array_to_bitmap() { + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (11000..14000).collect::(); + let bitmap3 = ((0..11000).chain(12000..14000)).collect::(); + + bitmap1 ^= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmap_and_array_to_array() { + let mut bitmap1 = (0..6000).collect::(); + let bitmap2 = (3000..7000).collect::(); + let bitmap3 = ((0..3000).chain(6000..7000)).collect::(); + + bitmap1 ^= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn arrays() { + let mut bitmap1 = + ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)).collect::(); + let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_000_001)) + .collect::(); + let bitmap3 = ((0..1000) + .chain(1_000_000..1_001_000) + .chain(2000..3000) + .chain(1_002_000..1_003_000) + .chain(2_000_000..2_000_001) + .chain(3_000_000..3_001_000)) + .collect::(); + + bitmap1 ^= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmaps() { + let mut bitmap1 = + ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)).collect::(); + let bitmap2 = ((3000..7000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) + .collect::(); + let bitmap3 = ((0..3000) + .chain(1_000_000..1_006_000) + .chain(6000..7000) + .chain(1_012_000..1_018_000) + .chain(2_000_000..2_010_000) + .chain(3_000_000..3_010_000)) + .collect::(); + + bitmap1 ^= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} diff --git a/tests/roaring64_union_with.rs b/tests/roaring64_union_with.rs new file mode 100644 index 000000000..f2f7b8c79 --- /dev/null +++ b/tests/roaring64_union_with.rs @@ -0,0 +1,90 @@ +use roaring::Roaring64; + +#[test] +fn array_to_array() { + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..3000).collect::(); + let bitmap3 = (0..3000).collect::(); + + bitmap1 |= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn array_to_bitmap() { + let mut bitmap1 = (0..4000).collect::(); + let bitmap2 = (4000..8000).collect::(); + let bitmap3 = (0..8000).collect::(); + + bitmap1 |= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn array_and_bitmap() { + let mut bitmap1 = (0..2000).collect::(); + let bitmap2 = (1000..8000).collect::(); + let bitmap3 = (0..8000).collect::(); + + bitmap1 |= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmap() { + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (6000..18000).collect::(); + let bitmap3 = (0..18000).collect::(); + + bitmap1 |= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmap_and_array() { + let mut bitmap1 = (0..12000).collect::(); + let bitmap2 = (10000..13000).collect::(); + let bitmap3 = (0..13000).collect::(); + + bitmap1 |= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn arrays() { + let mut bitmap1 = + ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)).collect::(); + let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) + .collect::(); + let bitmap3 = ((0..3000) + .chain(1_000_000..1_003_000) + .chain(2_000_000..2_001_000) + .chain(3_000_000..3_001_000)) + .collect::(); + + bitmap1 |= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} + +#[test] +fn bitmaps() { + let mut bitmap1 = + ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)).collect::(); + let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) + .collect::(); + let bitmap3 = ((0..9000) + .chain(1_000_000..1_018_000) + .chain(2_000_000..2_010_000) + .chain(3_000_000..3_010_000)) + .collect::(); + + bitmap1 |= bitmap2; + + assert_eq!(bitmap1, bitmap3); +} diff --git a/tests/treemap_clone.rs b/tests/treemap_clone.rs deleted file mode 100644 index 88e64d062..000000000 --- a/tests/treemap_clone.rs +++ /dev/null @@ -1,40 +0,0 @@ -// extern crate roaring; -// use roaring::RoaringTreemap; - -// #[test] -// #[allow(clippy::redundant_clone)] -// fn array() { -// let original = (0..2000).collect::(); -// let clone = original.clone(); - -// assert_eq!(clone, original); -// } - -// #[test] -// #[allow(clippy::redundant_clone)] -// fn bitmap() { -// let original = (0..6000).collect::(); -// let clone = original.clone(); - -// assert_eq!(clone, original); -// } - -// #[test] -// #[allow(clippy::redundant_clone)] -// fn arrays() { -// let original = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) -// .collect::(); -// let clone = original.clone(); - -// assert_eq!(clone, original); -// } - -// #[test] -// #[allow(clippy::redundant_clone)] -// fn bitmaps() { -// let original = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) -// .collect::(); -// let clone = original.clone(); - -// assert_eq!(clone, original); -// } diff --git a/tests/treemap_difference_with.rs b/tests/treemap_difference_with.rs deleted file mode 100644 index d2389a03c..000000000 --- a/tests/treemap_difference_with.rs +++ /dev/null @@ -1,117 +0,0 @@ -// extern crate roaring; -// use roaring::RoaringTreemap; - -// #[test] -// fn array() { -// let mut bitmap1 = (0..2000).collect::(); -// let bitmap2 = (1000..3000).collect::(); -// let bitmap3 = (0..1000).collect::(); - -// bitmap1 -= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn no_difference() { -// let mut bitmap1 = (1..3).collect::(); -// let bitmap2 = (1..3).collect::(); - -// bitmap1 -= bitmap2; - -// assert_eq!(bitmap1, RoaringTreemap::new()); -// } - -// #[test] -// fn array_and_bitmap() { -// let mut bitmap1 = (0..2000).collect::(); -// let bitmap2 = (1000..8000).collect::(); -// let bitmap3 = (0..1000).collect::(); - -// bitmap1 -= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmap_to_bitmap() { -// let mut bitmap1 = (0..12000).collect::(); -// let bitmap2 = (6000..18000).collect::(); -// let bitmap3 = (0..6000).collect::(); - -// bitmap1 -= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmap_to_array() { -// let mut bitmap1 = (0..6000).collect::(); -// let bitmap2 = (3000..9000).collect::(); -// let bitmap3 = (0..3000).collect::(); - -// bitmap1 -= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmap_and_array_to_bitmap() { -// let mut bitmap1 = (0..12000).collect::(); -// let bitmap2 = (9000..12000).collect::(); -// let bitmap3 = (0..9000).collect::(); - -// bitmap1 -= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmap_and_array_to_array() { -// let mut bitmap1 = (0..6000).collect::(); -// let bitmap2 = (3000..6000).collect::(); -// let bitmap3 = (0..3000).collect::(); - -// bitmap1 -= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn arrays() { -// let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) -// .collect::(); -// let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) -// .collect::(); -// let bitmap3 = ((0..1000).chain(1_000_000..1_001_000)).collect::(); - -// bitmap1 -= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn arrays_removing_one_whole_container() { -// let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) -// .collect::(); -// let bitmap2 = ((0..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) -// .collect::(); -// let bitmap3 = (1_000_000..1_001_000).collect::(); - -// bitmap1 -= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmaps() { -// let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) -// .collect::(); -// let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) -// .collect::(); -// let bitmap3 = ((0..3000).chain(1_000_000..1_006_000)).collect::(); - -// bitmap1 -= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } diff --git a/tests/treemap_intersect_with.rs b/tests/treemap_intersect_with.rs deleted file mode 100644 index c739c3c8c..000000000 --- a/tests/treemap_intersect_with.rs +++ /dev/null @@ -1,93 +0,0 @@ -// extern crate roaring; -// use roaring::RoaringTreemap; - -// #[test] -// fn array() { -// let mut bitmap1 = (0..2000).collect::(); -// let bitmap2 = (1000..3000).collect::(); -// let bitmap3 = (1000..2000).collect::(); - -// bitmap1 &= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn no_intersection() { -// let mut bitmap1 = (0..2).collect::(); -// let bitmap2 = (3..4).collect::(); - -// bitmap1 &= bitmap2; - -// assert_eq!(bitmap1, RoaringTreemap::new()); -// } - -// #[test] -// fn array_and_bitmap() { -// let mut bitmap1 = (0..2000).collect::(); -// let bitmap2 = (1000..8000).collect::(); -// let bitmap3 = (1000..2000).collect::(); - -// bitmap1 &= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmap_to_bitmap() { -// let mut bitmap1 = (0..12000).collect::(); -// let bitmap2 = (6000..18000).collect::(); -// let bitmap3 = (6000..12000).collect::(); - -// bitmap1 &= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmap_to_array() { -// let mut bitmap1 = (0..6000).collect::(); -// let bitmap2 = (3000..9000).collect::(); -// let bitmap3 = (3000..6000).collect::(); - -// bitmap1 &= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmap_and_array() { -// let mut bitmap1 = (0..12000).collect::(); -// let bitmap2 = (7000..9000).collect::(); -// let bitmap3 = (7000..9000).collect::(); - -// bitmap1 &= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn arrays() { -// let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)) -// .collect::(); -// let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) -// .collect::(); -// let bitmap3 = ((1000..2000).chain(1_001_000..1_002_000)).collect::(); - -// bitmap1 &= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmaps() { -// let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)) -// .collect::(); -// let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) -// .collect::(); -// let bitmap3 = ((3000..6000).chain(1_006_000..1_012_000)).collect::(); - -// bitmap1 &= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } diff --git a/tests/treemap_is_disjoint.rs b/tests/treemap_is_disjoint.rs deleted file mode 100644 index a5f0e7ee8..000000000 --- a/tests/treemap_is_disjoint.rs +++ /dev/null @@ -1,62 +0,0 @@ -// extern crate roaring; -// use roaring::RoaringTreemap; - -// #[test] -// fn array() { -// let bitmap1 = (0..2000).collect::(); -// let bitmap2 = (4000..6000).collect::(); -// assert!(bitmap1.is_disjoint(&bitmap2)); -// } - -// #[test] -// fn array_not() { -// let bitmap1 = (0..4000).collect::(); -// let bitmap2 = (2000..6000).collect::(); -// assert!(!bitmap1.is_disjoint(&bitmap2)); -// } - -// #[test] -// fn bitmap() { -// let bitmap1 = (0..6000).collect::(); -// let bitmap2 = (10000..16000).collect::(); -// assert!(bitmap1.is_disjoint(&bitmap2)); -// } - -// #[test] -// fn bitmap_not() { -// let bitmap1 = (0..10000).collect::(); -// let bitmap2 = (5000..15000).collect::(); -// assert!(!bitmap1.is_disjoint(&bitmap2)); -// } - -// #[test] -// fn arrays() { -// let bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_002_000)) -// .collect::(); -// let bitmap2 = ((100_000..102_000).chain(1_100_000..1_102_000)).collect::(); -// assert!(bitmap1.is_disjoint(&bitmap2)); -// } - -// #[test] -// fn arrays_not() { -// let bitmap1 = ((0..2_000).chain(1_000_000..1_002_000).chain(2_000_000..2_002_000)) -// .collect::(); -// let bitmap2 = ((100_000..102_000).chain(1_001_000..1_003_000)).collect::(); -// assert!(!bitmap1.is_disjoint(&bitmap2)); -// } - -// #[test] -// fn bitmaps() { -// let bitmap1 = ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_006_000)) -// .collect::(); -// let bitmap2 = ((100_000..106_000).chain(1_100_000..1_106_000)).collect::(); -// assert!(bitmap1.is_disjoint(&bitmap2)); -// } - -// #[test] -// fn bitmaps_not() { -// let bitmap1 = ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_006_000)) -// .collect::(); -// let bitmap2 = ((100_000..106_000).chain(1_004_000..1_008_000)).collect::(); -// assert!(!bitmap1.is_disjoint(&bitmap2)); -// } diff --git a/tests/treemap_is_subset.rs b/tests/treemap_is_subset.rs deleted file mode 100644 index f41908f5c..000000000 --- a/tests/treemap_is_subset.rs +++ /dev/null @@ -1,80 +0,0 @@ -// extern crate roaring; -// use roaring::RoaringTreemap; - -// #[test] -// fn array_not() { -// let sup = (0..2000).collect::(); -// let sub = (1000..3000).collect::(); -// assert!(!sub.is_subset(&sup)); -// } - -// #[test] -// fn array() { -// let sup = (0..4000).collect::(); -// let sub = (2000..3000).collect::(); -// assert!(sub.is_subset(&sup)); -// } - -// #[test] -// fn array_bitmap_not() { -// let sup = (0..2000).collect::(); -// let sub = (1000..15000).collect::(); -// assert!(!sub.is_subset(&sup)); -// } - -// #[test] -// fn bitmap_not() { -// let sup = (0..6000).collect::(); -// let sub = (4000..10000).collect::(); -// assert!(!sub.is_subset(&sup)); -// } - -// #[test] -// fn bitmap() { -// let sup = (0..20000).collect::(); -// let sub = (5000..15000).collect::(); -// assert!(sub.is_subset(&sup)); -// } - -// #[test] -// fn bitmap_array_not() { -// let sup = (0..20000).collect::(); -// let sub = (19000..21000).collect::(); -// assert!(!sub.is_subset(&sup)); -// } - -// #[test] -// fn bitmap_array() { -// let sup = (0..20000).collect::(); -// let sub = (18000..20000).collect::(); -// assert!(sub.is_subset(&sup)); -// } - -// #[test] -// fn arrays_not() { -// let sup = ((0..2000).chain(1_000_000..1_002_000)).collect::(); -// let sub = ((100_000..102_000).chain(1_100_000..1_102_000)).collect::(); -// assert!(!sub.is_subset(&sup)); -// } - -// #[test] -// fn arrays() { -// let sup = ((0..3000).chain(100_000..103_000)).collect::(); -// let sub = ((0..2000).chain(100_000..102_000)).collect::(); -// assert!(sub.is_subset(&sup)); -// } - -// #[test] -// fn bitmaps_not() { -// let sup = ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_010_000)) -// .collect::(); -// let sub = ((100_000..106_000).chain(1_100_000..1_106_000)).collect::(); -// assert!(!sub.is_subset(&sup)); -// } - -// #[test] -// fn bitmaps() { -// let sup = ((0..1_000_000).chain(2_000_000..2_010_000)).collect::(); -// let sub = ((0..10_000).chain(500_000..510_000)).collect::(); -// assert!(sub.is_subset(&sup)); -// } diff --git a/tests/treemap_iter.rs b/tests/treemap_iter.rs deleted file mode 100644 index c35fda421..000000000 --- a/tests/treemap_iter.rs +++ /dev/null @@ -1,129 +0,0 @@ -// extern crate roaring; -// mod iter; -// use roaring::RoaringTreemap; - -// use iter::outside_in; -// use proptest::arbitrary::any; -// use proptest::collection::btree_set; -// use proptest::proptest; -// use std::iter::FromIterator; - -// #[test] -// fn range() { -// let original = (0..2000).collect::(); -// let clone = RoaringTreemap::from_iter(&original); -// let clone2 = RoaringTreemap::from_iter(original.clone()); - -// assert_eq!(clone, original); -// assert_eq!(clone2, original); -// } - -// #[test] -// fn array() { -// let original = (0..5).collect::(); -// let clone = RoaringTreemap::from([0, 1, 2, 3, 4]); - -// assert_eq!(clone, original); -// } - -// #[test] -// fn bitmap() { -// let original = (0..6000).collect::(); -// let clone = RoaringTreemap::from_iter(&original); -// let clone2 = RoaringTreemap::from_iter(original.clone()); - -// assert_eq!(clone, original); -// assert_eq!(clone2, original); -// } - -// #[test] -// fn arrays() { -// let original = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) -// .collect::(); -// let clone = RoaringTreemap::from_iter(&original); -// let clone2 = RoaringTreemap::from_iter(original.clone()); - -// assert_eq!(clone, original); -// assert_eq!(clone2, original); -// } - -// #[test] -// fn bitmaps() { -// let original = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) -// .collect::(); -// let clone = RoaringTreemap::from_iter(&original); -// let clone2 = RoaringTreemap::from_iter(original.clone()); - -// assert_eq!(clone, original); -// assert_eq!(clone2, original); -// } - -// #[test] -// fn bitmaps_iterator() { -// let original = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) -// .collect::(); -// let clone = RoaringTreemap::from_bitmaps(original.bitmaps().map(|(p, b)| (p, b.clone()))); -// let clone2 = original.bitmaps().map(|(p, b)| (p, b.clone())).collect::(); - -// assert_eq!(clone, original); -// assert_eq!(clone2, original); -// } - -// proptest! { -// #[test] -// fn iter(values in btree_set(any::(), ..=10_000)) { -// let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); - -// assert!(values.into_iter().eq(bitmap)); -// } -// } - -// #[test] -// fn rev() { -// let values = (1..3) -// .chain(1_000_000..1_012_003) -// .chain(2_000_001..2_000_003) -// .chain(2_000_000_000_001..2_000_000_000_003); -// let bitmap = RoaringTreemap::from_iter(values.clone()); - -// assert!(values.into_iter().rev().eq(bitmap.iter().rev())); -// } - -// proptest! { -// #[test] -// fn rev_iter(values in btree_set(any::(), ..=10_000)) { -// let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); - -// assert!(values.into_iter().rev().eq(bitmap.iter().rev())); -// } -// } - -// #[test] -// fn from_iter() { -// // This test verifies that the public API allows conversion from iterators -// // with u64 as well as &u64 elements. -// let vals = vec![1, 5, 1_000_000_000_000_000]; -// let a = RoaringTreemap::from_iter(vals.iter()); -// let b = RoaringTreemap::from_iter(vals); -// assert_eq!(a, b); -// } - -// #[test] -// fn interleaved() { -// let values = (1..3) -// .chain(1_000_000..1_012_003) -// .chain(2_000_001..2_000_003) -// .chain(2_000_000_000_001..2_000_000_000_003); -// let bitmap = RoaringTreemap::from_iter(values.clone()); - -// assert!(outside_in(values).eq(outside_in(bitmap))); -// } - -// proptest! { -// #[test] -// fn interleaved_iter(values in btree_set(any::(), 50_000..=100_000)) { -// let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); - -// assert!(outside_in(values).eq(outside_in(bitmap))); -// } -// } diff --git a/tests/treemap_lib.rs b/tests/treemap_lib.rs deleted file mode 100644 index 60211c88b..000000000 --- a/tests/treemap_lib.rs +++ /dev/null @@ -1,119 +0,0 @@ -// extern crate roaring; -// use roaring::RoaringTreemap; - -// #[test] -// fn smoke() { -// let mut bitmap = RoaringTreemap::new(); -// assert_eq!(bitmap.len(), 0); -// assert!(bitmap.is_empty()); -// bitmap.remove(0); -// assert_eq!(bitmap.len(), 0); -// assert!(bitmap.is_empty()); -// bitmap.insert(1); -// assert!(bitmap.contains(1)); -// assert_eq!(bitmap.len(), 1); -// assert!(!bitmap.is_empty()); -// bitmap.insert(u64::MAX - 2); -// assert!(bitmap.contains(u64::MAX - 2)); -// assert_eq!(bitmap.len(), 2); -// bitmap.insert(u64::MAX); -// assert!(bitmap.contains(u64::MAX)); -// assert_eq!(bitmap.len(), 3); -// bitmap.insert(2); -// assert!(bitmap.contains(2)); -// assert_eq!(bitmap.len(), 4); -// bitmap.remove(2); -// assert!(!bitmap.contains(2)); -// assert_eq!(bitmap.len(), 3); -// assert!(!bitmap.contains(0)); -// assert!(bitmap.contains(1)); -// assert!(!bitmap.contains(100)); -// assert!(bitmap.contains(u64::MAX - 2)); -// assert!(!bitmap.contains(u64::MAX - 1)); -// assert!(bitmap.contains(u64::MAX)); -// } - -// #[test] -// fn insert_range() { -// let ranges = 0..0x1000; -// const SIGMA: u64 = u32::MAX as u64; - -// let mut bitmap = RoaringTreemap::new(); -// assert_eq!(bitmap.insert_range(ranges), 0x1000); -// assert_eq!(bitmap.len(), 0x1000); -// assert_eq!(bitmap.max(), Some(0xFFF)); - -// assert_eq!(bitmap.insert_range(u32::MAX as u64 - 1..u32::MAX as u64 + 1), 2); -// assert!(bitmap.contains(2)); -// assert!(bitmap.contains(0xFFF)); -// assert!(!bitmap.contains(0x1000)); - -// bitmap.clear(); -// bitmap.insert_range(2 * SIGMA..=4 * SIGMA); - -// assert_eq!(bitmap.min(), Some(2 * SIGMA)); -// assert_eq!(bitmap.max(), Some(4 * SIGMA)); - -// assert!(bitmap.contains(3 * SIGMA)); -// } - -// #[test] -// fn remove_range() { -// let ranges = [0u64, 1, 63, 64, 65, 100, 4096 - 1, 4096, 4096 + 1, 65536 - 1]; -// for (i, &a) in ranges.iter().enumerate() { -// for &b in &ranges[i..] { -// let mut bitmap = (0..=65536).collect::(); -// assert_eq!(bitmap.remove_range(a..b), (b - a)); -// assert_eq!(bitmap, ((0..a).chain(b..=65536)).collect::()); -// } -// } -// } - -// #[test] -// fn test_max() { -// let mut bitmap = RoaringTreemap::new(); -// assert_eq!(bitmap.max(), None); -// bitmap.insert(0); -// assert_eq!(bitmap.max(), Some(0)); -// bitmap.insert(1); -// assert_eq!(bitmap.max(), Some(1)); -// bitmap.insert(u64::MAX); -// assert_eq!(bitmap.max(), Some(u64::MAX)); -// } - -// #[test] -// fn test_min() { -// let mut bitmap = RoaringTreemap::new(); -// assert_eq!(bitmap.min(), None); -// bitmap.insert(u64::MAX); -// assert_eq!(bitmap.min(), Some(u64::MAX)); -// bitmap.insert(1); -// assert_eq!(bitmap.min(), Some(1)); -// bitmap.insert(0); -// assert_eq!(bitmap.min(), Some(0)); -// } - -// #[test] -// fn to_bitmap() { -// let bitmap = (0..5000).collect::(); -// assert_eq!(bitmap.len(), 5000); -// for i in 1..5000 { -// assert!(bitmap.contains(i)); -// } -// assert!(!bitmap.contains(5001)); -// } - -// #[test] -// fn to_array() { -// let mut bitmap = (0..5000).collect::(); -// for i in 3000..5000 { -// bitmap.remove(i); -// } -// assert_eq!(bitmap.len(), 3000); -// for i in 0..3000 { -// assert!(bitmap.contains(i)); -// } -// for i in 3000..5000 { -// assert!(!bitmap.contains(i)); -// } -// } diff --git a/tests/treemap_ops.rs b/tests/treemap_ops.rs deleted file mode 100644 index 9512159b9..000000000 --- a/tests/treemap_ops.rs +++ /dev/null @@ -1,78 +0,0 @@ -// extern crate roaring; -// use roaring::RoaringTreemap; - -// #[test] -// fn or() { -// let mut rb1 = (1..4).collect::(); -// let rb2 = (3..6).collect::(); -// let rb3 = (1..6).collect::(); - -// assert_eq!(rb3, &rb1 | &rb2); -// assert_eq!(rb3, &rb1 | rb2.clone()); -// assert_eq!(rb3, rb1.clone() | &rb2); -// assert_eq!(rb3, rb1.clone() | rb2.clone()); -// assert_eq!(rb3.len(), rb1.union_len(&rb2)); - -// rb1 |= &rb2; -// rb1 |= rb2; - -// assert_eq!(rb3, rb1); -// } - -// #[test] -// fn and() { -// let mut rb1 = (1..4).collect::(); -// let rb2 = (3..6).collect::(); -// let rb3 = (3..4).collect::(); - -// assert_eq!(rb3, &rb1 & &rb2); -// assert_eq!(rb3, &rb1 & rb2.clone()); -// assert_eq!(rb3, rb1.clone() & &rb2); -// assert_eq!(rb3, rb1.clone() & rb2.clone()); -// assert_eq!(rb3.len(), rb1.intersection_len(&rb2)); - -// rb1 &= &rb2; -// rb1 &= rb2; - -// assert_eq!(rb3, rb1); -// } - -// #[test] -// fn sub() { -// let mut rb1 = (1..4).collect::(); -// let rb2 = (3..6).collect::(); -// let rb3 = (1..3).collect::(); - -// assert_eq!(rb3, &rb1 - &rb2); -// assert_eq!(rb3, &rb1 - rb2.clone()); -// assert_eq!(rb3, rb1.clone() - &rb2); -// assert_eq!(rb3, rb1.clone() - rb2.clone()); -// assert_eq!(rb3.len(), rb1.difference_len(&rb2)); - -// rb1 -= &rb2; -// rb1 -= rb2; - -// assert_eq!(rb3, rb1); -// } - -// #[test] -// fn xor() { -// let mut rb1 = (1..4).collect::(); -// let rb2 = (3..6).collect::(); -// let rb3 = ((1..3).chain(4..6)).collect::(); -// let rb4 = (0..0).collect::(); - -// assert_eq!(rb3, &rb1 ^ &rb2); -// assert_eq!(rb3, &rb1 ^ rb2.clone()); -// assert_eq!(rb3, rb1.clone() ^ &rb2); -// assert_eq!(rb3, rb1.clone() ^ rb2.clone()); -// assert_eq!(rb3.len(), rb1.symmetric_difference_len(&rb2)); - -// rb1 ^= &rb2; - -// assert_eq!(rb3, rb1); - -// rb1 ^= rb3; - -// assert_eq!(rb4, rb1); -// } diff --git a/tests/treemap_rank.rs b/tests/treemap_rank.rs deleted file mode 100644 index 71984cbcd..000000000 --- a/tests/treemap_rank.rs +++ /dev/null @@ -1,54 +0,0 @@ -// extern crate roaring; - -// use proptest::collection::{btree_set, vec}; -// use proptest::prelude::*; -// use roaring::RoaringTreemap; -// use std::ops::RangeInclusive; - -// const BITMAP_MAX: u64 = u32::MAX as u64; - -// #[test] -// fn rank_roaring_bitmaps() { -// // A treemap with two roaring bitmaps. -// // The lower one contains one array container with the highest 1000 values -// // The higher one contains one bitmap at with the lowest 5000 values -// let treemap = RoaringTreemap::from_sorted_iter(BITMAP_MAX - 1000..BITMAP_MAX + 5000).unwrap(); - -// // start of treemap -// assert_eq!(treemap.rank(0), 0); - -// // low boundary -// assert_eq!(treemap.rank(BITMAP_MAX - 1002), 0); -// assert_eq!(treemap.rank(BITMAP_MAX - 1001), 0); -// assert_eq!(treemap.rank(BITMAP_MAX - 1000), 1); - -// // middle range (spans two roaring bitmaps) -// assert_eq!(treemap.rank(BITMAP_MAX - 1), 1000); -// assert_eq!(treemap.rank(BITMAP_MAX), 1001); -// assert_eq!(treemap.rank(BITMAP_MAX + 1), 1002); - -// // high boundary -// assert_eq!(treemap.rank(BITMAP_MAX + 4998), 5999); -// assert_eq!(treemap.rank(BITMAP_MAX + 4999), 6000); -// assert_eq!(treemap.rank(BITMAP_MAX + 5000), 6000); - -// // end of treemap -// assert_eq!(treemap.rank(u64::MAX), 6000); -// } - -// // A range that spans 2 roaring bitmaps with 2 containers each -// const PROP_RANGE: RangeInclusive = BITMAP_MAX - (1 << 17)..=BITMAP_MAX + (1 << 17); - -// proptest! { -// #[test] -// fn proptest_rank( -// values in btree_set(PROP_RANGE, ..=1000), -// checks in vec(PROP_RANGE, ..=100) -// ){ -// let treemap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); -// for i in checks { -// let expected = values.iter().take_while(|&&x| x <= i).count() as u64; -// assert_eq!(treemap.rank(i), expected); -// } -// } -// } diff --git a/tests/treemap_select.rs b/tests/treemap_select.rs deleted file mode 100644 index 312bc4ea2..000000000 --- a/tests/treemap_select.rs +++ /dev/null @@ -1,44 +0,0 @@ -// extern crate roaring; - -// use proptest::collection::btree_set; -// use proptest::prelude::*; -// use roaring::RoaringTreemap; - -// #[test] -// fn select() { -// let bitmap = (0..2000).collect::(); - -// assert_eq!(bitmap.select(0), Some(0)); -// } - -// #[test] -// fn select_multiple_bitmap() { -// let mut bitmap = (0..100_000).collect::(); -// bitmap.append(u32::MAX as u64..u32::MAX as u64 + 100_000).expect("sorted integers"); - -// assert_eq!(bitmap.select(0), Some(0)); -// assert_eq!(bitmap.select(99_999), Some(99_999)); -// assert_eq!(bitmap.select(100_000), Some(u32::MAX as u64)); -// assert_eq!(bitmap.select(199_999), Some(u32::MAX as u64 + 99_999)); -// assert_eq!(bitmap.select(200_000), None); -// assert_eq!(bitmap.select(u64::MAX), None); -// } - -// #[test] -// fn select_empty() { -// let bitmap = RoaringTreemap::new(); - -// assert_eq!(bitmap.select(0), None); -// assert_eq!(bitmap.select(1024), None); -// assert_eq!(bitmap.select(u64::MAX), None); -// } - -// proptest! { -// #[test] -// fn proptest_select(values in btree_set(any::(), 1000)) { -// let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); -// for (i, value) in values.iter().cloned().enumerate() { -// prop_assert_eq!(bitmap.select(i as u64), Some(value)); -// } -// } -// } diff --git a/tests/treemap_serialization.rs b/tests/treemap_serialization.rs deleted file mode 100644 index 303ff7b3d..000000000 --- a/tests/treemap_serialization.rs +++ /dev/null @@ -1,44 +0,0 @@ -// use roaring::RoaringTreemap; -// use std::iter::FromIterator; - -// fn serialize_deserialize(dataset: Dataset) -// where -// Dataset: IntoIterator, -// I: Iterator, -// { -// let rb = RoaringTreemap::from_iter(dataset); - -// let mut buffer = vec![]; -// rb.serialize_into(&mut buffer).unwrap(); - -// assert_eq!(buffer.len(), rb.serialized_size()); - -// let new_rb = RoaringTreemap::deserialize_from(&buffer[..]).unwrap(); - -// assert_eq!(rb, new_rb); -// } - -// #[test] -// fn empty() { -// serialize_deserialize(vec![]) -// } - -// #[test] -// fn basic() { -// serialize_deserialize(vec![1, 2, 3, 4, 5, 100, 1000]) -// } - -// #[test] -// fn basic_2() { -// serialize_deserialize(vec![1, 2, 3, 4, 5, 100, 1000, 10000, 100000, 1000000]) -// } - -// #[test] -// fn basic_3() { -// let u32max = u32::MAX as u64; -// serialize_deserialize( -// vec![1, 2, 3, 4, 5, 100, 1000, 10000, 100000, 1000000, u32max + 10, u32max << 10] -// .into_iter() -// .chain(u32max..(u32max + 2 * (1 << 16))), -// ) -// } diff --git a/tests/treemap_size_hint.rs b/tests/treemap_size_hint.rs deleted file mode 100644 index 367fd671c..000000000 --- a/tests/treemap_size_hint.rs +++ /dev/null @@ -1,52 +0,0 @@ -// extern crate roaring; -// use roaring::RoaringTreemap; - -// #[test] -// fn array() { -// let bitmap = (0..2000).collect::(); -// let mut iter = bitmap.iter(); -// assert_eq!((2000, Some(2000)), iter.size_hint()); -// iter.by_ref().take(1000).for_each(drop); -// assert_eq!((1000, Some(1000)), iter.size_hint()); -// iter.by_ref().for_each(drop); -// assert_eq!((0, Some(0)), iter.size_hint()); -// } - -// #[test] -// fn bitmap() { -// let bitmap = (0..6000).collect::(); -// let mut iter = bitmap.iter(); -// assert_eq!((6000, Some(6000)), iter.size_hint()); -// iter.by_ref().take(3000).for_each(drop); -// assert_eq!((3000, Some(3000)), iter.size_hint()); -// iter.by_ref().for_each(drop); -// assert_eq!((0, Some(0)), iter.size_hint()); -// } - -// #[test] -// fn arrays() { -// let bitmap = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) -// .collect::(); -// let mut iter = bitmap.iter(); -// assert_eq!((5000, Some(5000)), iter.size_hint()); -// iter.by_ref().take(3000).for_each(drop); -// assert_eq!((2000, Some(2000)), iter.size_hint()); -// iter.by_ref().for_each(drop); -// assert_eq!((0, Some(0)), iter.size_hint()); -// } - -// #[test] -// fn bitmaps() { -// let bitmap = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) -// .collect::(); -// let mut iter = bitmap.iter(); -// assert_eq!((28000, Some(28000)), iter.size_hint()); -// iter.by_ref().take(2000).for_each(drop); -// assert_eq!((26000, Some(26000)), iter.size_hint()); -// iter.by_ref().take(5000).for_each(drop); -// assert_eq!((21000, Some(21000)), iter.size_hint()); -// iter.by_ref().take(20000).for_each(drop); -// assert_eq!((1000, Some(1000)), iter.size_hint()); -// iter.by_ref().for_each(drop); -// assert_eq!((0, Some(0)), iter.size_hint()); -// } diff --git a/tests/treemap_symmetric_difference_with.rs b/tests/treemap_symmetric_difference_with.rs deleted file mode 100644 index 176527da3..000000000 --- a/tests/treemap_symmetric_difference_with.rs +++ /dev/null @@ -1,116 +0,0 @@ -// extern crate roaring; -// use roaring::RoaringTreemap; - -// #[test] -// fn array() { -// let mut bitmap1 = (0..2000).collect::(); -// let bitmap2 = (1000..3000).collect::(); -// let bitmap3 = ((0..1000).chain(2000..3000)).collect::(); - -// bitmap1 ^= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn no_symmetric_difference() { -// let mut bitmap1 = (0..2).collect::(); -// let bitmap2 = (0..2).collect::(); - -// bitmap1 ^= bitmap2; - -// assert_eq!(bitmap1, RoaringTreemap::new()); -// } - -// #[test] -// fn array_and_bitmap() { -// let mut bitmap1 = (0..2000).collect::(); -// let bitmap2 = (1000..8000).collect::(); -// let bitmap3 = ((0..1000).chain(2000..8000)).collect::(); - -// bitmap1 ^= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmap_to_bitmap() { -// let mut bitmap1 = (0..12000).collect::(); -// let bitmap2 = (6000..18000).collect::(); -// let bitmap3 = ((0..6000).chain(12000..18000)).collect::(); - -// bitmap1 ^= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmap_to_array() { -// let mut bitmap1 = (0..6000).collect::(); -// let bitmap2 = (2000..7000).collect::(); -// let bitmap3 = ((0..2000).chain(6000..7000)).collect::(); - -// bitmap1 ^= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmap_and_array_to_bitmap() { -// let mut bitmap1 = (0..12000).collect::(); -// let bitmap2 = (11000..14000).collect::(); -// let bitmap3 = ((0..11000).chain(12000..14000)).collect::(); - -// bitmap1 ^= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmap_and_array_to_array() { -// let mut bitmap1 = (0..6000).collect::(); -// let bitmap2 = (3000..7000).collect::(); -// let bitmap3 = ((0..3000).chain(6000..7000)).collect::(); - -// bitmap1 ^= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn arrays() { -// let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)) -// .collect::(); -// let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_000_001)) -// .collect::(); -// let bitmap3 = ((0..1000) -// .chain(1_000_000..1_001_000) -// .chain(2000..3000) -// .chain(1_002_000..1_003_000) -// .chain(2_000_000..2_000_001) -// .chain(3_000_000..3_001_000)) -// .collect::(); - -// bitmap1 ^= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmaps() { -// let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)) -// .collect::(); -// let bitmap2 = ((3000..7000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) -// .collect::(); -// let bitmap3 = ((0..3000) -// .chain(1_000_000..1_006_000) -// .chain(6000..7000) -// .chain(1_012_000..1_018_000) -// .chain(2_000_000..2_010_000) -// .chain(3_000_000..3_010_000)) -// .collect::(); - -// bitmap1 ^= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } diff --git a/tests/treemap_union_with.rs b/tests/treemap_union_with.rs deleted file mode 100644 index 374a4dbd3..000000000 --- a/tests/treemap_union_with.rs +++ /dev/null @@ -1,91 +0,0 @@ -// extern crate roaring; -// use roaring::RoaringTreemap; - -// #[test] -// fn array_to_array() { -// let mut bitmap1 = (0..2000).collect::(); -// let bitmap2 = (1000..3000).collect::(); -// let bitmap3 = (0..3000).collect::(); - -// bitmap1 |= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn array_to_bitmap() { -// let mut bitmap1 = (0..4000).collect::(); -// let bitmap2 = (4000..8000).collect::(); -// let bitmap3 = (0..8000).collect::(); - -// bitmap1 |= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn array_and_bitmap() { -// let mut bitmap1 = (0..2000).collect::(); -// let bitmap2 = (1000..8000).collect::(); -// let bitmap3 = (0..8000).collect::(); - -// bitmap1 |= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmap() { -// let mut bitmap1 = (0..12000).collect::(); -// let bitmap2 = (6000..18000).collect::(); -// let bitmap3 = (0..18000).collect::(); - -// bitmap1 |= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmap_and_array() { -// let mut bitmap1 = (0..12000).collect::(); -// let bitmap2 = (10000..13000).collect::(); -// let bitmap3 = (0..13000).collect::(); - -// bitmap1 |= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn arrays() { -// let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)) -// .collect::(); -// let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) -// .collect::(); -// let bitmap3 = ((0..3000) -// .chain(1_000_000..1_003_000) -// .chain(2_000_000..2_001_000) -// .chain(3_000_000..3_001_000)) -// .collect::(); - -// bitmap1 |= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } - -// #[test] -// fn bitmaps() { -// let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)) -// .collect::(); -// let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) -// .collect::(); -// let bitmap3 = ((0..9000) -// .chain(1_000_000..1_018_000) -// .chain(2_000_000..2_010_000) -// .chain(3_000_000..3_010_000)) -// .collect::(); - -// bitmap1 |= bitmap2; - -// assert_eq!(bitmap1, bitmap3); -// } From 1611ba45a8218140735bcd002ed48e5244cc1991 Mon Sep 17 00:00:00 2001 From: Sylvain Laperche Date: Sun, 3 Sep 2023 14:16:25 +0200 Subject: [PATCH 3/4] core: expose iterator types --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 4cf29d4f8..a9d88d3b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,7 +29,7 @@ pub use roaring32::Roaring32; mod roaring64; pub use roaring64::Roaring64; -pub use self::core::RoaringBitmap; +pub use self::core::{IntoIter, Iter, RoaringBitmap}; /// An error type that is returned when an iterator isn't sorted. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] From 2178b97fa69037a615be1890d4e819dc96a6ebdb Mon Sep 17 00:00:00 2001 From: Sylvain Laperche Date: Sun, 3 Sep 2023 21:52:03 +0200 Subject: [PATCH 4/4] maybe better like that? --- src/lib.rs | 6 +++--- src/roaring32.rs | 4 ++++ src/roaring64.rs | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a9d88d3b5..5a1597dea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,12 +24,12 @@ mod value; pub use value::{ContainerKey, Value, ValueRange}; mod roaring32; -pub use roaring32::Roaring32; +pub use roaring32::{IntoIter32, Iter32, Roaring32}; mod roaring64; -pub use roaring64::Roaring64; +pub use roaring64::{IntoIter64, Iter64, Roaring64}; -pub use self::core::{IntoIter, Iter, RoaringBitmap}; +pub use self::core::RoaringBitmap; /// An error type that is returned when an iterator isn't sorted. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/src/roaring32.rs b/src/roaring32.rs index 7133380ae..1fe931bd8 100644 --- a/src/roaring32.rs +++ b/src/roaring32.rs @@ -22,6 +22,10 @@ use std::{ /// println!("total bits set to true: {}", rb.len()); /// ``` pub type Roaring32 = RoaringBitmap; +/// An iterator for `Roaring32`. +pub type Iter32<'a> = crate::core::Iter<'a, u32>; +/// An iterator for `Roaring32`. +pub type IntoIter32 = crate::core::IntoIter; impl Value for u32 { type Key = u16; diff --git a/src/roaring64.rs b/src/roaring64.rs index d8782847a..87782b812 100644 --- a/src/roaring64.rs +++ b/src/roaring64.rs @@ -22,6 +22,10 @@ use std::{ /// println!("total bits set to true: {}", rb.len()); /// ``` pub type Roaring64 = RoaringBitmap; +/// An iterator for `Roaring64. +pub type Iter64<'a> = crate::core::Iter<'a, u64>; +/// An iterator for `Roaring64`. +pub type IntoIter64 = crate::core::IntoIter; impl Value for u64 { type Key = u64;