mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-14 15:59:57 +08:00
perf(graph-buffer): keep indexes for containment delete
Preserve graph indexes while deleting the target project row in cbm_gbuf_flush_to_store(), then drop/recreate them only around the replacement insert workload. This keeps SQLite's ON DELETE CASCADE from scanning large child tables without FK lookup indexes during incremental containment publishes. Adds opt-in CBM_PROFILE phase timings for gbuf_flush using the existing structured profiling path; no MCP stdout output and no new heap ownership. Validation: product build rc=0; ASan/UBSan graph_buffer 66/66; ASan/UBSan pipeline 301/301; source-safety rc=0. Profiled self-dogfood one_source_file improved from 1.51x to 3.52x speedup, with incremental.flush down from 13366 ms to 3914 ms and delete_project down from 10206 ms to 633 ms. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
This commit is contained in:
@@ -2034,38 +2034,51 @@ int cbm_gbuf_flush_to_store(cbm_gbuf_t *gb, cbm_store_t *store) {
|
||||
return CBM_NOT_FOUND;
|
||||
}
|
||||
|
||||
CBM_PROF_START(t_flush_total);
|
||||
int64_t *temp_to_real = NULL;
|
||||
const char *phase = "begin_bulk";
|
||||
CBM_PROF_START(t_begin_bulk);
|
||||
int rc = cbm_store_begin_bulk(store);
|
||||
CBM_PROF_END("gbuf_flush", "0_begin_bulk", t_begin_bulk);
|
||||
if (rc != CBM_STORE_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
phase = "begin";
|
||||
CBM_PROF_START(t_begin);
|
||||
rc = cbm_store_begin(store);
|
||||
CBM_PROF_END("gbuf_flush", "1_begin", t_begin);
|
||||
if (rc != CBM_STORE_OK) {
|
||||
(void)cbm_store_end_bulk(store);
|
||||
return rc;
|
||||
}
|
||||
|
||||
phase = "drop_indexes";
|
||||
rc = cbm_store_drop_indexes(store);
|
||||
if (rc != CBM_STORE_OK) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Delete the project row so ON DELETE CASCADE clears graph and freshness
|
||||
* tables owned by this project before the replacement graph is inserted.
|
||||
* This preserves sibling projects, including dependency subprojects; caller
|
||||
* code still owns contentless FTS rebuilds and user-authored project memory. */
|
||||
phase = "delete_project";
|
||||
CBM_PROF_START(t_delete_project);
|
||||
rc = cbm_store_delete_project(store, gb->project);
|
||||
CBM_PROF_END("gbuf_flush", "2_delete_project", t_delete_project);
|
||||
if (rc != CBM_STORE_OK) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Keep indexes during the cascade delete above: SQLite uses the child-table
|
||||
* FK indexes to avoid scanning the whole graph. Drop them only for inserts. */
|
||||
phase = "drop_indexes";
|
||||
CBM_PROF_START(t_drop_indexes);
|
||||
rc = cbm_store_drop_indexes(store);
|
||||
CBM_PROF_END("gbuf_flush", "3_drop_indexes", t_drop_indexes);
|
||||
if (rc != CBM_STORE_OK) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
phase = "upsert_project";
|
||||
CBM_PROF_START(t_upsert_project);
|
||||
rc = cbm_store_upsert_project(store, gb->project, gb->root_path);
|
||||
CBM_PROF_END("gbuf_flush", "4_upsert_project", t_upsert_project);
|
||||
if (rc != CBM_STORE_OK) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -2082,6 +2095,7 @@ int cbm_gbuf_flush_to_store(cbm_gbuf_t *gb, cbm_store_t *store) {
|
||||
}
|
||||
|
||||
phase = "upsert_nodes";
|
||||
CBM_PROF_START(t_upsert_nodes);
|
||||
for (int i = 0; i < gb->nodes.count; i++) {
|
||||
cbm_gbuf_node_t *n = gb->nodes.items[i];
|
||||
|
||||
@@ -2109,9 +2123,11 @@ int cbm_gbuf_flush_to_store(cbm_gbuf_t *gb, cbm_store_t *store) {
|
||||
temp_to_real[n->id] = real_id;
|
||||
}
|
||||
}
|
||||
CBM_PROF_END_N("gbuf_flush", "5_upsert_nodes", t_upsert_nodes, gb->nodes.count);
|
||||
|
||||
/* Insert all edges with remapped IDs */
|
||||
phase = "insert_edges";
|
||||
CBM_PROF_START(t_insert_edges);
|
||||
for (int i = 0; i < gb->edges.count; i++) {
|
||||
cbm_gbuf_edge_t *e = gb->edges.items[i];
|
||||
int64_t real_src = (e->source_id < max_temp_id) ? temp_to_real[e->source_id] : 0;
|
||||
@@ -2132,9 +2148,12 @@ int cbm_gbuf_flush_to_store(cbm_gbuf_t *gb, cbm_store_t *store) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
CBM_PROF_END_N("gbuf_flush", "6_insert_edges", t_insert_edges, gb->edges.count);
|
||||
|
||||
phase = "create_indexes";
|
||||
CBM_PROF_START(t_create_indexes);
|
||||
rc = cbm_store_create_indexes(store);
|
||||
CBM_PROF_END("gbuf_flush", "7_create_indexes", t_create_indexes);
|
||||
if (rc != CBM_STORE_OK) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -2144,11 +2163,16 @@ int cbm_gbuf_flush_to_store(cbm_gbuf_t *gb, cbm_store_t *store) {
|
||||
goto fail;
|
||||
}
|
||||
phase = "commit";
|
||||
CBM_PROF_START(t_commit);
|
||||
rc = cbm_store_commit(store);
|
||||
CBM_PROF_END("gbuf_flush", "8_commit", t_commit);
|
||||
if (rc != CBM_STORE_OK) {
|
||||
goto fail;
|
||||
}
|
||||
CBM_PROF_START(t_end_bulk);
|
||||
int end_bulk_rc = cbm_store_end_bulk(store);
|
||||
CBM_PROF_END("gbuf_flush", "9_end_bulk", t_end_bulk);
|
||||
CBM_PROF_END_N("gbuf_flush", "TOTAL", t_flush_total, gb->nodes.count + gb->edges.count);
|
||||
|
||||
free(temp_to_real);
|
||||
return end_bulk_rc == CBM_STORE_OK ? 0 : end_bulk_rc;
|
||||
|
||||
Reference in New Issue
Block a user