use std::iter::{Peekable,};
use std::cmp::Ordering;
use super::EitherOrBoth::{self, Right, Left, Both};
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct MergeJoinInner<L, R, F>
where L: Iterator,
R: Iterator,
{
left: Peekable<L>,
right: Peekable<R>,
cmp: F,
}
impl<L, R, F> MergeJoinInner<L, R, F>
where L: Iterator,
R: Iterator,
{
pub fn new<LI, RI>(left: LI, right: RI, cmp: F) -> Self
where L: Iterator<Item=LI::Item>,
LI: IntoIterator<IntoIter=L>,
R: Iterator<Item=RI::Item>,
RI: IntoIterator<IntoIter=R>,
F: FnMut(&L::Item, &R::Item) -> Ordering
{
MergeJoinInner {
left: left.into_iter().peekable(),
right: right.into_iter().peekable(),
cmp: cmp,
}
}
}
impl<L, R, F> Iterator for MergeJoinInner<L, R, F>
where L: Iterator,
R: Iterator,
F: FnMut(&L::Item, &R::Item) -> Ordering
{
type Item = (L::Item, R::Item);
fn next(&mut self) -> Option<Self::Item> {
loop {
let ord = match (self.left.peek(), self.right.peek()) {
(Some(l), Some(r)) => (self.cmp)(l, r),
_ => return None,
};
match ord {
Ordering::Less => {self.left.next();},
Ordering::Greater =>{self.right.next();},
Ordering::Equal => match (self.left.next(), self.right.next()) {
(Some(l), Some(r)) => return Some((l, r)),
_ => return None,
}
}
}
}
}
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct MergeJoinLeftExcl<L, R, F> where
L: Iterator,
R: Iterator,
{
left: Peekable<L>,
right: Peekable<R>,
cmp: F,
fused: Option<Ordering>,
}
impl<L, R, F> MergeJoinLeftExcl<L, R, F> where
L: Iterator,
R: Iterator,
{
pub fn new<LI, RI>(left: LI, right: RI, cmp: F) -> Self
where L: Iterator<Item=LI::Item>,
LI: IntoIterator<IntoIter=L>,
R: Iterator<Item=RI::Item>,
RI: IntoIterator<IntoIter=R>,
F: FnMut(&L::Item, &R::Item) -> Ordering
{
MergeJoinLeftExcl {
left: left.into_iter().peekable(),
right: right.into_iter().peekable(),
cmp: cmp,
fused: None,
}
}
}
impl<L, R, F> Iterator for MergeJoinLeftExcl<L, R, F>
where L: Iterator,
R: Iterator,
F: FnMut(&L::Item, &R::Item) -> Ordering
{
type Item = L::Item;
fn next(&mut self) -> Option<Self::Item> {
loop {
let ord = match self.fused {
Some(o) => o,
None => match (self.left.peek(), self.right.peek()) {
(Some(l), Some(r)) => (self.cmp)(l, r),
(Some(_), None) => {
self.fused = Some(Ordering::Less);
Ordering::Less
}
_ => return None,
}
};
match ord {
Ordering::Less => return self.left.next(),
Ordering::Greater => {self.right.next();},
Ordering::Equal => {
self.left.next();
self.right.next();
}
}
}
}
}
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct MergeJoinLeftOuter<L, R, F> where
L: Iterator,
R: Iterator,
{
left: Peekable<L>,
right: Peekable<R>,
cmp: F,
fused: Option<Ordering>,
}
impl<L, R, F> MergeJoinLeftOuter<L, R, F> where
L: Iterator,
R: Iterator,
{
pub fn new<LI, RI>(left: LI, right: RI, cmp: F) -> Self
where L: Iterator<Item=LI::Item>,
LI: IntoIterator<IntoIter=L>,
R: Iterator<Item=RI::Item>,
RI: IntoIterator<IntoIter=R>,
F: FnMut(&L::Item, &R::Item) -> Ordering
{
MergeJoinLeftOuter {
left: left.into_iter().peekable(),
right: right.into_iter().peekable(),
cmp: cmp,
fused: None,
}
}
}
impl<L, R, F> Iterator for MergeJoinLeftOuter<L, R, F>
where L: Iterator,
R: Iterator,
F: FnMut(&L::Item, &R::Item) -> Ordering
{
type Item = EitherOrBoth<L::Item, R::Item>;
fn next(&mut self) -> Option<Self::Item> {
loop {
let ord = match self.fused {
Some(o) => o,
None => match (self.left.peek(), self.right.peek()) {
(Some(l), Some(r)) => (self.cmp)(l, r),
(Some(_), None) => {
self.fused = Some(Ordering::Less);
Ordering::Less
}
_ => return None,
}
};
match ord {
Ordering::Less => match self.left.next() {
Some(l) => return Some(Left(l)),
None => return None,
},
Ordering::Greater => {self.right.next();},
Ordering::Equal => match (self.left.next(), self.right.next()) {
(Some(l), Some(r)) => return Some(Both(l, r)),
_ => return None,
}
}
}
}
}
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct MergeJoinFullOuter<L, R, F> where
L: Iterator,
R: Iterator,
{
left: Peekable<L>,
right: Peekable<R>,
cmp: F,
fused: Option<Ordering>,
}
impl<L, R, F> MergeJoinFullOuter<L, R, F> where
L: Iterator,
R: Iterator,
{
pub fn new<LI, RI>(left: LI, right: RI, cmp: F) -> Self
where L: Iterator<Item=LI::Item>,
LI: IntoIterator<IntoIter=L>,
R: Iterator<Item=RI::Item>,
RI: IntoIterator<IntoIter=R>,
F: FnMut(&L::Item, &R::Item) -> Ordering
{
MergeJoinFullOuter {
left: left.into_iter().peekable(),
right: right.into_iter().peekable(),
cmp: cmp,
fused: None,
}
}
}
impl<L, R, F> Iterator for MergeJoinFullOuter<L, R, F>
where L: Iterator,
R: Iterator,
F: FnMut(&L::Item, &R::Item) -> Ordering
{
type Item = EitherOrBoth<L::Item, R::Item>;
fn next(&mut self) -> Option<Self::Item> {
loop {
let ord = match self.fused {
Some(o) => o,
None => match (self.left.peek(), self.right.peek()) {
(Some(l), Some(r)) => (self.cmp)(l, r),
(Some(_), None) => {
self.fused = Some(Ordering::Less);
Ordering::Less
}
(None, Some(_)) => {
self.fused = Some(Ordering::Greater);
Ordering::Greater
}
_ => return None,
}
};
match ord {
Ordering::Less => match self.left.next() {
Some(l) => return Some(Left(l)),
None => return None,
},
Ordering::Greater => match self.right.next() {
Some(r) => return Some(Right(r)),
None => return None,
},
Ordering::Equal => match (self.left.next(), self.right.next()) {
(Some(l), Some(r)) => return Some(Both(l, r)),
_ => return None,
}
}
}
}
}