Skip to content

Commit 0936c8d

Browse files
Fuse the iterator in k_smallest_general
1 parent 76be907 commit 0936c8d

File tree

1 file changed

+11
-14
lines changed

1 file changed

+11
-14
lines changed

src/k_smallest.rs

+11-14
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use alloc::vec::Vec;
22
use core::cmp::Ordering;
33

44
/// Consumes a given iterator, returning the minimum elements in **ascending** order.
5-
pub(crate) fn k_smallest_general<I, F>(mut iter: I, k: usize, mut comparator: F) -> Vec<I::Item>
5+
pub(crate) fn k_smallest_general<I, F>(iter: I, k: usize, mut comparator: F) -> Vec<I::Item>
66
where
77
I: Iterator,
88
F: FnMut(&I::Item, &I::Item) -> Ordering,
@@ -44,6 +44,7 @@ where
4444
if k == 0 {
4545
return Vec::new();
4646
}
47+
let mut iter = iter.fuse();
4748
let mut storage: Vec<I::Item> = iter.by_ref().take(k).collect();
4849

4950
let mut is_less_than = move |a: &_, b: &_| comparator(a, b) == Ordering::Less;
@@ -55,19 +56,15 @@ where
5556
sift_down(&mut storage, &mut is_less_than, i);
5657
}
5758

58-
if k == storage.len() {
59-
// If we fill the storage, there may still be iterator elements left so feed them into the heap.
60-
// Also avoids unexpected behaviour with restartable iterators.
61-
iter.for_each(|val| {
62-
if is_less_than(&val, &storage[0]) {
63-
// Treating this as an push-and-pop saves having to write a sift-up implementation.
64-
// https://en.wikipedia.org/wiki/Binary_heap#Insert_then_extract
65-
storage[0] = val;
66-
// We retain the smallest items we've seen so far, but ordered largest first so we can drop the largest efficiently.
67-
sift_down(&mut storage, &mut is_less_than, 0);
68-
}
69-
});
70-
}
59+
iter.for_each(|val| {
60+
if is_less_than(&val, &storage[0]) {
61+
// Treating this as an push-and-pop saves having to write a sift-up implementation.
62+
// https://en.wikipedia.org/wiki/Binary_heap#Insert_then_extract
63+
storage[0] = val;
64+
// We retain the smallest items we've seen so far, but ordered largest first so we can drop the largest efficiently.
65+
sift_down(&mut storage, &mut is_less_than, 0);
66+
}
67+
});
7168

7269
// Ultimately the items need to be in least-first, strict order, but the heap is currently largest-first.
7370
// To achieve this, repeatedly,

0 commit comments

Comments
 (0)