mirror of
https://github.com/erg-lang/erg.git
synced 2025-07-23 21:18:19 +00:00
67 lines
1.6 KiB
Rust
67 lines
1.6 KiB
Rust
use std::borrow::Borrow;
|
|
use std::cell::RefCell;
|
|
use std::hash::Hash;
|
|
use std::thread::LocalKey;
|
|
|
|
use erg_common::dict::Dict;
|
|
|
|
use crate::ty::Type;
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
|
pub struct SubtypePair {
|
|
pub sub: Type,
|
|
pub sup: Type,
|
|
}
|
|
|
|
impl SubtypePair {
|
|
pub const fn new(sub: Type, sup: Type) -> Self {
|
|
Self { sub, sup }
|
|
}
|
|
}
|
|
|
|
/// Caches type relationships.
|
|
/// The cost of searching for subtype relations of a class, for example, is not small.
|
|
/// Some relationships are cached because they tend to be queried many times.
|
|
#[derive(Debug, Default)]
|
|
pub struct TypeCmpCache {
|
|
cache: Dict<SubtypePair, bool>,
|
|
}
|
|
|
|
impl TypeCmpCache {
|
|
pub fn new() -> Self {
|
|
Self::default()
|
|
}
|
|
|
|
pub fn get<Q: Eq + Hash>(&self, pair: &Q) -> Option<bool>
|
|
where
|
|
SubtypePair: Borrow<Q>,
|
|
{
|
|
self.cache.get(pair).copied()
|
|
}
|
|
|
|
pub fn register(&mut self, pair: SubtypePair, b: bool) {
|
|
self.cache.insert(pair, b);
|
|
}
|
|
}
|
|
|
|
thread_local! {
|
|
static TYPE_CACHE: RefCell<TypeCmpCache> = RefCell::new(TypeCmpCache::default());
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct GlobalTypeCmpCache(LocalKey<RefCell<TypeCmpCache>>);
|
|
|
|
pub static GLOBAL_TYPE_CACHE: GlobalTypeCmpCache = GlobalTypeCmpCache(TYPE_CACHE);
|
|
|
|
impl GlobalTypeCmpCache {
|
|
pub fn get<Q: Eq + Hash>(&'static self, pair: &Q) -> Option<bool>
|
|
where
|
|
SubtypePair: Borrow<Q>,
|
|
{
|
|
self.0.with(|s| s.borrow().get(pair))
|
|
}
|
|
|
|
pub fn register(&'static self, pair: SubtypePair, b: bool) {
|
|
self.0.with(|s| s.borrow_mut().register(pair, b));
|
|
}
|
|
}
|