Skip to content

Commit fbf7262

Browse files
Philippe-Choletjswrenn
authored andcommitted
Make MergeBy an alias of InternalMergeJoinBy
Being now an alias, we can remove various implementations. `FusedIterator` will be inserted back soon. We don't need `MergePredicate<T>` anymore because we use two new implementations of `OrderingOrBool<T, T>`.
1 parent 485a6b5 commit fbf7262

File tree

1 file changed

+49
-99
lines changed

1 file changed

+49
-99
lines changed

src/merge_join.rs

Lines changed: 49 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::cmp::Ordering;
22
use std::fmt;
33
use std::iter::Fuse;
4-
use std::iter::{FusedIterator, Peekable};
54
use std::marker::PhantomData;
65

76
use either::Either;
@@ -12,19 +11,9 @@ use crate::size_hint::{self, SizeHint};
1211
#[cfg(doc)]
1312
use crate::Itertools;
1413

15-
pub trait MergePredicate<T> {
16-
fn merge_pred(&mut self, a: &T, b: &T) -> bool;
17-
}
18-
1914
#[derive(Clone, Debug)]
2015
pub struct MergeLte;
2116

22-
impl<T: PartialOrd> MergePredicate<T> for MergeLte {
23-
fn merge_pred(&mut self, a: &T, b: &T) -> bool {
24-
a <= b
25-
}
26-
}
27-
2817
/// An iterator adaptor that merges the two base iterators in ascending order.
2918
/// If both base iterators are sorted (ascending), the result is sorted.
3019
///
@@ -62,104 +51,21 @@ where
6251
/// Iterator element type is `I::Item`.
6352
///
6453
/// See [`.merge_by()`](crate::Itertools::merge_by) for more information.
65-
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
66-
pub struct MergeBy<I, J, F>
67-
where
68-
I: Iterator,
69-
J: Iterator<Item = I::Item>,
70-
{
71-
a: Peekable<I>,
72-
b: Peekable<J>,
73-
fused: Option<bool>,
74-
cmp: F,
75-
}
76-
77-
impl<I, J, F> fmt::Debug for MergeBy<I, J, F>
78-
where
79-
I: Iterator + fmt::Debug,
80-
J: Iterator<Item = I::Item> + fmt::Debug,
81-
I::Item: fmt::Debug,
82-
{
83-
debug_fmt_fields!(MergeBy, a, b);
84-
}
85-
86-
impl<T, F: FnMut(&T, &T) -> bool> MergePredicate<T> for F {
87-
fn merge_pred(&mut self, a: &T, b: &T) -> bool {
88-
self(a, b)
89-
}
90-
}
54+
pub type MergeBy<I, J, F> = InternalMergeJoinBy<I, J, F>;
9155

9256
/// Create a `MergeBy` iterator.
9357
pub fn merge_by_new<I, J, F>(a: I, b: J, cmp: F) -> MergeBy<I::IntoIter, J::IntoIter, F>
9458
where
9559
I: IntoIterator,
9660
J: IntoIterator<Item = I::Item>,
97-
F: MergePredicate<I::Item>,
9861
{
99-
MergeBy {
100-
a: a.into_iter().peekable(),
101-
b: b.into_iter().peekable(),
102-
fused: None,
103-
cmp,
104-
}
105-
}
106-
107-
impl<I, J, F> Clone for MergeBy<I, J, F>
108-
where
109-
I: Iterator,
110-
J: Iterator<Item = I::Item>,
111-
Peekable<I>: Clone,
112-
Peekable<J>: Clone,
113-
F: Clone,
114-
{
115-
clone_fields!(a, b, fused, cmp);
116-
}
117-
118-
impl<I, J, F> Iterator for MergeBy<I, J, F>
119-
where
120-
I: Iterator,
121-
J: Iterator<Item = I::Item>,
122-
F: MergePredicate<I::Item>,
123-
{
124-
type Item = I::Item;
125-
126-
fn next(&mut self) -> Option<Self::Item> {
127-
let less_than = match self.fused {
128-
Some(lt) => lt,
129-
None => match (self.a.peek(), self.b.peek()) {
130-
(Some(a), Some(b)) => self.cmp.merge_pred(a, b),
131-
(Some(_), None) => {
132-
self.fused = Some(true);
133-
true
134-
}
135-
(None, Some(_)) => {
136-
self.fused = Some(false);
137-
false
138-
}
139-
(None, None) => return None,
140-
},
141-
};
142-
if less_than {
143-
self.a.next()
144-
} else {
145-
self.b.next()
146-
}
147-
}
148-
149-
fn size_hint(&self) -> (usize, Option<usize>) {
150-
// Not ExactSizeIterator because size may be larger than usize
151-
size_hint::add(self.a.size_hint(), self.b.size_hint())
62+
InternalMergeJoinBy {
63+
left: put_back(a.into_iter().fuse()),
64+
right: put_back(b.into_iter().fuse()),
65+
cmp_fn: cmp,
15266
}
15367
}
15468

155-
impl<I, J, F> FusedIterator for MergeBy<I, J, F>
156-
where
157-
I: FusedIterator,
158-
J: FusedIterator<Item = I::Item>,
159-
F: MergePredicate<I::Item>,
160-
{
161-
}
162-
16369
/// Return an iterator adaptor that merge-joins items from the two base iterators in ascending order.
16470
///
16571
/// [`IntoIterator`] enabled version of [`Itertools::merge_join_by`].
@@ -269,6 +175,50 @@ impl<L, R, F: FnMut(&L, &R) -> bool> OrderingOrBool<L, R> for MergeFuncLR<F, boo
269175
}
270176
}
271177

178+
impl<T, F: FnMut(&T, &T) -> bool> OrderingOrBool<T, T> for F {
179+
type Out = bool;
180+
type MergeResult = T;
181+
fn left(left: T) -> Self::MergeResult {
182+
left
183+
}
184+
fn right(right: T) -> Self::MergeResult {
185+
right
186+
}
187+
fn merge(&mut self, left: T, right: T) -> (Option<T>, Option<T>, Self::MergeResult) {
188+
if self(&left, &right) {
189+
(None, Some(right), left)
190+
} else {
191+
(Some(left), None, right)
192+
}
193+
}
194+
fn size_hint(left: SizeHint, right: SizeHint) -> SizeHint {
195+
// Not ExactSizeIterator because size may be larger than usize
196+
size_hint::add(left, right)
197+
}
198+
}
199+
200+
impl<T: PartialOrd> OrderingOrBool<T, T> for MergeLte {
201+
type Out = bool;
202+
type MergeResult = T;
203+
fn left(left: T) -> Self::MergeResult {
204+
left
205+
}
206+
fn right(right: T) -> Self::MergeResult {
207+
right
208+
}
209+
fn merge(&mut self, left: T, right: T) -> (Option<T>, Option<T>, Self::MergeResult) {
210+
if left <= right {
211+
(None, Some(right), left)
212+
} else {
213+
(Some(left), None, right)
214+
}
215+
}
216+
fn size_hint(left: SizeHint, right: SizeHint) -> SizeHint {
217+
// Not ExactSizeIterator because size may be larger than usize
218+
size_hint::add(left, right)
219+
}
220+
}
221+
272222
impl<I, J, F> Clone for InternalMergeJoinBy<I, J, F>
273223
where
274224
I: Iterator,

0 commit comments

Comments
 (0)