use std::collections::VecDeque;
use std::time::Instant;
pub struct EitherQueue<L, R> {
left: VecDeque<(Instant, L)>,
right: VecDeque<(Instant, R)>
}
pub enum Either<L, R> {
Left(L),
Right(R)
}
impl<L, R> EitherQueue<L, R> {
#[inline(always)]
pub fn new() -> Self {
Self::default()
}
#[inline(always)]
pub fn len(&self) -> usize {
self.left.len() + self.right.len()
}
#[inline(always)]
pub fn left_len(&self) -> usize {
self.left.len()
}
#[inline(always)]
pub fn right_len(&self) -> usize {
self.right.len()
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.left.is_empty() && self.right.is_empty()
}
#[inline(always)]
pub fn is_left_empty(&self) -> bool {
self.left.is_empty()
}
#[inline(always)]
pub fn is_right_empty(&self) -> bool {
self.right.is_empty()
}
#[inline(always)]
pub fn clear(&mut self) {
self.left.clear();
self.right.clear();
}
#[inline(always)]
pub fn push(&mut self, n: Either<L, R>) {
match n {
Either::Left(n) => self.push_left(n),
Either::Right(n) => self.push_right(n)
}
}
#[inline(always)]
pub fn push_left(&mut self, n: L) {
self.left.push_back((Instant::now(), n));
}
#[inline(always)]
pub fn push_right(&mut self, n: R) {
self.right.push_back((Instant::now(), n));
}
pub fn pop(&mut self) -> Option<Either<L, R>> {
if self.left.is_empty() {
if let Some((_, n)) = self.right.pop_front() {
Some(Either::Right(n))
} else {
None
}
} else if self.right.is_empty() {
if let Some((_, n)) = self.left.pop_front() {
Some(Either::Left(n))
} else {
unreachable!("Could not get node that is known to exist");
}
} else {
let next_left = {
let (li, _) = self
.left
.front()
.expect("Unable to get reference to expected front left node");
let (ri, _) = self
.right
.front()
.expect("Unable to get reference to expected front right node");
li <= ri
};
if next_left {
let (_, n) = self
.left
.pop_front()
.expect("Unexpectededly unable to get next left node");
Some(Either::Left(n))
} else {
let (_, n) = self
.right
.pop_front()
.expect("Unexpectededly unable to get next put node");
Some(Either::Right(n))
}
}
}
#[inline(always)]
pub fn pop_left(&mut self) -> Option<L> {
if let Some((_, n)) = self.left.pop_front() {
Some(n)
} else {
None
}
}
#[inline(always)]
pub fn pop_right(&mut self) -> Option<R> {
if let Some((_, n)) = self.right.pop_front() {
Some(n)
} else {
None
}
}
}
impl<L, R> Default for EitherQueue<L, R> {
fn default() -> Self {
Self {
left: VecDeque::new(),
right: VecDeque::new()
}
}
}