Port performance improvements from PR #15
- SQLite performance pragmas: synchronous=NORMAL, 64MB cache, memory temp store, 256MB mmap (safe with WAL mode) - Batch insert for unresolved refs: single transaction instead of N individual inserts per file - Symbol caching (warmCaches): pre-load all nodes into memory maps before resolution, eliminating repeated SQLite queries per ref - Async file I/O: fs.stat/readFile in indexFile() are now non-blocking - Denormalize filePath/language onto UnresolvedReference: avoids N node lookups during resolution, with schema migration v2 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
e07250ed60
commit
d80900f653
+47
-2
@@ -73,6 +73,8 @@ interface UnresolvedRefRow {
|
||||
reference_kind: string;
|
||||
line: number;
|
||||
col: number;
|
||||
file_path: string | null;
|
||||
language: string | null;
|
||||
candidates: string | null;
|
||||
}
|
||||
|
||||
@@ -422,6 +424,14 @@ export class QueryBuilder {
|
||||
return rows.map(rowToNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all nodes in the database
|
||||
*/
|
||||
getAllNodes(): Node[] {
|
||||
const rows = this.db.prepare('SELECT * FROM nodes').all() as NodeRow[];
|
||||
return rows.map(rowToNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search nodes by name using FTS with fallback to LIKE for better matching
|
||||
*
|
||||
@@ -778,8 +788,8 @@ export class QueryBuilder {
|
||||
insertUnresolvedRef(ref: UnresolvedReference): void {
|
||||
if (!this.stmts.insertUnresolved) {
|
||||
this.stmts.insertUnresolved = this.db.prepare(`
|
||||
INSERT INTO unresolved_refs (from_node_id, reference_name, reference_kind, line, col, candidates)
|
||||
VALUES (@fromNodeId, @referenceName, @referenceKind, @line, @col, @candidates)
|
||||
INSERT INTO unresolved_refs (from_node_id, reference_name, reference_kind, line, col, file_path, language, candidates)
|
||||
VALUES (@fromNodeId, @referenceName, @referenceKind, @line, @col, @filePath, @language, @candidates)
|
||||
`);
|
||||
}
|
||||
|
||||
@@ -789,10 +799,41 @@ export class QueryBuilder {
|
||||
referenceKind: ref.referenceKind,
|
||||
line: ref.line,
|
||||
col: ref.column,
|
||||
filePath: ref.filePath ?? null,
|
||||
language: ref.language ?? null,
|
||||
candidates: ref.candidates ? JSON.stringify(ref.candidates) : null,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert multiple unresolved references in a single transaction
|
||||
*/
|
||||
insertUnresolvedRefsBatch(refs: UnresolvedReference[]): void {
|
||||
if (refs.length === 0) return;
|
||||
|
||||
if (!this.stmts.insertUnresolved) {
|
||||
this.stmts.insertUnresolved = this.db.prepare(`
|
||||
INSERT INTO unresolved_refs (from_node_id, reference_name, reference_kind, line, col, file_path, language, candidates)
|
||||
VALUES (@fromNodeId, @referenceName, @referenceKind, @line, @col, @filePath, @language, @candidates)
|
||||
`);
|
||||
}
|
||||
|
||||
this.db.transaction(() => {
|
||||
for (const ref of refs) {
|
||||
this.stmts.insertUnresolved!.run({
|
||||
fromNodeId: ref.fromNodeId,
|
||||
referenceName: ref.referenceName,
|
||||
referenceKind: ref.referenceKind,
|
||||
line: ref.line,
|
||||
col: ref.column,
|
||||
filePath: ref.filePath ?? null,
|
||||
language: ref.language ?? null,
|
||||
candidates: ref.candidates ? JSON.stringify(ref.candidates) : null,
|
||||
});
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete unresolved references from a node
|
||||
*/
|
||||
@@ -821,6 +862,8 @@ export class QueryBuilder {
|
||||
referenceKind: row.reference_kind as EdgeKind,
|
||||
line: row.line,
|
||||
column: row.col,
|
||||
filePath: row.file_path ?? undefined,
|
||||
language: (row.language as Language) ?? undefined,
|
||||
candidates: row.candidates ? safeJsonParse<string[]>(row.candidates, []) : undefined,
|
||||
}));
|
||||
}
|
||||
@@ -836,6 +879,8 @@ export class QueryBuilder {
|
||||
referenceKind: row.reference_kind as EdgeKind,
|
||||
line: row.line,
|
||||
column: row.col,
|
||||
filePath: row.file_path ?? undefined,
|
||||
language: (row.language as Language) ?? undefined,
|
||||
candidates: row.candidates ? safeJsonParse<string[]>(row.candidates, []) : undefined,
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user