Skip to content

Commit 1934aae

Browse files
committed
perf(codegen-core): reduce cache key overhead in symbol registry
1 parent 9c47fe3 commit 1934aae

1 file changed

Lines changed: 12 additions & 18 deletions

File tree

packages/codegen-core/src/symbols/registry.ts

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ import type { ISymbolMeta } from '../extensions';
22
import { Symbol } from './symbol';
33
import type { ISymbolIdentifier, ISymbolIn, ISymbolRegistry } from './types';
44

5-
type IndexEntry = [string, unknown];
5+
type IndexEntry = readonly [key: string, value: unknown, serialized: string];
66
type IndexKeySpace = ReadonlyArray<IndexEntry>;
77
type QueryCacheKey = string;
88
type SymbolId = number;
99

1010
export class SymbolRegistry implements ISymbolRegistry {
11-
/** Forward index: cache key → serialized entries it depends on. */
12-
private _cacheDependencies: Map<QueryCacheKey, ReadonlyArray<string>> = new Map();
11+
/** Forward index: cache key → index key space it was registered with. */
12+
private _cacheDependencies: Map<QueryCacheKey, IndexKeySpace> = new Map();
1313
/** Reverse index: serialized index entry → set of cache keys that depend on it. */
14-
private _dependencyToCache: Map<QueryCacheKey, Set<QueryCacheKey>> = new Map();
14+
private _dependencyToCache: Map<string, Set<QueryCacheKey>> = new Map();
1515
private _id: SymbolId = 0;
1616
private _indices: Map<IndexEntry[0], Map<IndexEntry[1], Set<SymbolId>>> = new Map();
1717
private _queryCache: Map<QueryCacheKey, ReadonlyArray<Symbol>> = new Map();
@@ -87,7 +87,7 @@ export class SymbolRegistry implements ISymbolRegistry {
8787
if (value && typeof value === 'object' && !Array.isArray(value)) {
8888
entries.push(...this.buildIndexKeySpace(value as ISymbolMeta, path));
8989
} else {
90-
entries.push([path, value]);
90+
entries.push([path, value, `${path}:${JSON.stringify(value)}`]);
9191
}
9292
}
9393
return entries;
@@ -99,7 +99,7 @@ export class SymbolRegistry implements ISymbolRegistry {
9999
*/
100100
private cacheKeyFromKeySpace(indexKeySpace: IndexKeySpace): QueryCacheKey {
101101
return indexKeySpace
102-
.map((indexEntry) => this.serializeIndexEntry(indexEntry))
102+
.map((indexEntry) => indexEntry[2])
103103
.sort() // ensure order-insensitivity
104104
.join('|');
105105
}
@@ -116,7 +116,7 @@ export class SymbolRegistry implements ISymbolRegistry {
116116

117117
private invalidateCache(indexKeySpace: IndexKeySpace): void {
118118
for (const indexEntry of indexKeySpace) {
119-
const serialized = this.serializeIndexEntry(indexEntry);
119+
const serialized = indexEntry[2];
120120
const cacheKeys = this._dependencyToCache.get(serialized);
121121
if (!cacheKeys) continue;
122122
for (const cacheKey of cacheKeys) {
@@ -126,8 +126,8 @@ export class SymbolRegistry implements ISymbolRegistry {
126126
const deps = this._cacheDependencies.get(cacheKey);
127127
if (deps) {
128128
for (const dep of deps) {
129-
if (dep !== serialized) {
130-
this._dependencyToCache.get(dep)?.delete(cacheKey);
129+
if (dep[2] !== serialized) {
130+
this._dependencyToCache.get(dep[2])?.delete(cacheKey);
131131
}
132132
}
133133
this._cacheDependencies.delete(cacheKey);
@@ -138,7 +138,7 @@ export class SymbolRegistry implements ISymbolRegistry {
138138
}
139139

140140
private isSubset(sub: IndexKeySpace, sup: IndexKeySpace): boolean {
141-
const supMap = new Map(sup);
141+
const supMap = new Map(sup.map((e) => [e[0], e[1]] as const));
142142
for (const [key, value] of sub) {
143143
if (!supMap.has(key) || supMap.get(key) !== value) {
144144
return false;
@@ -202,18 +202,16 @@ export class SymbolRegistry implements ISymbolRegistry {
202202
* are invalidated, the cache key is evicted in O(1) per entry.
203203
*/
204204
private registerCacheDependencies(cacheKey: QueryCacheKey, indexKeySpace: IndexKeySpace): void {
205-
const serializedEntries: Array<string> = [];
206205
for (const indexEntry of indexKeySpace) {
207-
const serialized = this.serializeIndexEntry(indexEntry);
208-
serializedEntries.push(serialized);
206+
const serialized = indexEntry[2];
209207
let cacheKeys = this._dependencyToCache.get(serialized);
210208
if (!cacheKeys) {
211209
cacheKeys = new Set();
212210
this._dependencyToCache.set(serialized, cacheKeys);
213211
}
214212
cacheKeys.add(cacheKey);
215213
}
216-
this._cacheDependencies.set(cacheKey, serializedEntries);
214+
this._cacheDependencies.set(cacheKey, indexKeySpace);
217215
}
218216

219217
private replaceStubs(symbol: Symbol, indexKeySpace: IndexKeySpace): void {
@@ -230,8 +228,4 @@ export class SymbolRegistry implements ISymbolRegistry {
230228
}
231229
}
232230
}
233-
234-
private serializeIndexEntry(indexEntry: IndexEntry): string {
235-
return `${indexEntry[0]}:${JSON.stringify(indexEntry[1])}`;
236-
}
237231
}

0 commit comments

Comments
 (0)