sim_kernel/library/registry/
query.rs1use std::collections::{BTreeMap, BTreeSet};
2use std::sync::Arc;
3
4use crate::{
5 catalog::CatalogSnapshot,
6 id::{
7 ClassId, CodecId, FunctionId, MacroId, NumberDomainId, RuntimeId, ShapeId, SiteId, Symbol,
8 },
9 value::Value,
10};
11
12use super::Registry;
13use crate::library::{
14 ExportKind, LibBootDependency, LibBootReceipt, LibManifest, LibSourceSpec, LoadedLib,
15 RegisteredTest, Test,
16};
17
18fn symbol_for_cached_value<Id>(
19 symbols: &BTreeMap<Symbol, Id>,
20 values: &BTreeMap<Id, Value>,
21 value: &Value,
22) -> Option<Symbol>
23where
24 Id: Copy + Ord,
25{
26 symbols.iter().find_map(|(symbol, id)| {
27 values
28 .get(id)
29 .filter(|candidate| *candidate == value)
30 .map(|_| symbol.clone())
31 })
32}
33
34fn symbol_for_plain_value(values: &BTreeMap<Symbol, Value>, value: &Value) -> Option<Symbol> {
35 values
36 .iter()
37 .find_map(|(symbol, candidate)| (candidate == value).then(|| symbol.clone()))
38}
39
40impl Registry {
41 pub fn catalog_snapshot(&self) -> CatalogSnapshot {
43 CatalogSnapshot::from_store(&self.catalog)
44 }
45
46 pub fn libs(&self) -> &[LoadedLib] {
48 &self.libs
49 }
50
51 pub fn boot_receipt(
53 &self,
54 lib_id: crate::LibId,
55 requested_source: LibSourceSpec,
56 resolved_source: LibSourceSpec,
57 ) -> Option<LibBootReceipt> {
58 let loaded = self.libs.iter().find(|loaded| loaded.id == lib_id)?;
59 let dependencies = self
60 .load_dependencies
61 .get(&lib_id)
62 .into_iter()
63 .flat_map(|dependencies| dependencies.iter())
64 .filter_map(|dependency| {
65 let symbol = self
66 .libs
67 .iter()
68 .find(|loaded| loaded.id == *dependency)?
69 .manifest
70 .id
71 .clone();
72 Some(LibBootDependency {
73 lib_id: *dependency,
74 symbol,
75 })
76 })
77 .collect();
78 Some(LibBootReceipt {
79 lib_id,
80 requested_source,
81 resolved_source,
82 manifest: loaded.manifest.clone(),
83 dependencies,
84 exports: loaded.exports.clone(),
85 })
86 }
87
88 pub fn subset_for_libs(&self, libs: &[Symbol]) -> Self {
90 if libs.is_empty() {
91 return Self::default();
92 }
93
94 let allowed = libs.iter().cloned().collect::<BTreeSet<_>>();
95 let mut registry = self.clone();
96 registry
97 .libs
98 .retain(|loaded| allowed.contains(&loaded.manifest.id));
99 registry
100 .libs_by_symbol
101 .retain(|symbol, _| allowed.contains(symbol));
102 let allowed_ids = registry
103 .libs
104 .iter()
105 .map(|loaded| loaded.id)
106 .collect::<BTreeSet<_>>();
107 registry
108 .load_deltas
109 .retain(|lib_id, _| allowed_ids.contains(lib_id));
110 registry.load_dependencies.retain(|lib_id, dependencies| {
111 if !allowed_ids.contains(lib_id) {
112 return false;
113 }
114 dependencies.retain(|dependency| allowed_ids.contains(dependency));
115 true
116 });
117
118 let exported_symbols = registry
119 .libs
120 .iter()
121 .flat_map(|loaded| loaded.exports.iter())
122 .map(|record| (record.kind.clone(), record.symbol.clone()))
123 .collect::<BTreeSet<_>>();
124
125 registry.export_symbols.retain(|kind, symbols| {
126 symbols.retain(|symbol, _| exported_symbols.contains(&(kind.clone(), symbol.clone())));
127 !symbols.is_empty()
128 });
129
130 registry.class_symbol_cache.retain(|symbol, _| {
131 exported_symbols.contains(&(ExportKind::named(ExportKind::CLASS), symbol.clone()))
132 });
133 registry.function_symbol_cache.retain(|symbol, _| {
134 exported_symbols.contains(&(ExportKind::named(ExportKind::FUNCTION), symbol.clone()))
135 });
136 registry.macro_symbol_cache.retain(|symbol, _| {
137 exported_symbols.contains(&(ExportKind::named(ExportKind::MACRO), symbol.clone()))
138 });
139 registry.shape_symbol_cache.retain(|symbol, _| {
140 exported_symbols.contains(&(ExportKind::named(ExportKind::SHAPE), symbol.clone()))
141 });
142 registry.codec_symbol_cache.retain(|symbol, _| {
143 exported_symbols.contains(&(ExportKind::named(ExportKind::CODEC), symbol.clone()))
144 });
145 registry.number_domain_symbol_cache.retain(|symbol, _| {
146 exported_symbols
147 .contains(&(ExportKind::named(ExportKind::NUMBER_DOMAIN), symbol.clone()))
148 });
149 registry.site_symbol_cache.retain(|symbol, _| {
150 exported_symbols.contains(&(ExportKind::named(ExportKind::SITE), symbol.clone()))
151 });
152 registry.plain_value_cache.retain(|symbol, _| {
153 exported_symbols.contains(&(ExportKind::named(ExportKind::VALUE), symbol.clone()))
154 });
155
156 registry.class_value_cache.retain(|id, _| {
157 registry
158 .class_symbol_cache
159 .values()
160 .any(|value| value == id)
161 });
162 registry.function_value_cache.retain(|id, _| {
163 registry
164 .function_symbol_cache
165 .values()
166 .any(|value| value == id)
167 });
168 registry.macro_value_cache.retain(|id, _| {
169 registry
170 .macro_symbol_cache
171 .values()
172 .any(|value| value == id)
173 });
174 registry.shape_value_cache.retain(|id, _| {
175 registry
176 .shape_symbol_cache
177 .values()
178 .any(|value| value == id)
179 });
180 registry.codec_value_cache.retain(|id, _| {
181 registry
182 .codec_symbol_cache
183 .values()
184 .any(|value| value == id)
185 });
186 registry.number_domain_value_cache.retain(|id, _| {
187 registry
188 .number_domain_symbol_cache
189 .values()
190 .any(|value| value == id)
191 });
192 registry
193 .site_value_cache
194 .retain(|id, _| registry.site_symbol_cache.values().any(|value| value == id));
195 registry.tests.retain(|_, test| allowed.contains(&test.lib));
196 registry
197 .tests_by_lib
198 .retain(|symbol, _| allowed.contains(symbol));
199 registry.retain_catalog_rows_for_subset();
200 registry.rebuild_projection_caches_from_catalog();
201 registry
202 }
203
204 pub fn lib(&self, symbol: &Symbol) -> Option<&LoadedLib> {
206 let id = self.libs_by_symbol.get(symbol)?;
207 self.libs.iter().find(|loaded| loaded.id == *id)
208 }
209
210 pub(crate) fn lib_mut(&mut self, symbol: &Symbol) -> Option<&mut LoadedLib> {
211 let id = *self.libs_by_symbol.get(symbol)?;
212 self.libs.iter_mut().find(|loaded| loaded.id == id)
213 }
214
215 pub fn export_symbols(
217 &self,
218 ) -> &std::collections::BTreeMap<ExportKind, std::collections::BTreeMap<Symbol, crate::RuntimeId>>
219 {
220 &self.export_symbols
221 }
222
223 pub fn classes(&self) -> &std::collections::BTreeMap<Symbol, ClassId> {
225 &self.class_symbol_cache
226 }
227
228 pub fn functions(&self) -> &std::collections::BTreeMap<Symbol, FunctionId> {
230 &self.function_symbol_cache
231 }
232
233 pub fn macros(&self) -> &std::collections::BTreeMap<Symbol, MacroId> {
235 &self.macro_symbol_cache
236 }
237
238 pub fn shapes(&self) -> &std::collections::BTreeMap<Symbol, ShapeId> {
240 &self.shape_symbol_cache
241 }
242
243 pub fn codecs(&self) -> &std::collections::BTreeMap<Symbol, CodecId> {
245 &self.codec_symbol_cache
246 }
247
248 pub fn number_domains(&self) -> &std::collections::BTreeMap<Symbol, NumberDomainId> {
250 &self.number_domain_symbol_cache
251 }
252
253 pub fn sites(&self) -> &std::collections::BTreeMap<Symbol, SiteId> {
255 &self.site_symbol_cache
256 }
257
258 pub fn tests(&self) -> &std::collections::BTreeMap<Symbol, RegisteredTest> {
260 &self.tests
261 }
262
263 pub fn tests_for_lib(&self, symbol: &Symbol) -> Option<&[Symbol]> {
265 self.tests_by_lib.get(symbol).map(Vec::as_slice)
266 }
267
268 pub fn class_value(&self, id: ClassId) -> Option<&Value> {
270 self.catalog_value_by_runtime_id(RuntimeId::Class(id))
271 }
272
273 pub fn function_value(&self, id: FunctionId) -> Option<&Value> {
275 self.catalog_value_by_runtime_id(RuntimeId::Function(id))
276 }
277
278 pub fn macro_value(&self, id: MacroId) -> Option<&Value> {
280 self.catalog_value_by_runtime_id(RuntimeId::Macro(id))
281 }
282
283 pub fn shape_value(&self, id: ShapeId) -> Option<&Value> {
285 self.catalog_value_by_runtime_id(RuntimeId::Shape(id))
286 }
287
288 pub fn codec_value(&self, id: CodecId) -> Option<&Value> {
290 self.catalog_value_by_runtime_id(RuntimeId::Codec(id))
291 }
292
293 pub fn number_domain_value(&self, id: NumberDomainId) -> Option<&Value> {
295 self.catalog_value_by_runtime_id(RuntimeId::NumberDomain(id))
296 }
297
298 pub fn site_value(&self, id: RuntimeId) -> Option<&Value> {
300 match id {
301 RuntimeId::Site(_) => self.catalog_value_by_runtime_id(id),
302 _ => None,
303 }
304 }
305
306 pub fn class_by_symbol(&self, symbol: &Symbol) -> Option<&Value> {
308 self.catalog_value_by_export(&ExportKind::named(ExportKind::CLASS), symbol)
309 }
310
311 pub fn function_by_symbol(&self, symbol: &Symbol) -> Option<&Value> {
313 self.catalog_value_by_export(&ExportKind::named(ExportKind::FUNCTION), symbol)
314 }
315
316 pub fn macro_by_symbol(&self, symbol: &Symbol) -> Option<&Value> {
318 self.catalog_value_by_export(&ExportKind::named(ExportKind::MACRO), symbol)
319 }
320
321 pub fn shape_by_symbol(&self, symbol: &Symbol) -> Option<&Value> {
323 self.catalog_value_by_export(&ExportKind::named(ExportKind::SHAPE), symbol)
324 }
325
326 pub fn codec_by_symbol(&self, symbol: &Symbol) -> Option<&Value> {
328 self.catalog_value_by_export(&ExportKind::named(ExportKind::CODEC), symbol)
329 }
330
331 pub fn number_domain_by_symbol(&self, symbol: &Symbol) -> Option<&Value> {
333 self.catalog_value_by_export(&ExportKind::named(ExportKind::NUMBER_DOMAIN), symbol)
334 }
335
336 pub fn site_by_symbol(&self, symbol: &Symbol) -> Option<&Value> {
338 self.catalog_value_by_export(&ExportKind::named(ExportKind::SITE), symbol)
339 }
340
341 pub fn manifest_by_symbol(&self, symbol: &Symbol) -> Option<&LibManifest> {
343 self.lib(symbol).map(|loaded| &loaded.manifest)
344 }
345
346 pub fn test_by_symbol(&self, symbol: &Symbol) -> Option<&Arc<dyn Test>> {
348 self.tests.get(symbol).map(|test| &test.test)
349 }
350
351 pub fn registered_test(&self, symbol: &Symbol) -> Option<&RegisteredTest> {
353 self.tests.get(symbol)
354 }
355
356 pub fn value_by_symbol(&self, symbol: &Symbol) -> Option<&Value> {
358 self.catalog_value_by_export(&ExportKind::named(ExportKind::VALUE), symbol)
359 }
360
361 pub fn export_symbol_for_value(&self, value: &Value) -> Option<Symbol> {
364 symbol_for_cached_value(&self.class_symbol_cache, &self.class_value_cache, value)
365 .or_else(|| {
366 symbol_for_cached_value(
367 &self.function_symbol_cache,
368 &self.function_value_cache,
369 value,
370 )
371 })
372 .or_else(|| {
373 symbol_for_cached_value(&self.macro_symbol_cache, &self.macro_value_cache, value)
374 })
375 .or_else(|| {
376 symbol_for_cached_value(&self.shape_symbol_cache, &self.shape_value_cache, value)
377 })
378 .or_else(|| {
379 symbol_for_cached_value(&self.codec_symbol_cache, &self.codec_value_cache, value)
380 })
381 .or_else(|| {
382 symbol_for_cached_value(
383 &self.number_domain_symbol_cache,
384 &self.number_domain_value_cache,
385 value,
386 )
387 })
388 .or_else(|| {
389 symbol_for_cached_value(&self.site_symbol_cache, &self.site_value_cache, value)
390 })
391 .or_else(|| symbol_for_plain_value(&self.plain_value_cache, value))
392 }
393}