optimize superset
method of IntervalSet
This commit is contained in:
parent
50b00252ae
commit
8db6d4bae2
1 changed files with 21 additions and 4 deletions
|
@ -1,7 +1,7 @@
|
||||||
use std::iter::Step;
|
use std::iter::Step;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::Bound;
|
|
||||||
use std::ops::RangeBounds;
|
use std::ops::RangeBounds;
|
||||||
|
use std::ops::{Bound, Range};
|
||||||
|
|
||||||
use crate::vec::Idx;
|
use crate::vec::Idx;
|
||||||
use crate::vec::IndexVec;
|
use crate::vec::IndexVec;
|
||||||
|
@ -145,9 +145,26 @@ impl<I: Idx> IntervalSet<I> {
|
||||||
where
|
where
|
||||||
I: Step,
|
I: Step,
|
||||||
{
|
{
|
||||||
// FIXME: Performance here is probably not great. We will be doing a lot
|
let mut sup_iter = self.iter_intervals();
|
||||||
// of pointless tree traversals.
|
let mut current = None;
|
||||||
other.iter().all(|elem| self.contains(elem))
|
let contains = |sup: Range<I>, sub: Range<I>, current: &mut Option<Range<I>>| {
|
||||||
|
if sup.end < sub.start {
|
||||||
|
// if `sup.end == sub.start`, the next sup doesn't contain `sub.start`
|
||||||
|
None // continue to the next sup
|
||||||
|
} else if sup.end >= sub.end && sup.start <= sub.start {
|
||||||
|
*current = Some(sup); // save the current sup
|
||||||
|
Some(true)
|
||||||
|
} else {
|
||||||
|
Some(false)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
other.iter_intervals().all(|sub| {
|
||||||
|
current
|
||||||
|
.take()
|
||||||
|
.and_then(|sup| contains(sup, sub.clone(), &mut current))
|
||||||
|
.or_else(|| sup_iter.find_map(|sup| contains(sup, sub.clone(), &mut current)))
|
||||||
|
.unwrap_or(false)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue