//! Cache for candidate selection. use crate::dep_graph::DepNodeIndex; use crate::query::QueryContext; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::HashMapExt; use rustc_data_structures::sync::Lock; use std::hash::Hash; #[derive(Clone)] pub struct Cache { hashmap: Lock>>, } impl Default for Cache { fn default() -> Self { Self { hashmap: Default::default() } } } impl Cache { /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear` pub fn clear(&self) { *self.hashmap.borrow_mut() = Default::default(); } } impl Cache { pub fn get(&self, key: &Key, tcx: CTX) -> Option { Some(self.hashmap.borrow().get(key)?.get(tcx)) } pub fn insert(&self, key: Key, dep_node: DepNodeIndex, value: Value) { self.hashmap.borrow_mut().insert(key, WithDepNode::new(dep_node, value)); } pub fn insert_same(&self, key: Key, dep_node: DepNodeIndex, value: Value) where Value: Eq, { self.hashmap.borrow_mut().insert_same(key, WithDepNode::new(dep_node, value)); } } #[derive(Clone, Eq, PartialEq)] pub struct WithDepNode { dep_node: DepNodeIndex, cached_value: T, } impl WithDepNode { pub fn new(dep_node: DepNodeIndex, cached_value: T) -> Self { WithDepNode { dep_node, cached_value } } pub fn get(&self, tcx: CTX) -> T { tcx.dep_graph().read_index(self.dep_node); self.cached_value.clone() } }