joinkit

Trait Joinkit

Source
pub trait Joinkit: Iterator {
    // Provided methods
    fn merge_join_inner_by<R, F>(
        self,
        other: R,
        cmp: F,
    ) -> MergeJoinInner<Self, R::IntoIter, F> 
       where Self: Sized,
             R: IntoIterator,
             F: FnMut(&Self::Item, &R::Item) -> Ordering { ... }
    fn merge_join_left_excl_by<R, F>(
        self,
        other: R,
        cmp: F,
    ) -> MergeJoinLeftExcl<Self, R::IntoIter, F> 
       where Self: Sized,
             R: IntoIterator,
             F: FnMut(&Self::Item, &R::Item) -> Ordering { ... }
    fn merge_join_left_outer_by<R, F>(
        self,
        other: R,
        cmp: F,
    ) -> MergeJoinLeftOuter<Self, R::IntoIter, F> 
       where Self: Sized,
             R: IntoIterator,
             F: FnMut(&Self::Item, &R::Item) -> Ordering { ... }
    fn merge_join_full_outer_by<R, F>(
        self,
        other: R,
        cmp: F,
    ) -> MergeJoinFullOuter<Self, R::IntoIter, F> 
       where Self: Sized,
             R: IntoIterator,
             F: FnMut(&Self::Item, &R::Item) -> Ordering { ... }
    fn hash_join_inner<K, RI, RV>(self, other: RI) -> HashJoinInner<Self, K, RV> 
       where Self: Sized,
             K: Hash + Eq,
             RV: Clone,
             RI: IntoIterator<Item = (K, RV)> { ... }
    fn hash_join_left_excl<K, RI, RV>(
        self,
        other: RI,
    ) -> HashJoinLeftExcl<Self, K> 
       where Self: Sized,
             K: Hash + Eq,
             RI: IntoIterator<Item = (K, RV)> { ... }
    fn hash_join_left_outer<K, RI, RV>(
        self,
        other: RI,
    ) -> HashJoinLeftOuter<Self, K, RV> 
       where Self: Sized,
             K: Hash + Eq,
             RV: Clone,
             RI: IntoIterator<Item = (K, RV)> { ... }
    fn hash_join_right_excl<K, RI, RV>(
        self,
        other: RI,
    ) -> HashJoinRightExcl<Self, K, RV> 
       where Self: Sized,
             K: Hash + Eq,
             RI: IntoIterator<Item = (K, RV)> { ... }
    fn hash_join_right_outer<K, RI, RV>(
        self,
        other: RI,
    ) -> HashJoinRightOuter<Self, K, RV> 
       where Self: Sized,
             K: Hash + Eq,
             RV: Clone,
             RI: IntoIterator<Item = (K, RV)> { ... }
    fn hash_join_full_outer<K, RI, RV>(
        self,
        other: RI,
    ) -> HashJoinFullOuter<Self, K, RV> 
       where Self: Sized,
             K: Hash + Eq,
             RV: Clone,
             RI: IntoIterator<Item = (K, RV)> { ... }
}
Expand description

Trait Joinkit provides the extra iterator adaptors for efficient SQL-like joins.

Provided Methods§

Source

fn merge_join_inner_by<R, F>( self, other: R, cmp: F, ) -> MergeJoinInner<Self, R::IntoIter, F>
where Self: Sized, R: IntoIterator, F: FnMut(&Self::Item, &R::Item) -> Ordering,

Return an iterator adaptor that inner joins the two input iterators in ascending order. The resulting iterator is the intersection of the two input iterators.

The both input iterators must be sorted and unique on the join key (e.g. by grouping them, if necessary) to produce the correct results.

Iterator element type is (L::Item, R::Item).

use joinkit::Joinkit;

// tuples of (key, [value,...]), where the key is extracted from the value
// notice the values are grouped by the key
let l = vec![("0", vec!["0;A"]), ("1", vec!["1;B"])].into_iter();
let r = vec![("1", vec!["1;X", "1;Y"]), ("2", vec!["2;Z"])].into_iter();
let mut it = l.merge_join_inner_by(r, |x, y| Ord::cmp(&x.0, &y.0));

assert_eq!(it.next(), Some((("1", vec!["1;B"]), ("1", vec!["1;X", "1;Y"]))));
assert_eq!(it.next(), None);
Source

fn merge_join_left_excl_by<R, F>( self, other: R, cmp: F, ) -> MergeJoinLeftExcl<Self, R::IntoIter, F>
where Self: Sized, R: IntoIterator, F: FnMut(&Self::Item, &R::Item) -> Ordering,

Return an iterator adaptor that left exclusive joins the two input iterators in ascending order. The resulting iterator contains only those records from the left input iterator, which do not match the right input iterator. There is no direct equivalent in SQL.

The both input iterators must be sorted and unique on the join key (e.g. by grouping them, if necessary) to produce the correct results.

Iterator element type is L::Item.

use joinkit::Joinkit;

// tuples of (key, [value,...]), where the key is extracted from the value
// notice the values are grouped by the key
let l = vec![("0", vec!["0;A"]), ("1", vec!["1;B"])].into_iter();
let r = vec![("1", vec!["1;X", "1;Y"]), ("2", vec!["2;Z"])].into_iter();
let mut it = l.merge_join_left_excl_by(r, |x, y| Ord::cmp(&x.0, &y.0));

assert_eq!(it.next(), Some(("0", vec!["0;A"])));
assert_eq!(it.next(), None);
Source

fn merge_join_left_outer_by<R, F>( self, other: R, cmp: F, ) -> MergeJoinLeftOuter<Self, R::IntoIter, F>
where Self: Sized, R: IntoIterator, F: FnMut(&Self::Item, &R::Item) -> Ordering,

Return an iterator adaptor that left outer joins the two input iterators in ascending order. The resulting iterator contains all the records from the left input iterator, even if they do not match the right input iterator.

The both input iterators must be sorted and unique on the join key (e.g. by grouping them, if necessary) to produce the correct results.

Iterator element type is EitherOrBoth<L::Item, R::Item>.

use joinkit::Joinkit;
use joinkit::EitherOrBoth::{Left, Both, Right};

// tuples of (key, [value,...]), where the key is extracted from the value
// notice the values are grouped by the key
let l = vec![("0", vec!["0;A"]), ("1", vec!["1;B"])].into_iter();
let r = vec![("1", vec!["1;X", "1;Y"]), ("2", vec!["2;Z"])].into_iter();
let mut it = l.merge_join_left_outer_by(r, |x, y| Ord::cmp(&x.0, &y.0));

assert_eq!(it.next(), Some(Left(("0", vec!["0;A"]))));
assert_eq!(it.next(), Some(Both(("1", vec!["1;B"]), ("1", vec!["1;X", "1;Y"]))));
assert_eq!(it.next(), None);
Source

fn merge_join_full_outer_by<R, F>( self, other: R, cmp: F, ) -> MergeJoinFullOuter<Self, R::IntoIter, F>
where Self: Sized, R: IntoIterator, F: FnMut(&Self::Item, &R::Item) -> Ordering,

Return an iterator adaptor that full outer joins the two input iterators in ascending order. The resulting iterator contains all the records from the both input iterators.

The both input iterators must be sorted and unique on the join key (e.g. by grouping them, if necessary) to produce the correct results.

Iterator element type is EitherOrBoth<L::Item, R::Item>.

use joinkit::Joinkit;
use joinkit::EitherOrBoth::{Left, Both, Right};


// tuples of (key, [value,...]), where the key is extracted from the value
// notice the values are grouped by the key
let l = vec![("0",vec!["0;A"]), ("1", vec!["1;B"])].into_iter();
let r = vec![("1",vec!["1;X", "1;Y"]), ("2", vec!["2;Z"])].into_iter();
let mut it = l.merge_join_full_outer_by(r, |x, y| Ord::cmp(&x.0, &y.0));

assert_eq!(it.next(), Some(Left(("0", vec!["0;A"]))));
assert_eq!(it.next(), Some(Both(("1", vec!["1;B"]), ("1", vec!["1;X", "1;Y"]))));
assert_eq!(it.next(), Some(Right(("2", vec!["2;Z"]))));
assert_eq!(it.next(), None);
Source

fn hash_join_inner<K, RI, RV>(self, other: RI) -> HashJoinInner<Self, K, RV>
where Self: Sized, K: Hash + Eq, RV: Clone, RI: IntoIterator<Item = (K, RV)>,

Return an iterator adaptor that inner joins the two input iterators in ascending order. The resulting iterator is the intersection of the two input iterators.

The input iterators do not need to be sorted. The right input iterator is loaded into HashMap and grouped by the key automatically. Neither the left input iterator need to be unique on the key.

The left input iterator element type must be (K, LV), where K: Hash + Eq. The right input iterator element type must be (K, RV), where K: Hash + Eq and RV: Clone.

When the join adaptor is created, the right iterator is consumed into HashMap.

Iterator element type is (LV, vec![RV,...]). The RV is cloned from HashMap for each joined value. A single RV can be expected to be joined (and cloned) multiple times to LV. To increase performance, consider wrapping RV into std::rc::Rc pointer to avoid unnecessary allocations.

use joinkit::Joinkit;

// tuples of (key, value), where the key is extracted from the value
let l = vec![("0", "0;A"), ("1", "1;B")].into_iter();
let r = vec![("1", "1;X"), ("2", "2;Z"), ("1", "1;Y")].into_iter();
let mut it = l.hash_join_inner(r);

// notice the grouped right values
assert_eq!(it.next(), Some(("1;B", vec!["1;X", "1;Y"])));
assert_eq!(it.next(), None);
Source

fn hash_join_left_excl<K, RI, RV>(self, other: RI) -> HashJoinLeftExcl<Self, K>
where Self: Sized, K: Hash + Eq, RI: IntoIterator<Item = (K, RV)>,

Return an iterator adaptor that left exclusive joins the two input iterators. The resulting iterator contains only those records from the left input iterator, which do not match the right input iterator. There is no direct equivalent in SQL.

The input iterators do not need to be sorted. The right input iterator is loaded into HashMap and grouped by the key automatically. Neither the left input iterator need to be unique on the key.

The left input iterator element type must be (K, LV), where K: Hash + Eq. The right input iterator element type must be (K, RV), where K: Hash + Eq.

When the join adaptor is created, the right iterator is consumed into HashMap.

Iterator element type is LV.

use joinkit::Joinkit;

// tuples of (key, value), where the key is extracted from the value
let l = vec![("0", "0;A"), ("1", "1;B")].into_iter();
let r = vec![("1", "1;X"), ("2", "2;Z"), ("1", "1;Y")].into_iter();
let mut it = l.hash_join_left_excl(r);

assert_eq!(it.next(), Some("0;A"));
assert_eq!(it.next(), None);
Source

fn hash_join_left_outer<K, RI, RV>( self, other: RI, ) -> HashJoinLeftOuter<Self, K, RV>
where Self: Sized, K: Hash + Eq, RV: Clone, RI: IntoIterator<Item = (K, RV)>,

Return an iterator adaptor that left outer joins the two input iterators. The resulting iterator contains all the records from the left input iterator, even if they do not match the right input iterator.

The input iterators do not need to be sorted. The right input iterator is loaded into HashMap and grouped by the key automatically. Neither the left input iterator need to be unique on the key.

The left input iterator element type must be (K, LV), where K: Hash + Eq. The right input iterator element type must be (K, RV), where K: Hash + Eq and RV: Clone.

When the join adaptor is created, the right iterator is consumed into HashMap.

Iterator element type is EitherOrBoth<LV, RV>. The RV is cloned from HashMap for each joined value. It is expected a single RV will be joined (and cloned) multiple times to LV. To increase performance, consider wrapping RV into std::rc::Rc pointer to avoid unnecessary allocations.

use joinkit::Joinkit;
use joinkit::EitherOrBoth::{Left, Both, Right};

// tuples of (key, value), where the key is extracted from the value
let l = vec![("0", "0;A"), ("1", "1;B")].into_iter();
let r = vec![("1", "1;X"), ("2", "2;Z"), ("1", "1;Y")].into_iter();
let mut it = l.hash_join_left_outer(r);

// notice the grouped right values
assert_eq!(it.next(), Some(Left("0;A")));
assert_eq!(it.next(), Some(Both("1;B", vec!["1;X", "1;Y"])));
assert_eq!(it.next(), None);
Source

fn hash_join_right_excl<K, RI, RV>( self, other: RI, ) -> HashJoinRightExcl<Self, K, RV>
where Self: Sized, K: Hash + Eq, RI: IntoIterator<Item = (K, RV)>,

Return an iterator adaptor that right exclusive joins the two input iterators. The resulting iterator contains only those records from the right input iterator, which do not match the left input iterator. There is no direct equivalent in SQL.

The input iterators do not need to be sorted. The right input iterator is loaded into HashMap and grouped by the key automatically. Neither the left input iterator need to be unique on the key.

The left input iterator element type must be (K, LV), where K: Hash + Eq. The right input iterator element type must be (K, RV), where K: Hash + Eq.

When the join adaptor is created, the right iterator is consumed into HashMap.

Iterator element type is vec![RV,...].

use joinkit::Joinkit;

// tuples of (key, value), where the key is extracted from the value
let l = vec![("0", "0;A"), ("1", "1;B")].into_iter();
let r = vec![("1", "1;X"), ("2", "2;Z"), ("1", "1;Y")].into_iter();
let mut it = l.hash_join_right_excl(r);

assert_eq!(it.next(), Some(vec!["2;Z"]));
assert_eq!(it.next(), None);
Source

fn hash_join_right_outer<K, RI, RV>( self, other: RI, ) -> HashJoinRightOuter<Self, K, RV>
where Self: Sized, K: Hash + Eq, RV: Clone, RI: IntoIterator<Item = (K, RV)>,

Return an iterator adaptor that right outer joins the two input iterators. The resulting iterator contains all the records from the right input iterator, even if they do not match the left input iterator.

The input iterators do not need to be sorted. The right input iterator is loaded into HashMap and grouped by the key automatically. Neither the left input iterator need to be unique on the key.

The left input iterator element type must be (K, LV), where K: Hash + Eq. The right input iterator element type must be (K, RV), where K: Hash + Eq and RV: Clone.

When the join adaptor is created, the right iterator is consumed into HashMap.

Iterator element type is EitherOrBoth<LV, RV>. The RV is cloned from HashMap for each joined value. It is expected a single RV will be joined (and cloned) multiple times to LV. To increase performance, consider wrapping RV into std::rc::Rc pointer to avoid unnecessary allocations.

use joinkit::Joinkit;
use joinkit::EitherOrBoth::{Left, Both, Right};

// tuples of (key, value), where the key is extracted from the value
let l = vec![("0", "0;A"), ("1", "1;B")].into_iter();
let r = vec![("1", "1;X"), ("2", "2;Z"), ("1", "1;Y")].into_iter();
let mut it = l.hash_join_right_outer(r);

// notice the grouped right values
assert_eq!(it.next(), Some(Both("1;B", vec!["1;X", "1;Y"])));
assert_eq!(it.next(), Some(Right(vec!["2;Z"])));
assert_eq!(it.next(), None);
Source

fn hash_join_full_outer<K, RI, RV>( self, other: RI, ) -> HashJoinFullOuter<Self, K, RV>
where Self: Sized, K: Hash + Eq, RV: Clone, RI: IntoIterator<Item = (K, RV)>,

Return an iterator adaptor that full outer joins the two input iterators. The resulting iterator contains all the records from the both input iterators.

The input iterators do not need to be sorted. The right input iterator is loaded into HashMap and grouped by the key automatically. Neither the left input iterator need to be unique on the key.

The left input iterator element type must be (K, LV), where K: Hash + Eq. The right input iterator element type must be (K, RV), where K: Hash + Eq and RV: Clone.

When the join adaptor is created, the right iterator is consumed into HashMap.

Iterator element type is EitherOrBoth<LV, RV>. The RV is cloned from HashMap for each joined value. It is expected a single RV will be joined (and cloned) multiple times to LV. To increase performance, consider wrapping RV into std::rc::Rc pointer to avoid unnecessary allocations.

use joinkit::Joinkit;
use joinkit::EitherOrBoth::{Left, Both, Right};

// tuples of (key, value), where the key is extracted from the value
let l = vec![("0", "0;A"), ("1", "1;B")].into_iter();
let r = vec![("1", "1;X"), ("2", "2;Z"), ("1", "1;Y")].into_iter();
let mut it = l.hash_join_full_outer(r);

// notice the grouped right values
assert_eq!(it.next(), Some(Left("0;A")));
assert_eq!(it.next(), Some(Both("1;B", vec!["1;X", "1;Y"])));
assert_eq!(it.next(), Some(Right(vec!["2;Z"])));
assert_eq!(it.next(), None);

Implementors§

Source§

impl<T> Joinkit for T
where T: Iterator + ?Sized,