1use std::sync::OnceLock;
2
3use rustc_data_structures::sharded::ShardedHashMap;
4pub use rustc_data_structures::vec_cache::VecCache;
5use rustc_hir::def_id::LOCAL_CRATE;
6use rustc_index::Idx;
7use rustc_span::def_id::{DefId, DefIndex};
8
9use crate::dep_graph::DepNodeIndex;
10use crate::query::keys::QueryKey;
11
12pub trait QueryCache: Sized {
18 type Key: QueryKey;
19 type Value: Copy;
20
21 fn without_track_present() -> Self
26 where
27 Self: Default,
28 {
29 Default::default()
30 }
31
32 fn lookup(&self, key: &Self::Key) -> Option<(Self::Value, DepNodeIndex)>;
35
36 fn complete(&self, key: Self::Key, value: Self::Value, index: DepNodeIndex);
41
42 fn for_each(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex));
44
45 fn len(&self) -> usize;
50}
51
52pub struct DefaultCache<K, V> {
55 cache: ShardedHashMap<K, (V, DepNodeIndex)>,
56}
57
58impl<K, V> Default for DefaultCache<K, V> {
59 fn default() -> Self {
60 DefaultCache { cache: Default::default() }
61 }
62}
63
64impl<K, V> QueryCache for DefaultCache<K, V>
65where
66 K: QueryKey,
67 V: Copy,
68{
69 type Key = K;
70 type Value = V;
71
72 #[inline(always)]
73 fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> {
74 self.cache.get(key)
75 }
76
77 #[inline]
78 fn complete(&self, key: K, value: V, index: DepNodeIndex) {
79 self.cache.insert_unique(key, (value, index));
80 }
81
82 fn for_each(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
83 for shard in self.cache.lock_shards() {
84 for (k, v) in shard.iter() {
85 f(k, &v.0, v.1);
86 }
87 }
88 }
89
90 fn len(&self) -> usize {
91 self.cache.len()
92 }
93}
94
95pub struct SingleCache<V> {
98 cache: OnceLock<(V, DepNodeIndex)>,
99}
100
101impl<V> Default for SingleCache<V> {
102 fn default() -> Self {
103 SingleCache { cache: OnceLock::new() }
104 }
105}
106
107impl<V> QueryCache for SingleCache<V>
108where
109 V: Copy,
110{
111 type Key = ();
112 type Value = V;
113
114 #[inline(always)]
115 fn lookup(&self, _key: &()) -> Option<(V, DepNodeIndex)> {
116 self.cache.get().copied()
117 }
118
119 #[inline]
120 fn complete(&self, _key: (), value: V, index: DepNodeIndex) {
121 self.cache.set((value, index)).ok();
122 }
123
124 fn for_each(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
125 if let Some(value) = self.cache.get() {
126 f(&(), &value.0, value.1)
127 }
128 }
129
130 fn len(&self) -> usize {
131 self.cache.get().is_some().into()
132 }
133}
134
135pub struct DefIdCache<V> {
140 local: VecCache<DefIndex, V, DepNodeIndex>,
143 foreign: DefaultCache<DefId, V>,
144}
145
146impl<V> Default for DefIdCache<V> {
147 fn default() -> Self {
148 DefIdCache { local: Default::default(), foreign: Default::default() }
149 }
150}
151
152impl<V> QueryCache for DefIdCache<V>
153where
154 V: Copy,
155{
156 type Key = DefId;
157 type Value = V;
158
159 fn without_track_present() -> Self {
160 DefIdCache { local: VecCache::without_track_present(), foreign: Default::default() }
161 }
162
163 #[inline(always)]
164 fn lookup(&self, key: &DefId) -> Option<(V, DepNodeIndex)> {
165 if key.krate == LOCAL_CRATE {
166 self.local.lookup(&key.index)
167 } else {
168 self.foreign.lookup(key)
169 }
170 }
171
172 #[inline]
173 fn complete(&self, key: DefId, value: V, index: DepNodeIndex) {
174 if key.krate == LOCAL_CRATE {
175 self.local.complete(key.index, value, index)
176 } else {
177 self.foreign.complete(key, value, index)
178 }
179 }
180
181 fn for_each(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
182 self.local.for_each(&mut |key, value, index| {
183 f(&DefId { krate: LOCAL_CRATE, index: *key }, value, index);
184 });
185 self.foreign.for_each(f);
186 }
187
188 fn len(&self) -> usize {
189 self.local.len() + self.foreign.len()
190 }
191}
192
193impl<K, V> QueryCache for VecCache<K, V, DepNodeIndex>
194where
195 K: Idx + QueryKey,
196 V: Copy,
197{
198 type Key = K;
199 type Value = V;
200
201 fn without_track_present() -> Self {
202 VecCache::without_track_present()
203 }
204
205 #[inline(always)]
206 fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> {
207 self.lookup(key)
208 }
209
210 #[inline]
211 fn complete(&self, key: K, value: V, index: DepNodeIndex) {
212 self.complete(key, value, index)
213 }
214
215 fn for_each(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
216 self.for_each(f)
217 }
218
219 fn len(&self) -> usize {
220 self.len()
221 }
222}