#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![allow(unused_parens)]
#![allow(unused_mut)]
#![allow(unused_assignments)]
#![allow(unused_doc_comments)]
#![allow(unused_imports)]
use std::cell::{Ref, RefCell, RefMut};
use std::cmp::Ord;
use std::collections::hash_map::RandomState;
use std::collections::{HashMap, HashSet};
use std::hash::{BuildHasher, Hash, Hasher};
pub mod consthashheap;
pub use consthashheap::*;
const DEFAULTCAP: usize = 16;
fn left(i: usize) -> usize {
2 * i + 1
}
fn right(i: usize) -> usize {
2 * i + 2
}
fn parent(i: usize) -> usize {
if i > 0 {
(i - 1) / 2
} else {
0
}
}
fn derive_hash<T: Hash + Eq>(rs: &RandomState, key: &T) -> usize {
let mut bs = rs.build_hasher();
key.hash(&mut bs);
bs.finish() as usize
}
#[derive(Clone, Debug)]
pub struct HashHeap<KT, VT> {
keys: Vec<Option<KT>>, vals: Vec<(VT, usize)>, userhash: Option<fn(&KT) -> usize>,
rehash: fn(usize, usize) -> usize, kmap: HashMap<usize, (usize, usize)>, lessthan: fn(&VT, &VT) -> bool,
autostate: RandomState,
minmax: bool, }
impl<KT: Hash + Eq, VT: PartialOrd> HashHeap<KT, VT> {
pub fn with_capacity(mut cap: usize, maxheap: bool) -> HashHeap<KT, VT> {
if cap < 1 {
cap = DEFAULTCAP;
}
let mut hh = HashHeap {
keys: Vec::with_capacity(cap),
vals: Vec::with_capacity(cap),
kmap: HashMap::with_capacity(cap),
userhash: None,
rehash: |h, c| h + c,
lessthan: |a, b| a < b,
autostate: RandomState::new(),
minmax: maxheap,
};
if !maxheap {
hh.lessthan = |a, b| b < a;
}
hh
}
pub fn new_minheap() -> HashHeap<KT, VT> {
Self::with_capacity(0, false)
}
pub fn new_maxheap() -> HashHeap<KT, VT> {
Self::with_capacity(0, true)
}
pub fn from_pairs(kvpairs: Vec<(KT, VT)>, maxheap: bool) -> HashHeap<KT, VT> {
let mut hh = Self::with_capacity(kvpairs.len() + 1, maxheap);
hh.heapify(kvpairs);
hh
}
pub fn set_hash(&mut self, h: fn(&KT) -> usize) -> bool {
if self.keys.len() > 0 {
return false;
}
self.userhash = Some(h);
true
}
pub fn set_rehash(&mut self, rh: fn(usize, usize) -> usize) -> bool {
if self.keys.len() > 0 {
return false;
}
self.rehash = rh;
true
}
pub fn set_cmp(&mut self, cmp: fn(&VT, &VT) -> bool) -> bool {
if self.keys.len() > 1 {
false
} else {
self.lessthan = cmp;
true
}
}
fn autohash(&self, key: &KT) -> usize {
self.userhash
.map_or(derive_hash(&self.autostate, key),
|f| { f(key) }
)
}
fn findslot(&self, key: &KT) -> (usize, bool) {
let mut h = self.autohash(key);
let h0 = h;
let mut collisions = 0;
let mut reuse = None;
while let Some((ki, vi)) = self.kmap.get(&h) {
match &self.keys[*ki] {
Some(key2) if key2 == key => {
return (h, true);
}
None => {
if let None = reuse {
reuse = Some(h);
}
collisions += 1;
h = (self.rehash)(h0, collisions);
}
Some(_) => {
collisions += 1;
h = (self.rehash)(h0, collisions);
}
} } reuse.map_or((h, false), |g| (g, false))
}
pub fn insert(&mut self, key: KT, val: VT) -> Option<(KT, VT)> {
let (h, exists) = self.findslot(&key);
if exists {
let (ki, vi) = *self.kmap.get(&h).unwrap();
let mut newkey = Some(key);
let mut newval = (val, h);
core::mem::swap(&mut newkey, &mut self.keys[ki]);
core::mem::swap(&mut newval, &mut self.vals[vi]);
self.reposition(vi);
Some((newkey.unwrap(), newval.0))
}
else {
let kn = self.keys.len();
let vn = self.vals.len();
self.keys.push(Some(key));
self.vals.push((val, h));
self.kmap.insert(h, (kn, vn));
self.swapup(vn);
None
} }
pub fn push(&mut self, key: KT, val: VT) -> bool {
let (h, exists) = self.findslot(&key);
if exists {
false
} else {
let kn = self.keys.len();
let vn = self.vals.len();
self.keys.push(Some(key));
self.vals.push((val, h));
self.kmap.insert(h, (kn, vn));
self.swapup(vn);
true
} }
pub fn top_swap(&mut self, key: KT, val: VT) -> Option<(KT, VT)> {
if self.vals.len() == 0 {
self.push(key, val);
return None;
}
let (h, exists) = self.findslot(&key);
if exists {
let (ki, vi) = *self.kmap.get(&h).unwrap();
self.keys[ki] = Some(key);
self.vals[vi] = (val, h);
self.reposition(vi);
return self.pop();
}
let (_, it) = &self.vals[0];
let (tki, tvi) = *self.kmap.get(it).unwrap();
assert!(tvi == 0);
let mut newkey = Some(key);
let mut newval = (val, h);
core::mem::swap(&mut newkey, &mut self.keys[tki]);
core::mem::swap(&mut newval, &mut self.vals[0]);
self.kmap.insert(h, (tki, 0));
self.swapdown(0);
Some((newkey.unwrap(), newval.0))
}
pub fn peek(&self) -> Option<(&KT, &VT)> {
if self.vals.len() == 0 {
return None;
}
let (v, hv) = &self.vals[0];
let k = self.kmap.get(hv).unwrap().0;
Some((self.keys[k].as_ref().unwrap(), v))
}
pub fn pop(&mut self) -> Option<(KT, VT)> {
let vn = self.vals.len();
if vn == 0 {
return None;
}
self.heapswap(0, vn - 1);
let mut Kopt = None;
let (V, iv) = self.vals.pop().unwrap();
let (ki, vi) = *self.kmap.get(&iv).unwrap();
core::mem::swap(&mut self.keys[ki], &mut Kopt);
self.swapdown(0);
Some((Kopt.unwrap(), V))
}
pub fn get(&self, key: &KT) -> Option<&VT> {
if let (h, true) = self.findslot(key) {
let (_, vi) = self.kmap[&h];
Some(&self.vals[vi].0)
} else {
None
}
}
pub fn modify<F>(&mut self, key: &KT, mapfun: F) -> bool
where
F: FnOnce(&mut VT),
{
if let (h, true) = self.findslot(key) {
let (_, vi) = self.kmap[&h];
mapfun(&mut self.vals[vi].0);
self.reposition(vi);
true
} else {
false
}
}
pub fn remove(&mut self, key: &KT) -> Option<(KT, VT)> {
if let (h, true) = self.findslot(key) {
let (ki, vi) = self.kmap[&h];
self.heapswap(vi, self.vals.len() - 1);
let (V, _) = self.vals.pop().unwrap();
self.reposition(vi);
let mut K = None;
core::mem::swap(&mut K, &mut self.keys[ki]);
Some((K.unwrap(), V))
} else {
None
}
}
pub fn contains_key(&self, key: &KT) -> bool {
self.findslot(key).1
}
pub fn contains_val(&self, val: &VT) -> bool {
self.valsearch(0, val)
}
fn valsearch(&self, root: usize, val: &VT) -> bool {
if root >= self.vals.len() {
false
} else if &self.vals[root].0 == val {
true
} else if (self.lessthan)(&self.vals[root].0, val) {
false
} else {
self.valsearch(left(root), val) || self.valsearch(right(root), val)
}
}
fn swapup(&mut self, mut i: usize) -> usize {
if i >= self.vals.len() {
return i;
}
let mut p = parent(i);
while i > 0 && (self.lessthan)(&self.vals[p].0, &self.vals[i].0) {
self.heapswap(i, p);
i = p;
p = parent(i);
} i
}
fn swapdown(&mut self, mut i: usize) -> usize {
let size = self.vals.len();
let nonleaves = size - ((size + 1) / 2);
let mut sc = 0;
while (i < nonleaves && sc != usize::MAX) {
sc = usize::MAX;
let li = left(i);
let ri = right(i);
if li < size && (self.lessthan)(&self.vals[i].0, &self.vals[li].0) {
sc = li;
}
if ri < size
&& (self.lessthan)(&self.vals[i].0, &self.vals[ri].0)
&& (self.lessthan)(&self.vals[li].0, &self.vals[ri].0)
{
sc = ri;
}
if (sc != usize::MAX) {
self.heapswap(i, sc);
i = sc;
}
} i
}
fn reposition(&mut self, i: usize) -> usize {
let mut ni = self.swapup(i);
if ni == i {
ni = self.swapdown(i);
}
ni
}
fn heapswap(&mut self, i: usize, j: usize) {
if i == j {
return;
}
let ih = self.vals[i].1; let jh = self.vals[j].1;
self.vals.swap(i, j);
self.kmap.get_mut(&ih).map(|(_, vi)| {
*vi = j;
});
self.kmap.get_mut(&jh).map(|(_, vj)| {
*vj = i;
});
}
fn heapify(&mut self, vkv: Vec<(KT, VT)>) {
if self.keys.len() > 0 {
self.keys.clear();
self.vals.clear();
self.kmap.clear();
}
let vn = vkv.len();
let nonleafs = vn - (vn + 1) / 2;
let mut vi = 0;
for (k, v) in vkv {
let (kh, _) = self.findslot(&k);
self.keys.push(Some(k));
self.vals.push((v, kh));
self.kmap.insert(kh, (vi, vi));
vi += 1;
} vi = nonleafs;
while vi > 0 {
self.swapdown(vi - 1);
vi -= 1;
} }
pub fn len(&self) -> usize {
self.vals.len()
}
pub fn reserve(&mut self, additional: usize) {
self.kmap.reserve(additional);
self.vals.reserve(additional);
self.keys.reserve(additional);
}
pub fn clear(&mut self) {
self.vals.clear();
self.keys.clear();
self.kmap.clear();
self.autostate = RandomState::new();
}
pub fn is_max_hashheap(&self) -> bool {
self.minmax
}
}
impl<KT: Hash + Eq, VT: PartialOrd> Default for HashHeap<KT, VT> {
fn default() -> Self {
Self::new_maxheap()
}
}
impl<KT: Hash + Eq, VT: PartialOrd> core::ops::Index<&KT> for HashHeap<KT, VT> {
type Output = VT;
fn index(&self, index: &KT) -> &Self::Output {
self.get(index).expect("key not found")
}
}
impl<KT: Hash + Eq, VT: PartialOrd> From<Vec<(KT, VT)>> for HashHeap<KT, VT> {
fn from(v: Vec<(KT, VT)>) -> HashHeap<KT, VT> {
HashHeap::from_pairs(v, true)
}
}
impl<KT: Hash + Eq, VT: PartialOrd> FromIterator<(KT, VT)> for HashHeap<KT, VT> {
fn from_iter<T: IntoIterator<Item = (KT, VT)>>(iter: T) -> HashHeap<KT, VT> {
HashHeap::from_pairs(iter.into_iter().collect(), false)
}
}
pub struct KeyIter<'a, KT> {
keys: &'a [Option<KT>],
index: usize,
}
impl<'a, KT> Iterator for KeyIter<'a, KT> {
type Item = &'a KT;
fn next(&mut self) -> Option<Self::Item> {
let kn = self.keys.len();
while self.index < kn && self.keys[self.index].is_none() {
self.index += 1;
}
if self.index >= kn {
None
} else {
self.index += 1;
self.keys[self.index - 1].as_ref()
}
} }
pub struct ValIter<'a, VT> {
vals: &'a [(VT, usize)],
index: usize,
}
impl<'a, VT> Iterator for ValIter<'a, VT> {
type Item = &'a VT;
fn next(&mut self) -> Option<Self::Item> {
let vn = self.vals.len();
if self.index >= vn {
None
} else {
self.index += 1;
Some(&self.vals[self.index - 1].0)
}
} }
pub struct KeyValIter<'a, KT, VT> {
hh: &'a HashHeap<KT, VT>,
index: usize,
}
impl<'a, KT: Hash + Eq, VT: PartialOrd> Iterator for KeyValIter<'a, KT, VT> {
type Item = (&'a KT, &'a VT);
fn next(&mut self) -> Option<Self::Item> {
let vn = self.hh.vals.len();
while self.index < vn {
let (v, iv) = &self.hh.vals[self.index];
self.index += 1;
let (ki, _) = self.hh.kmap[iv];
if let Some(k) = &self.hh.keys[ki] {
return Some((k, v));
}
}
None
} }
impl<'a, KT: Hash + Eq, VT: PartialOrd> HashHeap<KT, VT> {
pub fn keys(&'a self) -> KeyIter<'a, KT> {
KeyIter {
keys: &self.keys,
index: 0,
}
}
pub fn values(&'a self) -> ValIter<'a, VT> {
ValIter {
vals: &self.vals,
index: 0,
}
}
pub fn iter(&'a self) -> KeyValIter<'a, KT, VT> {
KeyValIter { hh: self, index: 0 }
}
pub fn priority_stream(&'a mut self) -> PriorityQueue<'a,KT,VT> {
PriorityQueue(self)
}
}
impl<'t, KT: Hash + Eq, VT: PartialOrd> IntoIterator for &'t HashHeap<KT, VT> {
type Item = (&'t KT, &'t VT);
type IntoIter = KeyValIter<'t, KT, VT>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub struct IntoIter<KT, VT>(HashHeap<KT, VT>);
impl<KT: Hash + Eq, VT: PartialOrd> Iterator for IntoIter<KT, VT> {
type Item = (KT, VT);
fn next(&mut self) -> Option<(KT, VT)> {
self.0.pop()
}
}
impl<KT: Hash + Eq, VT: PartialOrd> IntoIterator for HashHeap<KT, VT> {
type Item = (KT, VT);
type IntoIter = IntoIter<KT, VT>;
fn into_iter(self) -> Self::IntoIter {
IntoIter(self)
}
}
pub struct PriorityQueue<'a,KT,VT>(&'a mut HashHeap<KT,VT>);
impl<'a,KT: Hash + Eq, VT: PartialOrd> Iterator
for PriorityQueue<'a,KT,VT>
{
type Item = (KT,VT);
fn next(&mut self) -> Option<Self::Item> {
self.0.pop()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let mut priority_map = HashHeap::<&str, u32>::new_minheap();
priority_map.insert("A", 4); priority_map.insert("B", 2);
priority_map.insert("C", 1);
priority_map.insert("D", 3);
priority_map.insert("E", 4);
priority_map.insert("F", 5);
priority_map.insert("A", 6); let mut total = 0;
for (key, val) in &priority_map {
println!("iterator key {} : val {}", key, val);
total += val;
}
assert_eq!(total, 21);
for (key, val) in priority_map {
println!("consuming iterator key {} : val {}", key, val);
}
} }