use std::cmp::Reverse;
use std::collections::BinaryHeap;
pub struct MergeIterator<T: Ord, I: Iterator<Item = T>> {
streams: Vec<I>,
heap: BinaryHeap<Reverse<(T, usize)>>,
}
impl<T: Ord, I: Iterator<Item = T>> MergeIterator<T, I> {
pub fn new<S: IntoIterator<Item = I>>(streams: S) -> Self {
let mut streams: Vec<I> = streams.into_iter().collect();
let mut heap = BinaryHeap::with_capacity(streams.len());
for (i, s) in streams.iter_mut().enumerate() {
if let Some(v) = s.next() {
heap.push(Reverse((v, i)));
}
}
Self { streams, heap }
}
}
impl<T: Ord, I: Iterator<Item = T>> Iterator for MergeIterator<T, I> {
type Item = T;
fn next(&mut self) -> Option<T> {
let Reverse((value, idx)) = self.heap.pop()?;
if let Some(next_value) = self.streams[idx].next() {
self.heap.push(Reverse((next_value, idx)));
}
Some(value)
}
}
#[cfg(feature = "harness")]
pub mod recipe;