rustc_query_system/
cache.rs

1//! Cache for candidate selection.
2
3use std::hash::Hash;
4
5use rustc_data_structures::fx::FxHashMap;
6use rustc_data_structures::sync::Lock;
7
8use crate::dep_graph::{DepContext, DepNodeIndex};
9
10pub struct Cache<Key, Value> {
11    hashmap: Lock<FxHashMap<Key, WithDepNode<Value>>>,
12}
13
14impl<Key: Clone, Value: Clone> Clone for Cache<Key, Value> {
15    fn clone(&self) -> Self {
16        Self { hashmap: Lock::new(self.hashmap.borrow().clone()) }
17    }
18}
19
20impl<Key, Value> Default for Cache<Key, Value> {
21    fn default() -> Self {
22        Self { hashmap: Default::default() }
23    }
24}
25
26impl<Key, Value> Cache<Key, Value> {
27    /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear`
28    pub fn clear(&self) {
29        *self.hashmap.borrow_mut() = Default::default();
30    }
31}
32
33impl<Key: Eq + Hash, Value: Clone> Cache<Key, Value> {
34    pub fn get<Tcx: DepContext>(&self, key: &Key, tcx: Tcx) -> Option<Value> {
35        Some(self.hashmap.borrow().get(key)?.get(tcx))
36    }
37
38    pub fn insert(&self, key: Key, dep_node: DepNodeIndex, value: Value) {
39        self.hashmap.borrow_mut().insert(key, WithDepNode::new(dep_node, value));
40    }
41}
42
43#[derive(Debug, Clone, Eq, PartialEq)]
44pub struct WithDepNode<T> {
45    dep_node: DepNodeIndex,
46    cached_value: T,
47}
48
49impl<T: Clone> WithDepNode<T> {
50    pub fn new(dep_node: DepNodeIndex, cached_value: T) -> Self {
51        WithDepNode { dep_node, cached_value }
52    }
53
54    pub fn get<Tcx: DepContext>(&self, tcx: Tcx) -> T {
55        tcx.dep_graph().read_index(self.dep_node);
56        self.cached_value.clone()
57    }
58}