use std::fmt::Debug;
use crate::index::{IndexType, NodeIndex};
use crate::interval::Interval;
use crate::intervalmap::IntervalMap;
use crate::node::Node;
fn left_link<T, V, Ix>(map_ref: &IntervalMap<T, V, Ix>, mut x: NodeIndex<Ix>) -> Vec<NodeIndex<Ix>>
where
T: Ord,
Ix: IndexType,
{
let mut nodes = vec![];
while !map_ref.node_ref(x, Node::is_sentinel) {
nodes.push(x);
x = map_ref.node_ref(x, Node::left);
}
nodes
}
#[derive(Debug)]
pub struct Iter<'a, T, V, Ix>
where
T: Ord,
{
pub(crate) map_ref: &'a IntervalMap<T, V, Ix>,
pub(crate) stack: Vec<NodeIndex<Ix>>,
}
impl<'a, T, V, Ix> Iter<'a, T, V, Ix>
where
T: Ord,
Ix: IndexType,
{
pub fn new(map_ref: &'a IntervalMap<T, V, Ix>) -> Self {
Iter {
map_ref,
stack: left_link(map_ref, map_ref.root),
}
}
}
impl<'a, T, V, Ix> Iterator for Iter<'a, T, V, Ix>
where
T: Ord,
Ix: IndexType,
{
type Item = (&'a Interval<T>, &'a V);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.stack.is_empty() {
return None;
}
let x = self.stack.pop()?;
self.stack.extend(left_link(
self.map_ref,
self.map_ref.node_ref(x, Node::right),
));
Some(self.map_ref.node_ref(x, |xn| (xn.interval(), xn.value())))
}
}
#[derive(Debug)]
pub struct IntoIter<T, V, Ix>
where
T: Ord,
{
interval_map: IntervalMap<T, V, Ix>,
pub(crate) stack: Vec<NodeIndex<Ix>>,
}
impl<T, V, Ix> IntoIter<T, V, Ix>
where
T: Ord,
Ix: IndexType,
{
pub fn new(interval_map: IntervalMap<T, V, Ix>) -> Self {
let mut temp = IntoIter {
interval_map,
stack: vec![],
};
temp.stack = left_link(&temp.interval_map, temp.interval_map.root);
temp
}
}
impl<T, V, Ix> Iterator for IntoIter<T, V, Ix>
where
T: Ord,
Ix: IndexType,
{
type Item = (Interval<T>, V);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.stack.is_empty() {
return None;
}
let x = self.stack.pop()?;
self.stack.extend(left_link(
&self.interval_map,
self.interval_map.node_ref(x, Node::right),
));
let res = &mut self.interval_map.nodes[x.index()];
Some((res.interval.take().unwrap(), res.value.take().unwrap()))
}
}
#[derive(Debug)]
pub struct UnsortedIter<'a, T, V, Ix>
where
T: Ord,
{
map_ref: &'a IntervalMap<T, V, Ix>,
pub(crate) cur: NodeIndex<Ix>,
}
impl<'a, T, V, Ix> UnsortedIter<'a, T, V, Ix>
where
T: Ord,
Ix: IndexType,
{
pub fn new(map_ref: &'a IntervalMap<T, V, Ix>) -> Self {
UnsortedIter {
map_ref,
cur: NodeIndex::SENTINEL,
}
}
}
impl<'a, T, V, Ix> Iterator for UnsortedIter<'a, T, V, Ix>
where
T: Ord,
Ix: IndexType,
{
type Item = (&'a Interval<T>, &'a V);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.map_ref.is_empty()
|| self.cur.index() >= self.map_ref.len()
|| self.cur.index() == <Ix as IndexType>::max().index()
{
return None;
}
self.cur = self.cur.inc();
Some(
self.map_ref
.node_ref(self.cur, |xn| (xn.interval(), xn.value())),
)
}
}
#[derive(Debug)]
pub struct FilterIter<'a, T, V, Ix>
where
T: Ord,
{
pub(crate) map_ref: &'a IntervalMap<T, V, Ix>,
pub(crate) stack: Vec<NodeIndex<Ix>>,
pub(crate) query: &'a Interval<T>,
}
fn left_link_with_query<T, V, Ix>(
map_ref: &IntervalMap<T, V, Ix>,
mut x: NodeIndex<Ix>,
query: &Interval<T>,
) -> Vec<NodeIndex<Ix>>
where
T: Ord,
Ix: IndexType,
{
let mut stack: Vec<NodeIndex<Ix>> = vec![];
if map_ref.max(x).is_some_and(|v| v <= &query.low) {
return stack;
}
while map_ref.node_ref(x, Node::sentinel).is_some() {
if map_ref.node_ref(x, Node::interval).low < query.high {
stack.push(x);
}
if map_ref.max(map_ref.node_ref(x, Node::left)) <= Some(&query.low) {
break;
}
x = map_ref.node_ref(x, Node::left);
}
stack
}
impl<'a, T, V, Ix> FilterIter<'a, T, V, Ix>
where
T: Ord,
Ix: IndexType,
{
pub fn new(map_ref: &'a IntervalMap<T, V, Ix>, query: &'a Interval<T>) -> Self {
FilterIter {
map_ref,
stack: left_link_with_query(map_ref, map_ref.root, query),
query,
}
}
}
impl<'a, T, V, Ix> Iterator for FilterIter<'a, T, V, Ix>
where
T: Ord,
Ix: IndexType,
{
type Item = (&'a Interval<T>, &'a V);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.stack.is_empty() {
return None;
}
let mut x = self.stack.pop()?;
while !self
.map_ref
.node_ref(x, Node::interval)
.overlaps(self.query)
{
self.stack.extend(left_link_with_query(
self.map_ref,
self.map_ref.node_ref(x, Node::right),
self.query,
));
if self.stack.is_empty() {
return None;
}
x = self.stack.pop()?;
}
self.stack.extend(left_link_with_query(
self.map_ref,
self.map_ref.node_ref(x, Node::right),
self.query,
));
Some(self.map_ref.node_ref(x, |xn| (xn.interval(), xn.value())))
}
}