Skip to content

Commit 8db6d4b

Browse files
committed
optimize superset method of IntervalSet
1 parent 50b0025 commit 8db6d4b

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

compiler/rustc_index/src/interval.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::iter::Step;
22
use std::marker::PhantomData;
3-
use std::ops::Bound;
43
use std::ops::RangeBounds;
4+
use std::ops::{Bound, Range};
55

66
use crate::vec::Idx;
77
use crate::vec::IndexVec;
@@ -145,9 +145,26 @@ impl<I: Idx> IntervalSet<I> {
145145
where
146146
I: Step,
147147
{
148-
// FIXME: Performance here is probably not great. We will be doing a lot
149-
// of pointless tree traversals.
150-
other.iter().all(|elem| self.contains(elem))
148+
let mut sup_iter = self.iter_intervals();
149+
let mut current = None;
150+
let contains = |sup: Range<I>, sub: Range<I>, current: &mut Option<Range<I>>| {
151+
if sup.end < sub.start {
152+
// if `sup.end == sub.start`, the next sup doesn't contain `sub.start`
153+
None // continue to the next sup
154+
} else if sup.end >= sub.end && sup.start <= sub.start {
155+
*current = Some(sup); // save the current sup
156+
Some(true)
157+
} else {
158+
Some(false)
159+
}
160+
};
161+
other.iter_intervals().all(|sub| {
162+
current
163+
.take()
164+
.and_then(|sup| contains(sup, sub.clone(), &mut current))
165+
.or_else(|| sup_iter.find_map(|sup| contains(sup, sub.clone(), &mut current)))
166+
.unwrap_or(false)
167+
})
151168
}
152169

153170
pub fn is_empty(&self) -> bool {

0 commit comments

Comments
 (0)