refactor: share chunked statement-cache primitive between builder and structure#1890
Conversation
… structure batchUpdateRoles in features/structure.ts re-implemented the same chunk-size-keyed prepared-statement cache already used by getNodeStmt/getEdgeStmt/getExportStmt in domain/graph/builder/helpers.ts (check cache by chunk size, prepare + cache on miss) — the SQL and cache scope differed, but the caching mechanics were identical. Extracted the shared mechanics into src/shared/chunked-stmt-cache.ts: getOrCreateChunkStmt (flat Map<chunkSize, stmt>) and its per-database wrapper getOrCreatePerDbChunkStmt (WeakMap<db, Map<chunkSize, stmt>>). builder/helpers.ts's three statement getters now delegate to getOrCreatePerDbChunkStmt against their existing WeakMap caches (same persisted-across-calls semantics as before); batchUpdateRoles now calls getOrCreateChunkStmt against a Map created fresh per call (same per-call-only lifetime as before). No SQL, chunking, or caching-scope changes on either side — one implementation instead of two copies of the same shape. Placed the primitive in shared/ rather than exporting it from builder/helpers.ts: nothing outside domain/graph/builder/ currently imports from that directory directly — index.ts, cli/commands/build.ts, and features/branch-compare.ts all go through the domain/graph/builder.ts barrel, which only re-exports the builder's public API (buildGraph, collectFiles, etc). Adding a generic, domain-agnostic statement-cache helper to that barrel's surface for a features/ consumer would be the first such exception; shared/ already hosts this class of cross-cutting, domain-free utility (paginate.ts, globs.ts, sleep.ts). docs check acknowledged: pure internal dedup refactor, no new feature, language, command, or architecture surface to document. Fixes #1767 Impact: 6 functions changed, 26 affected
Greptile SummaryThis PR extracts a duplicate chunk-size-keyed prepared-statement cache pattern into
Confidence Score: 5/5Safe to merge — no SQL, chunk sizes, or public API signatures change; behavior is identical in both call sites. All three changed files are consistent with each other. The two exported functions compose cleanly, types from No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[builder/helpers.ts\ngetNodeStmt / getEdgeStmt / getExportStmt] -->|calls| B[getOrCreatePerDbChunkStmt]
C[features/structure.ts\nbatchUpdateRoles] -->|calls| D[getOrCreateChunkStmt]
B -->|delegates to| D
D -->|cache miss: db.prepare| E[(SQLite DB)]
B -->|cache miss: creates per-db Map| F[(WeakMap keyed by db)]
F --> D
subgraph shared/chunked-stmt-cache.ts
B
D
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[builder/helpers.ts\ngetNodeStmt / getEdgeStmt / getExportStmt] -->|calls| B[getOrCreatePerDbChunkStmt]
C[features/structure.ts\nbatchUpdateRoles] -->|calls| D[getOrCreateChunkStmt]
B -->|delegates to| D
D -->|cache miss: db.prepare| E[(SQLite DB)]
B -->|cache miss: creates per-db Map| F[(WeakMap keyed by db)]
F --> D
subgraph shared/chunked-stmt-cache.ts
B
D
end
Reviews (1): Last reviewed commit: "refactor: share chunked statement-cache ..." | Re-trigger Greptile |
Codegraph Impact Analysis6 functions changed → 26 callers affected across 6 files
|
Summary
batchUpdateRoles(features/structure.ts) duplicated the same chunk-size-keyed prepared-statement cache shape already deduped inbuilder/helpers.ts'sgetOrCreateBatchStmt(used bygetNodeStmt/getEdgeStmt/getExportStmt).domain/graph/builder/import directly from files inside it (everything goes through thedomain/graph/builder.tsbarrel, which only re-exports the builder's public API) — a chunk-keyed statement cache has nothing to do with "graph building" as a domain concern, so extending that barrel would be a boundary exception for a domain-agnostic utility.shared/already hosts the single-statement analog (db/repository/cached-stmt.ts) and other cross-cutting DB/type utilities.src/shared/chunked-stmt-cache.ts(getOrCreateChunkStmt+ the per-dbWeakMapwrappergetOrCreatePerDbChunkStmt), refactoredbuilder/helpers.ts's existing usage to go through it too, and adopted it inbatchUpdateRoles— one real implementation now, not two similar ones.Closes #1767
Test plan
npm test— full suite green (3542 passed, 0 failed)npm run lint/npm run typecheck— cleanWeakMaps stay persisted across calls; structure's cache stays a fresh per-callMap) — pure refactor, no behavior changecodegraph diff-impact --staged -T— 6 functions touched, 26 transitive callers, consistent with an internal-only refactor with no public signature changesStacked on #1889 (base branch
fix/issue-1766-defineproperty-kind-filter-parity) — only the shared/builder/structure diff is this issue's change.