Skip to content

Commit

Permalink
Introduce the NonSortedIntegers error struct
Browse files Browse the repository at this point in the history
  • Loading branch information
Kerollmops committed Oct 21, 2021
1 parent f358f59 commit df89194
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 38 deletions.
2 changes: 1 addition & 1 deletion benchmarks/benches/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ fn from_sorted_iter(c: &mut Criterion) {
b.iter(|| {
for (_, numbers) in &parsed_numbers {
let numbers = numbers.as_ref().unwrap();
RoaringBitmap::from_sorted_iter(numbers.iter().copied());
RoaringBitmap::from_sorted_iter(numbers.iter().copied()).unwrap();
}
})
});
Expand Down
43 changes: 24 additions & 19 deletions src/bitmap/iter.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::convert::identity;
use std::iter::{self, FromIterator};
use std::slice;
use std::vec;
use std::{slice, vec};

use super::container::Container;
use crate::RoaringBitmap;
use crate::{NonSortedIntegers, RoaringBitmap};

/// An iterator for `RoaringBitmap`.
pub struct Iter<'a> {
Expand All @@ -21,27 +21,21 @@ pub struct IntoIter {
size_hint: u64,
}

impl<'a> Iter<'a> {
impl Iter<'_> {
fn new(containers: &[Container]) -> Iter {
fn identity<T>(t: T) -> T {
t
}
let size_hint = containers.iter().map(|c| c.len).sum();
Iter { inner: containers.iter().flat_map(identity as _), size_hint }
}
}

impl IntoIter {
fn new(containers: Vec<Container>) -> IntoIter {
fn identity<T>(t: T) -> T {
t
}
let size_hint = containers.iter().map(|c| c.len).sum();
IntoIter { inner: containers.into_iter().flat_map(identity as _), size_hint }
}
}

impl<'a> Iterator for Iter<'a> {
impl Iterator for Iter<'_> {
type Item = u32;

fn next(&mut self) -> Option<u32> {
Expand Down Expand Up @@ -140,7 +134,7 @@ impl RoaringBitmap {
/// Returns `Ok` with the requested `RoaringBitmap`, `Err` with the number of elements
/// that were correctly appended before failure.
///
/// # Examples
/// # Example: Create a set from an ordered list of integers.
///
/// ```rust
/// use roaring::RoaringBitmap;
Expand All @@ -149,14 +143,22 @@ impl RoaringBitmap {
///
/// assert!(rb.iter().eq(0..10));
/// ```
///
/// # Example: Try to create a set from a non-ordered list of integers.
///
/// ```rust
/// use roaring::RoaringBitmap;
///
/// let integers = 0..10u32;
/// let error = RoaringBitmap::from_sorted_iter(integers.rev()).unwrap_err();
///
/// assert_eq!(error.valid_until(), 1);
/// ```
pub fn from_sorted_iter<I: IntoIterator<Item = u32>>(
iterator: I,
) -> Result<RoaringBitmap, u64> {
) -> Result<RoaringBitmap, NonSortedIntegers> {
let mut rb = RoaringBitmap::new();
match rb.append(iterator) {
Ok(_) => Ok(rb),
Err(count) => Err(count),
}
rb.append(iterator).map(|_| rb)
}

/// Extend the set with a sorted iterator.
Expand All @@ -178,14 +180,17 @@ impl RoaringBitmap {
///
/// assert!(rb.iter().eq(0..10));
/// ```
pub fn append<I: IntoIterator<Item = u32>>(&mut self, iterator: I) -> Result<u64, u64> {
pub fn append<I: IntoIterator<Item = u32>>(
&mut self,
iterator: I,
) -> Result<u64, NonSortedIntegers> {
let mut count = 0;

for value in iterator {
if self.push(value) {
count += 1;
} else {
return Err(count);
return Err(NonSortedIntegers { valid_until: count });
}
}

Expand Down
24 changes: 24 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

extern crate byteorder;

use std::error::Error;
use std::fmt;

/// A compressed bitmap using the [Roaring bitmap compression scheme](http://roaringbitmap.org).
pub mod bitmap;

Expand All @@ -21,3 +24,24 @@ pub mod treemap;

pub use bitmap::RoaringBitmap;
pub use treemap::RoaringTreemap;

/// An error type that is returned when an iterator isn't sorted.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NonSortedIntegers {
valid_until: u64,
}

impl NonSortedIntegers {
/// Returns the number of elements that were
pub fn valid_until(&self) -> u64 {
self.valid_until
}
}

impl fmt::Display for NonSortedIntegers {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "integers are ordered up to the {}th element", self.valid_until())
}
}

impl Error for NonSortedIntegers {}
19 changes: 9 additions & 10 deletions src/treemap/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use std::iter::{self, FromIterator};
use super::util;
use crate::bitmap::IntoIter as IntoIter32;
use crate::bitmap::Iter as Iter32;
use crate::RoaringBitmap;
use crate::RoaringTreemap;
use crate::{NonSortedIntegers, RoaringBitmap, RoaringTreemap};

struct To64Iter<'a> {
hi: u32,
Expand Down Expand Up @@ -228,12 +227,9 @@ impl RoaringTreemap {
/// ```
pub fn from_sorted_iter<I: IntoIterator<Item = u64>>(
iterator: I,
) -> Result<RoaringTreemap, u64> {
let mut rb = RoaringTreemap::new();
match rb.append(iterator) {
Ok(_) => Ok(rb),
Err(count) => Err(count),
}
) -> Result<RoaringTreemap, NonSortedIntegers> {
let mut rt = RoaringTreemap::new();
rt.append(iterator).map(|_| rt)
}

/// Extend the set with a sorted iterator.
Expand All @@ -255,14 +251,17 @@ impl RoaringTreemap {
///
/// assert!(rb.iter().eq(0..10));
/// ```
pub fn append<I: IntoIterator<Item = u64>>(&mut self, iterator: I) -> Result<u64, u64> {
pub fn append<I: IntoIterator<Item = u64>>(
&mut self,
iterator: I,
) -> Result<u64, NonSortedIntegers> {
let mut count = 0;

for value in iterator {
if self.push(value) {
count += 1;
} else {
return Err(count);
return Err(NonSortedIntegers { valid_until: count });
}
}

Expand Down
10 changes: 2 additions & 8 deletions tests/push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,12 @@ macro_rules! test_from_sorted_iter {

#[test]
fn append() {
test_from_sorted_iter!(
(0..1_000_000).map(|x| 13 * x).collect::<Vec<u32>>(),
RoaringBitmap
);
test_from_sorted_iter!((0..1_000_000).map(|x| 13 * x).collect::<Vec<u32>>(), RoaringBitmap);
test_from_sorted_iter!(vec![1, 2, 4, 5, 7, 8, 9], RoaringBitmap);
}

#[test]
fn append_tree() {
test_from_sorted_iter!(
(0..1_000_000).map(|x| 13 * x).collect::<Vec<u64>>(),
RoaringTreemap
);
test_from_sorted_iter!((0..1_000_000).map(|x| 13 * x).collect::<Vec<u64>>(), RoaringTreemap);
test_from_sorted_iter!(vec![1, 2, 4, 5, 7, 8, 9], RoaringTreemap);
}

0 comments on commit df89194

Please sign in to comment.