Skip to content

Commit d29e271

Browse files
os-zhuangos-project-managerclaude
authored
perf(objectql): index short name to FQN so registry lookups stop scanning the whole registry (#11102)
* perf(objectql): index short name → FQN so registry lookups stop scanning the whole registry `SchemaRegistry.resolveObjectKey` answered the short-name direction by walking every `objectContributors` key and calling `parseFQN` on each. Reached from seven call sites including `getObject`, so a kernel boot that registers N objects and resolves O(N) names did O(N^2) string work — the mechanism behind a hosted environment whose bootstrap outgrew its request waiter and became permanently unservable with no error anywhere. Maintain a short-name -> FQN index Map beside `objectContributors`, mutated only through two private choke points (`openObjectEntry` / `closeObjectEntry`) so the two containers cannot drift. Resolution is unchanged: the index array is the scan's `matches` list with the same members in the same order, so an ambiguous short name still resolves to the first key registered under it and the ambiguity warning still names every match. Refs #10945 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RfyXxZ2WPjcjhuXpiQQc3y * test(objectql): tune the registry scaling pin to the measured populations, add changeset Ablation on this container: healthy ratio 5.7-11.1, full-registry scan 62.5. Threshold placed between them (30x) rather than close to either, and PASSES raised so the small window clears timer noise. Refs #10945 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RfyXxZ2WPjcjhuXpiQQc3y --------- Co-authored-by: Claude <pm@objectstack.ai> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent 189373b commit d29e271

3 files changed

Lines changed: 503 additions & 17 deletions

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
"@objectstack/objectql": patch
3+
---
4+
5+
Index short name → FQN in `SchemaRegistry` so name lookups stop scanning the
6+
whole registry (#10945).
7+
8+
`SchemaRegistry.resolveObjectKey` answered the short-name direction by walking
9+
**every** key of `objectContributors` and calling `parseFQN` on each. It is
10+
reached from seven call sites — `getObject` among them — so a kernel boot that
11+
registers N objects and resolves O(N) names did O(N²) string work, with
12+
`parseFQN` the largest non-database entry in the CPU profile.
13+
14+
The consequence was a silence rather than a failure: boot got slower purely by
15+
an environment accumulating metadata, and once bootstrap outgrew the request
16+
waiter every request answered `kernel_warming` and the environment could never
17+
be opened — no error anywhere.
18+
19+
`resolveObjectKey` now reads a short-name → FQN index `Map` maintained beside
20+
`objectContributors`. Both containers are mutated only through two private
21+
choke points, so they cannot drift apart: a caller cannot add a contributor
22+
list and forget the index half.
23+
24+
Resolution is deliberately unchanged. The index array holds the same members in
25+
the same order as the list the scan built, so an ambiguous short name still
26+
resolves to the **first** key registered under it, the ambiguity warning still
27+
names every match, and the legacy `<ns>__<name>` fallback still works. That
28+
equivalence is pinned against the old loop itself, over every registration
29+
order, rather than against a hand-written expectation.
30+
31+
Measured on the same container, resolving one name per registered object:
32+
33+
| registry | 32,000 lookups over 4,000 objects | scaling ratio at 8× input |
34+
|---|---|---|
35+
| full-registry scan | 4,888 ms | 62.5× (quadratic) |
36+
| short-name index | 2.3 ms | 5.7× |

0 commit comments

Comments
 (0)