Skip to content

Commit

Permalink
Fully replace MergePredicate by OrderingOrBool
Browse files Browse the repository at this point in the history
  • Loading branch information
Philippe-Cholet committed Jun 12, 2023
1 parent 072fe00 commit d1535e9
Showing 1 changed file with 15 additions and 40 deletions.
55 changes: 15 additions & 40 deletions src/merge_join.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@ use crate::size_hint::{self, SizeHint};
#[cfg(doc)]
use crate::Itertools;

pub trait MergePredicate<I, J> {
type Item;
fn left(left: I) -> Self::Item;
fn right(right: J) -> Self::Item;
fn merge(&mut self, left: I, right: J) -> (Option<I>, Option<J>, Self::Item);
fn size_hint(left: SizeHint, right: SizeHint) -> SizeHint;
}

/// Return an iterator adaptor that merge-joins items from the two base iterators in ascending order.
///
/// [`IntoIterator`] enabled version of [`Itertools::merge_join_by`].
Expand Down Expand Up @@ -100,24 +92,6 @@ impl<I, J> OrderingOrBool<I, J> for bool {
}
}

impl<I, J, OoB: OrderingOrBool<I, J>, F: FnMut(&I, &J) -> OoB> MergePredicate<I, J> for F {
type Item = OoB::MergeResult;
fn left(left: I) -> Self::Item {
OoB::left(left)
}
fn right(right: J) -> Self::Item {
OoB::right(right)
}
fn merge(&mut self, left: I, right: J) -> (Option<I>, Option<J>, Self::Item) {
let cmp_result = self(&left, &right);
OoB::merge(cmp_result, left, right)
}
fn size_hint(left: SizeHint, right: SizeHint) -> SizeHint {
OoB::size_hint(left, right)
}

}

impl<I, J, F> Clone for MergeJoinBy<I, J, F>
where I: Iterator,
J: Iterator,
Expand All @@ -137,20 +111,21 @@ impl<I, J, F> fmt::Debug for MergeJoinBy<I, J, F>
debug_fmt_fields!(MergeJoinBy, left, right);
}

impl<I, J, F> Iterator for MergeJoinBy<I, J, F>
impl<I, J, F, T> Iterator for MergeJoinBy<I, J, F>
where I: Iterator,
J: Iterator,
F: MergePredicate<I::Item, J::Item>,
F: FnMut(&I::Item, &J::Item) -> T,
T: OrderingOrBool<I::Item, J::Item>,
{
type Item = F::Item;
type Item = T::MergeResult;

fn next(&mut self) -> Option<Self::Item> {
match (self.left.next(), self.right.next()) {
(None, None) => None,
(Some(left), None) => Some(F::left(left)),
(None, Some(right)) => Some(F::right(right)),
(Some(left), None) => Some(T::left(left)),
(None, Some(right)) => Some(T::right(right)),
(Some(left), Some(right)) => {
let (left, right, next) = self.cmp_fn.merge(left, right);
let (left, right, next) = (self.cmp_fn)(&left, &right).merge(left, right);
if let Some(left) = left {
self.left.put_back(left);
}
Expand All @@ -163,7 +138,7 @@ impl<I, J, F> Iterator for MergeJoinBy<I, J, F>
}

fn size_hint(&self) -> SizeHint {
F::size_hint(self.left.size_hint(), self.right.size_hint())
T::size_hint(self.left.size_hint(), self.right.size_hint())
}

fn count(mut self) -> usize {
Expand All @@ -175,7 +150,7 @@ impl<I, J, F> Iterator for MergeJoinBy<I, J, F>
(None, Some(_right)) => break count + 1 + self.right.into_parts().1.count(),
(Some(left), Some(right)) => {
count += 1;
let (left, right, _) = self.cmp_fn.merge(left, right);
let (left, right, _) = (self.cmp_fn)(&left, &right).merge(left, right);
if let Some(left) = left {
self.left.put_back(left);
}
Expand All @@ -193,17 +168,17 @@ impl<I, J, F> Iterator for MergeJoinBy<I, J, F>
match (self.left.next(), self.right.next()) {
(None, None) => break previous_element,
(Some(left), None) => {
break Some(F::left(
break Some(T::left(
self.left.into_parts().1.last().unwrap_or(left),
))
}
(None, Some(right)) => {
break Some(F::right(
break Some(T::right(
self.right.into_parts().1.last().unwrap_or(right),
))
}
(Some(left), Some(right)) => {
let (left, right, elem) = self.cmp_fn.merge(left, right);
let (left, right, elem) = (self.cmp_fn)(&left, &right).merge(left, right);
previous_element = Some(elem);
if let Some(left) = left {
self.left.put_back(left);
Expand All @@ -224,10 +199,10 @@ impl<I, J, F> Iterator for MergeJoinBy<I, J, F>
n -= 1;
match (self.left.next(), self.right.next()) {
(None, None) => break None,
(Some(_left), None) => break self.left.nth(n).map(F::left),
(None, Some(_right)) => break self.right.nth(n).map(F::right),
(Some(_left), None) => break self.left.nth(n).map(T::left),
(None, Some(_right)) => break self.right.nth(n).map(T::right),
(Some(left), Some(right)) => {
let (left, right, _) = self.cmp_fn.merge(left, right);
let (left, right, _) = (self.cmp_fn)(&left, &right).merge(left, right);
if let Some(left) = left {
self.left.put_back(left);
}
Expand Down

0 comments on commit d1535e9

Please sign in to comment.