Skip to content

Commit

Permalink
refactor: use breadth-first search in find all overlap in interval tree
Browse files Browse the repository at this point in the history
Signed-off-by: bsbds <[email protected]>
  • Loading branch information
bsbds committed Mar 21, 2024
1 parent 0cfa232 commit 21c8293
Showing 1 changed file with 36 additions and 1 deletion.
37 changes: 36 additions & 1 deletion crates/utils/src/interval_map/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::VecDeque;

use petgraph::graph::{DefaultIx, IndexType, NodeIndex};

#[cfg(test)]
Expand Down Expand Up @@ -79,7 +81,7 @@ where
if self.node_ref(self.root, Node::is_sentinel) {
Vec::new()
} else {
self.find_all_overlap_inner(self.root, interval)
self.find_all_overlap_inner_unordered(self.root, interval)
}
}

Expand Down Expand Up @@ -289,6 +291,7 @@ where
}

/// Finds all intervals in the map that overlaps with the given interval.
#[cfg(interval_tree_find_overlap_ordered)]
fn find_all_overlap_inner(
&self,
x: NodeIndex<Ix>,
Expand All @@ -311,6 +314,38 @@ where
list
}

/// Finds all intervals in the map that overlaps with the given interval.
///
/// The result is unordered because of breadth-first search to save stack size
fn find_all_overlap_inner_unordered(
&self,
x: NodeIndex<Ix>,
interval: &Interval<T>,
) -> Vec<(&Interval<T>, &V)> {
let mut list = Vec::new();
let mut queue = VecDeque::new();
queue.push_back(x);
while let Some(p) = queue.pop_front() {
if self.node_ref(p, Node::interval).overlap(interval) {
list.push(self.node_ref(p, |np| (np.interval(), np.value())));
}
let p_left = self.node_ref(p, Node::left);
let p_right = self.node_ref(p, Node::right);
if self.max(p_left) >= Some(&interval.low) {
queue.push_back(p_left);
}
if self
.max(self.node_ref(p, Node::right))
.map(|rmax| IntervalRef::new(&self.node_ref(p, Node::interval).low, rmax))
.is_some_and(|i| i.overlap(interval))
{
queue.push_back(p_right);
}
}

list
}

/// Search for an interval that overlaps with the given interval.
fn search(&self, interval: &Interval<T>) -> NodeIndex<Ix> {
let mut x = self.root;
Expand Down

0 comments on commit 21c8293

Please sign in to comment.