waffle/src/scoped_map.rs

67 lines
1.5 KiB
Rust
Raw Normal View History

2022-11-03 01:32:23 -05:00
//! Scoped hashmap.
use fxhash::FxHashMap;
2022-11-03 02:20:58 -05:00
use std::fmt::Debug;
2022-11-03 01:32:23 -05:00
use std::hash::Hash;
2022-11-03 02:20:58 -05:00
#[derive(Clone, Debug)]
pub struct ScopedMap<K: Hash + Eq + Clone + Debug, V: Clone + Debug> {
2022-11-03 01:32:23 -05:00
map: FxHashMap<K, ScopedMapEntry<V>>,
gen: u32,
gen_by_level: Vec<u32>,
}
2022-11-03 02:20:58 -05:00
impl<K: Hash + Eq + Clone + Debug, V: Clone + Debug> std::default::Default for ScopedMap<K, V> {
fn default() -> Self {
ScopedMap::new()
}
}
#[derive(Clone, Debug)]
struct ScopedMapEntry<V: Clone + Debug> {
2022-11-03 01:32:23 -05:00
gen: u32,
level: u32,
value: V,
}
2022-11-03 02:20:58 -05:00
impl<K: Hash + Eq + Clone + Debug, V: Clone + Debug> ScopedMap<K, V> {
2022-11-03 01:32:23 -05:00
pub fn new() -> ScopedMap<K, V> {
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 {
2022-11-03 02:20:58 -05:00
gen: *self.gen_by_level.last().unwrap(),
level: (self.gen_by_level.len() - 1) as u32,
2022-11-03 01:32:23 -05:00
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
}
})
}
}