feat: Optimize reference resolution with indexed queries and built-in filtering

Replaces O(n) file scanning with O(log n) indexed database lookups by adding getAllNodeNames query and caching node lookups by name/qualified name. Pre-filters references against known symbol names to skip expensive resolution for non-existent symbols. Consolidates Go resolver helper functions into a unified resolveByNameAndKind function and moves built-in symbol sets to module-level constants for better performance.
This commit is contained in:
Colby McHenry
2026-04-06 10:45:14 -05:00
parent cacc213f09
commit d256af3a23
3 changed files with 220 additions and 159 deletions
+12
View File
@@ -178,6 +178,7 @@ export class QueryBuilder {
getUnresolvedCount?: SqliteStatement;
getUnresolvedBatch?: SqliteStatement;
getAllFilePaths?: SqliteStatement;
getAllNodeNames?: SqliteStatement;
} = {};
constructor(db: SqliteDatabase) {
@@ -976,6 +977,17 @@ export class QueryBuilder {
return rows.map((r) => r.path);
}
/**
* Get all distinct node names (lightweight — just name strings for pre-filtering)
*/
getAllNodeNames(): string[] {
if (!this.stmts.getAllNodeNames) {
this.stmts.getAllNodeNames = this.db.prepare('SELECT DISTINCT name FROM nodes');
}
const rows = this.stmts.getAllNodeNames.all() as Array<{ name: string }>;
return rows.map((r) => r.name);
}
/**
* Get unresolved references scoped to specific file paths.
* Uses the idx_unresolved_file_path index for efficient lookup.