use std::collections::hash_map::{HashMap, IntoIter,};
use std::collections::hash_set::{HashSet,};
use std::mem;
use std::hash::Hash;
use super::EitherOrBoth::{self, Right, Left, Both};
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct HashJoinInner<L, K, RV> {
left: L,
map: HashMap<K, Vec<RV>>,
}
impl<L, K, RV> HashJoinInner<L, K, RV>
where K: Hash + Eq,
{
pub fn new<LI, RI>(left: LI, right: RI) -> Self
where L: Iterator<Item=LI::Item>,
LI: IntoIterator<IntoIter=L>,
RI: IntoIterator<Item=(K, RV)>
{
let mut map: HashMap<K, Vec<RV>> = HashMap::new();
for (k, v) in right.into_iter() {
let values = map.entry(k).or_insert(Vec::with_capacity(1));
values.push(v);
}
HashJoinInner {
left: left.into_iter(),
map: map,
}
}
}
impl<L, K, LV, RV> Iterator for HashJoinInner<L, K, RV>
where L: Iterator<Item=(K, LV)>,
K: Hash + Eq,
RV: Clone,
{
type Item = (LV, Vec<RV>);
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.left.next() {
Some((lk, lv)) => match self.map.get(&lk) {
Some(rvv) => return Some((lv, rvv.clone())),
None => continue,
},
None => return None,
}
}
}
}
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct HashJoinLeftExcl<L, K> {
left: L,
set: HashSet<K>,
}
impl<L, K> HashJoinLeftExcl<L, K>
where K: Hash + Eq,
{
pub fn new<LI, RI, RV>(left: LI, right: RI) -> Self
where L: Iterator<Item=LI::Item>,
LI: IntoIterator<IntoIter=L>,
RI: IntoIterator<Item=(K, RV)>
{
let mut set: HashSet<K> = HashSet::new();
for (k, _) in right.into_iter() {
set.insert(k);
}
HashJoinLeftExcl {
left: left.into_iter(),
set: set,
}
}
}
impl<L, K, LV> Iterator for HashJoinLeftExcl<L, K>
where L: Iterator<Item=(K, LV)>,
K: Hash + Eq,
{
type Item = LV;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.left.next() {
Some((lk, lv)) => {
if self.set.contains(&lk) {
continue;
} else {
return Some(lv);
}
},
None => return None,
}
}
}
}
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct HashJoinLeftOuter<L, K, RV> {
left: L,
map: HashMap<K, Vec<RV>>,
}
impl<L, K, RV> HashJoinLeftOuter<L, K, RV>
where K: Hash + Eq,
{
pub fn new<LI, RI>(left: LI, right: RI) -> Self
where L: Iterator<Item=LI::Item>,
LI: IntoIterator<IntoIter=L>,
RI: IntoIterator<Item=(K, RV)>
{
let mut map: HashMap<K, Vec<RV>> = HashMap::new();
for (k, v) in right.into_iter() {
let values = map.entry(k).or_insert(Vec::with_capacity(1));
values.push(v);
}
HashJoinLeftOuter {
left: left.into_iter(),
map: map,
}
}
}
impl<L, K, LV, RV> Iterator for HashJoinLeftOuter<L, K, RV>
where L: Iterator<Item=(K, LV)>,
K: Hash + Eq,
RV: Clone,
{
type Item = EitherOrBoth<LV, Vec<RV>>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.left.next() {
Some((lk, lv)) => match self.map.get(&lk) {
Some(rvv) => return Some(Both(lv, rvv.clone())),
None => return Some(Left(lv)),
},
None => return None,
}
}
}
}
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct HashJoinRightExcl<L, K, RV> {
left: L,
map: HashMap<K, (Vec<RV>, bool)>,
excl_iter: Option<IntoIter<K, (Vec<RV>, bool)>>,
}
impl<L, K, RV> HashJoinRightExcl<L, K, RV>
where K: Hash + Eq,
{
pub fn new<LI, RI>(left: LI, right: RI) -> Self
where L: Iterator<Item=LI::Item>,
LI: IntoIterator<IntoIter=L>,
RI: IntoIterator<Item=(K, RV)>
{
let mut map: HashMap<K, (Vec<RV>, bool)> = HashMap::new();
for (k, v) in right.into_iter() {
let values = map.entry(k).or_insert((Vec::with_capacity(1), false));
values.0.push(v);
}
HashJoinRightExcl {
left: left.into_iter(),
map: map,
excl_iter: None,
}
}
fn set_excl_iter(&mut self) {
let map = mem::replace(&mut self.map, HashMap::<K, (Vec<RV>, bool)>::new());
self.excl_iter = Some(map.into_iter());
}
}
impl<L, K, LV, RV> Iterator for HashJoinRightExcl<L, K, RV>
where L: Iterator<Item=(K, LV)>,
K: Hash + Eq,
{
type Item = Vec<RV>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.excl_iter {
None => match self.left.next() {
Some((lk, _)) => match self.map.get_mut(&lk) {
Some(rt) => {
rt.1 = true; },
None => continue, },
None => self.set_excl_iter(),
},
Some(ref mut r) => match r.next() {
Some((_, (rvv, matched))) => {
if !matched {
return Some(rvv);
} else {
continue;
}
},
None => return None,
}
}
}
}
}
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct HashJoinRightOuter<L, K, RV> {
left: L,
map: HashMap<K, (Vec<RV>, bool)>,
excl_iter: Option<IntoIter<K, (Vec<RV>, bool)>>,
}
impl<L, K, RV> HashJoinRightOuter<L, K, RV>
where K: Hash + Eq,
{
pub fn new<LI, RI>(left: LI, right: RI) -> Self
where L: Iterator<Item=LI::Item>,
LI: IntoIterator<IntoIter=L>,
RI: IntoIterator<Item=(K, RV)>
{
let mut map: HashMap<K, (Vec<RV>, bool)> = HashMap::new();
for (k, v) in right.into_iter() {
let values = map.entry(k).or_insert((Vec::with_capacity(1), false));
values.0.push(v);
}
HashJoinRightOuter {
left: left.into_iter(),
map: map,
excl_iter: None,
}
}
fn set_excl_iter(&mut self) {
let map = mem::replace(&mut self.map, HashMap::<K, (Vec<RV>, bool)>::new());
self.excl_iter = Some(map.into_iter());
}
}
impl<L, K, LV, RV> Iterator for HashJoinRightOuter<L, K, RV>
where L: Iterator<Item=(K, LV)>,
K: Hash + Eq,
RV: Clone,
{
type Item = EitherOrBoth<LV, Vec<RV>>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.excl_iter {
None => match self.left.next() {
Some((lk, lv)) => match self.map.get_mut(&lk) {
Some(rt) => {
rt.1 = true; return Some(Both(lv, rt.0.clone()))
},
None => continue, },
None => self.set_excl_iter(),
},
Some(ref mut r) => match r.next() {
Some((_, (rvv, matched))) => {
if !matched {
return Some(Right(rvv));
} else {
continue;
}
},
None => return None,
}
}
}
}
}
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct HashJoinFullOuter<L, K, RV> {
left: L,
map: HashMap<K, (Vec<RV>, bool)>,
excl_iter: Option<IntoIter<K, (Vec<RV>, bool)>>,
}
impl<L, K, RV> HashJoinFullOuter<L, K, RV>
where K: Hash + Eq,
{
pub fn new<LI, RI>(left: LI, right: RI) -> Self
where L: Iterator<Item=LI::Item>,
LI: IntoIterator<IntoIter=L>,
RI: IntoIterator<Item=(K, RV)>
{
let mut map: HashMap<K, (Vec<RV>, bool)> = HashMap::new();
for (k, v) in right.into_iter() {
let values = map.entry(k).or_insert((Vec::with_capacity(1), false));
values.0.push(v);
}
HashJoinFullOuter {
left: left.into_iter(),
map: map,
excl_iter: None,
}
}
fn set_excl_iter(&mut self) {
let map = mem::replace(&mut self.map, HashMap::<K, (Vec<RV>, bool)>::new());
self.excl_iter = Some(map.into_iter());
}
}
impl<L, K, LV, RV> Iterator for HashJoinFullOuter<L, K, RV>
where L: Iterator<Item=(K, LV)>,
K: Hash + Eq,
RV: Clone,
{
type Item = EitherOrBoth<LV, Vec<RV>>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.excl_iter {
None => match self.left.next() {
Some((lk, lv)) => match self.map.get_mut(&lk) {
Some(rt) => {
rt.1 = true; return Some(Both(lv, rt.0.clone()))
},
None => return Some(Left(lv)),
},
None => self.set_excl_iter(),
},
Some(ref mut r) => match r.next() {
Some((_, (rvv, matched))) => {
if !matched {
return Some(Right(rvv));
} else {
continue;
}
},
None => return None,
}
}
}
}
}