Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion crates/codegraph-core/src/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,25 @@ fn compute_file_metrics(
}
}

// Batch-load import counts per file from DB (distinct imported files,
// matching the fast-path semantics in update_changed_file_metrics)
let mut import_counts: HashMap<String, i64> = HashMap::new();
if let Ok(mut stmt) = tx.prepare(
"SELECT n1.file, COUNT(DISTINCT n2.file) FROM edges e \
JOIN nodes n1 ON e.source_id = n1.id \
JOIN nodes n2 ON e.target_id = n2.id \
WHERE e.kind = 'imports' \
GROUP BY n1.file",
) {
if let Ok(rows) = stmt.query_map([], |row| {
Ok((row.get::<_, String>(0)?, row.get::<_, i64>(1)?))
}) {
for row in rows.flatten() {
import_counts.insert(row.0, row.1);
}
}
}

{
let mut upsert = match tx.prepare(
"INSERT OR REPLACE INTO node_metrics \
Expand All @@ -607,7 +626,7 @@ fn compute_file_metrics(

let line_count = line_count_map.get(rel_path).copied().unwrap_or(0);
let symbol_count = symbol_counts.get(rel_path).copied().unwrap_or(0);
let import_count = symbols.imports.len() as i64;
let import_count = import_counts.get(rel_path).copied().unwrap_or(0);
let export_count = symbols.exports.len() as i64;
let fan_in = fan_in_map.get(rel_path).copied().unwrap_or(0);
let fan_out = fan_out_map.get(rel_path).copied().unwrap_or(0);
Expand Down
18 changes: 17 additions & 1 deletion src/features/structure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,22 @@ function computeFileMetrics(
fanOutMap: Map<string, number>,
): void {
db.transaction(() => {
// Batch-load import counts per file (distinct imported files,
// matching the fast-path semantics in updateChangedFileMetrics).
// Runs inside the transaction for parity with the Rust path.
const importCountMap = new Map<string, number>();
for (const row of db
.prepare(
`SELECT n1.file AS src, COUNT(DISTINCT n2.file) AS cnt FROM edges e
JOIN nodes n1 ON e.source_id = n1.id
JOIN nodes n2 ON e.target_id = n2.id
WHERE e.kind = 'imports'
GROUP BY n1.file`,
)
.all() as { src: string; cnt: number }[]) {
importCountMap.set(row.src, row.cnt);
}

for (const [relPath, symbols] of fileSymbols) {
const fileRow = getNodeIdStmt.get(relPath, 'file', relPath, 0);
if (!fileRow) continue;
Expand All @@ -180,7 +196,7 @@ function computeFileMetrics(
symbolCount++;
}
}
const importCount = symbols.imports.length;
const importCount = importCountMap.get(relPath) || 0;
const exportCount = symbols.exports.length;
const fanIn = fanInMap.get(relPath) || 0;
const fanOut = fanOutMap.get(relPath) || 0;
Expand Down
Loading