//! Scoped hashmap. use fxhash::FxHashMap; use std::fmt::Debug; use std::hash::Hash; #[derive(Clone, Debug)] pub struct ScopedMap { map: FxHashMap>, gen: u32, gen_by_level: Vec, } impl std::default::Default for ScopedMap { fn default() -> Self { ScopedMap::new() } } #[derive(Clone, Debug)] struct ScopedMapEntry { gen: u32, level: u32, value: V, } impl ScopedMap { pub fn new() -> ScopedMap { ScopedMap { map: FxHashMap::default(), gen: 0, gen_by_level: vec![0], } } pub fn push_level(&mut self) { self.gen += 1; self.gen_by_level.push(self.gen); } pub fn pop_level(&mut self) { self.gen_by_level.pop(); } pub fn insert(&mut self, k: K, v: V) { self.map.insert( k, ScopedMapEntry { gen: *self.gen_by_level.last().unwrap(), level: (self.gen_by_level.len() - 1) as u32, value: v, }, ); } pub fn get(&self, k: &K) -> Option<&V> { self.map.get(k).and_then(|entry| { let level = entry.level as usize; if level < self.gen_by_level.len() && entry.gen == self.gen_by_level[level] { Some(&entry.value) } else { None } }) } }