Skip to content

Commit 6555872

Browse files
committed
fix: when advancing a run iter, check if we've reached the other size of the only interval if present
1 parent 61a2788 commit 6555872

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

roaring/src/bitmap/store/interval_store.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,18 @@ impl<I: SliceIterator<Interval>> RunIter<I> {
712712
if let Some(value) = index.checked_sub(1) {
713713
self.intervals.nth(value);
714714
}
715-
self.forward_offset = n - self.intervals.as_slice().first().unwrap().start;
715+
let first_interval = self.intervals.as_slice().first().unwrap();
716+
self.forward_offset = n - first_interval.start;
717+
if self.intervals.as_slice().len() == 1
718+
&& u64::from(self.forward_offset) + u64::from(self.backward_offset)
719+
>= first_interval.run_len()
720+
{
721+
// If we are now the only interval, and we've now met the forward offset,
722+
// consume the final interval
723+
_ = self.intervals.next();
724+
self.forward_offset = 0;
725+
self.backward_offset = 0;
726+
}
716727
}
717728
Err(index) => {
718729
if index == self.intervals.as_slice().len() {
@@ -749,7 +760,18 @@ impl<I: SliceIterator<Interval>> RunIter<I> {
749760
if let Some(value) = backward_index.checked_sub(1) {
750761
self.intervals.nth_back(value);
751762
}
752-
self.backward_offset = self.intervals.as_slice().last().unwrap().end - n;
763+
let last_interval = self.intervals.as_slice().last().unwrap();
764+
self.backward_offset = last_interval.end - n;
765+
if self.intervals.as_slice().len() == 1
766+
&& u64::from(self.forward_offset) + u64::from(self.backward_offset)
767+
>= last_interval.run_len()
768+
{
769+
// If we are now the only interval, and we've now met the forward offset,
770+
// consume the final interval
771+
_ = self.intervals.next_back();
772+
self.forward_offset = 0;
773+
self.backward_offset = 0;
774+
}
753775
}
754776
Err(index) => {
755777
if index == 0 {

roaring/tests/iter_advance_to.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,13 @@ fn advance_run_back_reduces_forward_iter() {
236236
assert_eq!(iter.next(), Some(1));
237237
assert_eq!(iter.next(), None);
238238
}
239+
240+
#[test]
241+
fn advance_run_front_and_back_past_each_other() {
242+
let mut bitmap = RoaringBitmap::new();
243+
bitmap.insert_range(0..=0x4000);
244+
let mut iter = bitmap.iter();
245+
iter.advance_back_to(100);
246+
iter.advance_to(300);
247+
assert_eq!(iter.next(), None);
248+
}

0 commit comments

Comments
 (0)