use tree::*;
use space::CoordSpace;
use bonzai::traverse_from;
use smallqueue::SmallQueue;
pub struct MTreeQueue<T, S: CoordSpace> {
space: S,
tree: MTree<SmallQueue<T>>
}
impl<T, S: CoordSpace> MTreeQueue<T, S> {
pub fn new(space: S) -> Self {
MTreeQueue {
space,
tree: MTree::new()
}
}
pub fn insert(&mut self, coord: S::Coord, elem: T) {
self.tree.upsert(self.space.raw(coord), SmallQueueUpserter {
elem
});
}
pub fn is_empty(&self) -> bool {
self.tree.is_empty()
}
pub fn remove(&mut self, focus: S::Coord) -> Option<T> {
let mut op = self.tree.operation();
if let Some(closest) = MTree::get_closest(&op, self.space.raw(focus)) {
let mut node = traverse_from!(op, closest);
let (elem, is_empty) = match &mut*node {
&mut Octant::Leaf {
elem: ref mut queue,
..
} => (queue.remove().unwrap(), queue.is_empty()),
&mut Octant::Branch { .. } => unreachable!()
};
if is_empty {
MTree::remove(node);
}
Some(elem)
} else {
None
}
}
}
struct SmallQueueUpserter<T> {
elem: T
}
impl<T> Upserter<SmallQueue<T>> for SmallQueueUpserter<T> {
fn update(self, queue: &mut SmallQueue<T>) {
queue.add(self.elem);
}
fn insert(self) -> SmallQueue<T> {
SmallQueue::of(self.elem)
}
}