use parking_lot::Mutex;
use shared::core::geometry::{Bounds2i, Point2i};
use std::collections::HashSet;
use std::hash::Hash;
use std::sync::Arc;

pub struct InternCache<T> {
    cache: Mutex<HashSet<Arc<T>>>,
}

impl<T> InternCache<T>
where
    T: Eq + Clone + Hash,
{
    pub fn new() -> Self {
        Self {
            cache: Mutex::new(HashSet::new()),
        }
    }

    pub fn lookup(&self, value: T) -> Arc<T> {
        let mut lock = self.cache.lock();

        if let Some(existing) = lock.get(&value) {
            return existing.clone();
        }

        let new_item = Arc::new(value);
        lock.insert(Arc::clone(&new_item));
        new_item
    }
}
