use crate::ValueHeap;
const DEFAULT_HEAP_CAPACITY: usize = 16;
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
struct Entry<V> {
key: i32,
value: V,
}
impl<V> From<(i32, V)> for Entry<V> {
fn from((key, value): (i32, V)) -> Self {
Self { key, value }
}
}
impl<V> From<Entry<V>> for (i32, V) {
fn from(entry: Entry<V>) -> Self {
(entry.key, entry.value)
}
}
pub struct Iter<'a, V> {
inner: std::slice::Iter<'a, Entry<V>>,
}
impl<'a, V> Iterator for Iter<'a, V> {
type Item = (&'a i32, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|entry| (&entry.key, &entry.value))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BinaryArrayIntegerValueHeap<V> {
entries: Vec<Entry<V>>,
}
impl<V> BinaryArrayIntegerValueHeap<V> {
#[must_use]
pub fn new() -> Self {
Self::with_capacity(DEFAULT_HEAP_CAPACITY)
}
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
entries: Vec::with_capacity(capacity),
}
}
#[must_use]
pub fn from_vec(entries: Vec<(i32, V)>) -> Self {
let mut heap = Self {
entries: entries.into_iter().map(Entry::from).collect(),
};
heap.heapify();
heap
}
pub fn insert(&mut self, key: i32, value: V) {
self.entries.push(Entry { key, value });
self.sift_up(self.entries.len() - 1);
}
#[must_use]
pub fn peek(&self) -> Option<(&i32, &V)> {
self.entries.first().map(|entry| (&entry.key, &entry.value))
}
#[must_use]
pub fn peek_key(&self) -> Option<&i32> {
self.entries.first().map(|entry| &entry.key)
}
#[must_use]
pub fn peek_value(&self) -> Option<&V> {
self.entries.first().map(|entry| &entry.value)
}
pub fn pop(&mut self) -> Option<(i32, V)> {
if self.entries.is_empty() {
return None;
}
let entry = self.entries.swap_remove(0);
if !self.entries.is_empty() {
self.sift_down(0);
}
Some(entry.into())
}
#[must_use]
pub fn len(&self) -> usize {
self.entries.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
pub fn clear(&mut self) {
self.entries.clear();
}
#[must_use]
pub fn into_vec(self) -> Vec<(i32, V)> {
self.entries.into_iter().map(Entry::into).collect()
}
pub fn iter(&self) -> Iter<'_, V> {
Iter {
inner: self.entries.iter(),
}
}
fn heapify(&mut self) {
for index in (0..self.entries.len() / 2).rev() {
self.sift_down(index);
}
}
fn sift_up(&mut self, mut index: usize) {
while index > 0 {
let parent = (index - 1) / 2;
if self.entries[parent].key <= self.entries[index].key {
break;
}
self.entries.swap(parent, index);
index = parent;
}
}
fn sift_down(&mut self, mut index: usize) {
loop {
let left = index * 2 + 1;
if left >= self.entries.len() {
return;
}
let right = left + 1;
let child =
if right < self.entries.len() && self.entries[right].key < self.entries[left].key {
right
} else {
left
};
if self.entries[index].key <= self.entries[child].key {
return;
}
self.entries.swap(index, child);
index = child;
}
}
}
impl<V> Default for BinaryArrayIntegerValueHeap<V> {
fn default() -> Self {
Self::new()
}
}
impl<V> FromIterator<(i32, V)> for BinaryArrayIntegerValueHeap<V> {
fn from_iter<I: IntoIterator<Item = (i32, V)>>(iter: I) -> Self {
Self::from_vec(iter.into_iter().collect())
}
}
impl<V> Extend<(i32, V)> for BinaryArrayIntegerValueHeap<V> {
fn extend<I: IntoIterator<Item = (i32, V)>>(&mut self, iter: I) {
for (key, value) in iter {
self.insert(key, value);
}
}
}
impl<V> IntoIterator for BinaryArrayIntegerValueHeap<V> {
type Item = (i32, V);
type IntoIter = std::vec::IntoIter<(i32, V)>;
fn into_iter(self) -> Self::IntoIter {
self.into_vec().into_iter()
}
}
impl<'a, V> IntoIterator for &'a BinaryArrayIntegerValueHeap<V> {
type Item = (&'a i32, &'a V);
type IntoIter = Iter<'a, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<V> ValueHeap<i32, V> for BinaryArrayIntegerValueHeap<V> {
fn insert(&mut self, key: i32, value: V) {
Self::insert(self, key, value);
}
fn peek(&self) -> Option<(&i32, &V)> {
Self::peek(self)
}
fn pop(&mut self) -> Option<(i32, V)> {
Self::pop(self)
}
fn len(&self) -> usize {
Self::len(self)
}
fn clear(&mut self) {
Self::clear(self);
}
}