use crndm::default::*; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; const BUCKETS_MAX: usize = 16; type P = BuddyAlloc; type Bucket = PVec>; pub struct HashMap { buckets: PVec>>, values: PVec>, } impl> HashMap where K: PartialEq + Hash, V: Copy, { pub fn new(j: &Journal) -> Self { let mut buckets = PVec::with_capacity(BUCKETS_MAX, j); for _ in 0..BUCKETS_MAX { buckets.push(PRefCell::new(PVec::new(j), j), j) } Self { buckets, values: PVec::new(j), } } pub fn get(&self, key: K) -> Option { let mut hasher = DefaultHasher::new(); key.hash(&mut hasher); let index = (hasher.finish() as usize) % BUCKETS_MAX; for e in &*self.buckets[index].borrow() { let e = e.borrow(); if e.0 == key { return Some(self.values[e.1].get()); } } None } pub fn put(&mut self, key: K, val: V, j: &Journal) { let mut hasher = DefaultHasher::new(); key.hash(&mut hasher); let index = (hasher.finish() as usize) % BUCKETS_MAX; let mut bucket = self.buckets[index].borrow_mut(j); for e in &*bucket { let e = e.borrow(); if e.0 == key { self.values[e.1].set(val, j); return; } } self.values.push(PCell::new(val, j), j); bucket.push(PRefCell::new((key, self.values.len() - 1), j), j); } pub fn update_with V>(&mut self, key: &K, j: &Journal, f: F) where V: Default, K: PClone

, { let mut hasher = DefaultHasher::new(); key.hash(&mut hasher); let index = (hasher.finish() as usize) % BUCKETS_MAX; let mut bucket = self.buckets[index].borrow_mut(j); for e in &*bucket { let e = e.borrow(); if e.0 == *key { self.values[e.1].set(f(self.values[e.1].get()), j); return; } } self.values.push(PCell::new(f(V::default()), j), j); bucket.push( PRefCell::new((key.pclone(j), self.values.len() - 1), j), j, ); } pub fn foreach ()>(&self, mut f: F) { for i in 0..BUCKETS_MAX { for e in &*self.buckets[i].borrow() { let e = e.borrow(); f(&e.0, &self.values[e.1].get()); } } } pub fn clear(&mut self, j: &Journal) { for i in 0..BUCKETS_MAX { *self.buckets[i].borrow_mut(j) = PVec::new(j); } self.values.clear(); } pub fn is_empty(&self) -> bool { for i in 0..BUCKETS_MAX { if !self.buckets[i].borrow().is_empty() { return false; } } true } }