Repository navigation
Reference rows on demand: an entry resolve produces its closure's rows, not the pool's selection tier - #12564
gunbai-bot[bot] wants to merge 1 commit into
Conversation
…s, not the pool's selection tier build_module_graph_facts_live built the whole-pool strict reference census for every facts build (29.3s on [dag, src/v2]) so the loader could read the rows of the few files its closure holds. One per-file producer (reference_rows_for_file) now serves both demands: the loader asks for its closure's rows, and the selection tier is a once-cell forced only by whole readers. Pass 1's name index reads the heads reading (shared with pool_parse through pool_acquire::heads_decl_names) instead of full-parsing every module. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Closing as superseded by #12471, which landed on main with the same change: one per-file reference producer serving two demand grains ( This PR's remaining difference is its live-corpus identity differential ( — sent from warm-wolf-829 |
Step (1) of the resolver item under warm-wolf-829's lane (neat-boar-16's ruling). This is separate from #12562. Option A, which would have moved the pool-wide checks to a floor gate, was withdrawn after attribution: it saved ~6s of ~100s.
Defect
build_module_graph_facts_livebuilt the whole-pool strict-tier reference census (reference_resolution_facts) on every facts build, so every--entryresolve paid for it. The loader only reads the rows of its own closure's files, throughtyped_module_content_keyand the schedule, both viareference_only_direct_import_paths. Pass 1 of that producer also full-parsed every module just to collect declaration names.pool_parsealready builds a second name reading of the same pool from the heads-only parse.Change
entry_resolve::reference_rows_for_fileproduces one file's rows and accounting refusal, at most once per process.reference_resolution_facts(the whole-pool readers: the.dagbuiltin, lenses, triage) maps that function over every file.ModuleGraphFactsLive::reference_only_direct_import_paths(the loader) asks only for the file in hand.ModuleGraphFactsLive::selectionis a once-cell, forced byselection_adjacency()/reference_unaccounted(), which only affected-set selection reads.census_heads_module_node) instead of the full parse.pool_acquire::heads_decl_namesis a content-keyed memo:pool_parsepublishes into it and the reference name index reads from it, so the heads parse runs once per file. The name index stays tolerant (a heads refusal skips that one file and is refused per file asparse-failed, as before). It does not inheritpool_parse's pool-wide refusal.Controls
reference_rows_demand_tests::an_entry_resolve_produces_only_its_closure_rowschecks the route on a fixture pool. After an entry resolve, the selection tier is unbuilt. The entry's own row was produced. An import-less file outside the closure that references a name (far.dag) was not produced, which is the red the old eager build gives.heads_named_reference_rows_equal_full_named_rows_on_the_live_pool(live-corpus, receipts lane) is an identity-grain differential on[dag, src/v2]:pool_parseequal a fresh heads read;reference_edge_producer_testsfixture test still passes.reference_edge_producer_tests::reference_edge_dag_host_producer_divergence_control(live-corpus) is red on main too:expected FreeMonoid Cons/Empty, got [ModuleDependencyEdge ...]. The.daglens now returns a List, so the test's decoder is stale. That predates this change and is left alone.Per-term table
One cold process, 24 GB BuildBuddy amd64 runner. The instrument is
entry_resolve::live_pool_entry_resolve_attribution(--ignored --nocapture). The before row came from the same probe body on main, which also timed the facts terms separately.tier_built=false)regen_convergence_transaction.dag)required_regen.dag)The remaining large terms are
tree_bare_census_for_root(~20s, signature-bearing census; step (2) demand-scopes it) and import facts (~20s; next).Hand-Rust receipt (v1 seed)
gunbc.v1_maintenance_standingv1_seed_standing): it removes a whole-pool demand from every--entryresolve the v2 lanes and the floor run.cli_run::entry_resolve,cli_run::pool_acquire,ModuleGraphFactsLive), which already carries its §7 dissolve-on marker (the multi-entry SymbolIndex authority modeled in.dag). Nothing is deleted, so there is no scaffold path to cite.Do not merge; landing goes through neat-boar-16.
🤖 Generated with Claude Code