use std::collections::HashMap;
use std::hash::Hash;
use std::sync::{Mutex, MutexGuard};
#[derive(Debug)]
pub(crate) struct MemoCache<K, V> {
entries: Mutex<HashMap<K, V>>,
}
impl<K, V> Default for MemoCache<K, V> {
fn default() -> Self {
Self {
entries: Mutex::new(HashMap::new()),
}
}
}
impl<K, V> MemoCache<K, V>
where
K: Eq + Hash,
V: Clone,
{
pub(crate) fn get_or_compute(&self, key: K, compute: impl FnOnce() -> V) -> V {
if let Some(cached) = self.entries().get(&key) {
return cached.clone();
}
let value = compute();
self.entries().insert(key, value.clone());
value
}
fn entries(&self) -> MutexGuard<'_, HashMap<K, V>> {
match self.entries.lock() {
Ok(guard) => guard,
Err(err) => err.into_inner(),
}
}
}