use once_cell::sync::OnceCell;
use std::hash::Hash;
use std::sync::{Arc, Mutex, MutexGuard, Weak};
use weak_table::WeakHashSet;
pub(crate) struct InternCache<T> {
cache: OnceCell<Mutex<WeakHashSet<Weak<T>>>>,
}
impl<T> InternCache<T> {
pub(crate) const fn new() -> Self {
InternCache {
cache: OnceCell::new(),
}
}
}
impl<T: Eq + Hash> InternCache<T> {
fn cache(&self) -> MutexGuard<'_, WeakHashSet<Weak<T>>> {
let cache = self.cache.get_or_init(|| Mutex::new(WeakHashSet::new()));
cache.lock().expect("Poisoned lock lock for cache")
}
pub(crate) fn intern(&self, value: T) -> Arc<T> {
let mut cache = self.cache();
if let Some(pp) = cache.get(&value) {
pp
} else {
let arc = Arc::new(value);
cache.insert(Arc::clone(&arc));
arc
}
}
}