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 45badbceb..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_insert_with(RoaringBitmap::new).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_insert_with(RoaringBitmap::new).insert_range(start_lo..=end_lo) - } else if hi == start_hi { - entry.or_insert_with(RoaringBitmap::new).insert_range(start_lo..=u32::MAX) - } else if hi == end_hi { - entry.or_insert_with(RoaringBitmap::new).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_insert_with(RoaringBitmap::new).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); -// }