#![cfg_attr(feature = "no_std_support", no_std)]
extern crate alloc;
use crate::usizemap::UsizeMap;
#[cfg(feature="no_std_support")]
use alloc::vec::Vec;
#[cfg(not(feature="no_std_support"))]
use std::vec::Vec;
use core::fmt::{self, Debug};
#[derive(Debug)]
struct Blob<T> {
data: T,
count: usize,
}
pub struct Heap<T> {
data: UsizeMap<Blob<T>>,
}
impl<T: Debug> Debug for Heap<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Heap")
.field("data", &self.data)
.finish()
}
}
impl<T> Heap<T> {
#[inline]
pub fn new() -> Heap<T> {
Heap {
data: UsizeMap::new(),
}
}
pub fn push(&mut self, data: T) -> usize {
let blob = Blob {
data,
count: 1,
};
self.data.insert(blob)
}
pub fn get(&mut self, index: usize) -> &mut T {
&mut self.data.get_mut(index).expect("Heap::get: Invalid index").data
}
pub fn try_get(&mut self, index: usize) -> Option<&mut T> {
self.data.get_mut(index).map(|blob| &mut blob.data)
}
pub fn contains_key(&self, index: usize) -> bool {
self.data.contains_key(index)
}
pub fn count(&mut self, index: usize) -> usize {
self.data.get_mut(index).map(|b| b.count).unwrap_or(0)
}
pub fn incr(&mut self, index: usize) {
if let Some(blob) = self.data.get_mut(index) {
blob.count += 1;
} else {
panic!("Heap::incr: Invalid index {}", index);
}
}
pub fn decr(&mut self, index: usize) {
let should_remove = if let Some(blob) = self.data.get_mut(index) {
if blob.count > 1 {
blob.count -= 1;
false
} else {
true
}
} else {
panic!("Heap::decr: Invalid index {}", index);
};
if should_remove {
self.data.remove(index);
}
}
pub fn free(&mut self, index: usize) -> Option<T> {
self.data.remove(index).map(|b| b.data)
}
pub fn keys(&self) -> Vec<usize> {
self.data.keys()
}
pub fn clear(&mut self) {
self.data.clear();
}
pub fn shrink_to_fit(&mut self) {
self.data.shrink_to_fit();
}
}
impl<T> Default for Heap<T> {
fn default() -> Self {
Self::new()
}
}