use crate::fx::FxHashMap; use arrayvec::ArrayVec; use std::hash::Hash; /// Small-storage-optimized implementation of a map /// made specifically for caching results. /// /// Stores elements in a small array up to a certain length /// and switches to `HashMap` when that length is exceeded. pub enum MiniMap { Array(ArrayVec<[(K, V); 8]>), Map(FxHashMap), } impl MiniMap { /// Creates an empty `MiniMap`. pub fn new() -> Self { MiniMap::Array(ArrayVec::new()) } /// Inserts or updates value in the map. pub fn insert(&mut self, key: K, value: V) { match self { MiniMap::Array(array) => { for pair in array.iter_mut() { if pair.0 == key { pair.1 = value; return; } } if let Err(error) = array.try_push((key, value)) { let mut map: FxHashMap = array.drain(..).collect(); let (key, value) = error.element(); map.insert(key, value); *self = MiniMap::Map(map); } } MiniMap::Map(map) => { map.insert(key, value); } } } /// Return value by key if any. pub fn get(&self, key: &K) -> Option<&V> { match self { MiniMap::Array(array) => { for pair in array { if pair.0 == *key { return Some(&pair.1); } } return None; } MiniMap::Map(map) => { return map.get(key); } } } }