use alloc::collections::BinaryHeap;
use core::cmp::Reverse;
pub trait BinaryHeapExtensions<T> {
fn into_sorted_iter(self) -> BinaryHeapIntoSortedIter<T>;
}
pub struct BinaryHeapIntoSortedIter<T> {
binary_heap: BinaryHeap<T>,
}
impl<T: Ord> Iterator for BinaryHeapIntoSortedIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.binary_heap.pop()
}
}
impl<T> BinaryHeapExtensions<T> for BinaryHeap<T> {
fn into_sorted_iter(self) -> BinaryHeapIntoSortedIter<T> {
BinaryHeapIntoSortedIter { binary_heap: self }
}
}
#[derive(Default, Clone)]
pub struct TopK<T: Ord, const K: usize> {
heap: BinaryHeap<Reverse<T>>,
}
impl<T: Ord, const K: usize> TopK<T, K> {
pub fn new() -> Self {
Self { heap: BinaryHeap::new() }
}
pub fn push(&mut self, item: T) {
if self.heap.len() < K {
self.heap.push(Reverse(item));
} else if let Some(Reverse(min)) = self.heap.peek()
&& item > *min
{
self.heap.pop();
self.heap.push(Reverse(item));
}
}
pub fn into_sorted_iter_ascending(self) -> impl Iterator<Item = T> {
self.heap.into_sorted_iter().map(|Reverse(x)| x)
}
}