MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / cbm_store_bfs_multi

Function cbm_store_bfs_multi

src/store/store.c:4686–4807  ·  view source on GitHub ↗

Multi-source BFS: one recursive CTE anchored on ALL seeds (via a temp * table — never a per-seed loop, which re-walks overlapping hub subgraphs * seed_count times). Semantics for impact analysis: * - shortest-path MIN(hop) across the whole seed set; * - SEEDS ARE EXCLUDED from the result: a seed reached from another seed * (changed files call each other constantly) is not "impact"; *

Source from the content-addressed store, hash-verified

4684 * - canonical (hop, id) order.
4685 * No root node and no edge collection — impact wants the reached set. */
4686int cbm_store_bfs_multi(cbm_store_t *s, const int64_t *seed_ids, int seed_count,
4687 const char *direction, const char **edge_types, int edge_type_count,
4688 int max_depth, int max_results, cbm_traverse_result_t *out,
4689 bool *truncated) {
4690 memset(out, 0, sizeof(*out));
4691 if (truncated) {
4692 *truncated = false;
4693 }
4694 if (!s || !s->db || !seed_ids || seed_count <= 0) {
4695 return CBM_STORE_ERR;
4696 }
4697
4698 if (sqlite3_exec(s->db,
4699 "CREATE TEMP TABLE IF NOT EXISTS bfs_seeds (id INTEGER PRIMARY KEY);"
4700 "DELETE FROM bfs_seeds;",
4701 NULL, NULL, NULL) != SQLITE_OK) {
4702 store_set_error_sqlite(s, "bfs_multi seeds");
4703 return CBM_STORE_ERR;
4704 }
4705 sqlite3_stmt *ins = NULL;
4706 if (sqlite3_prepare_v2(s->db, "INSERT OR IGNORE INTO bfs_seeds(id) VALUES (?1)", CBM_NOT_FOUND,
4707 &ins, NULL) != SQLITE_OK) {
4708 store_set_error_sqlite(s, "bfs_multi seed insert");
4709 return CBM_STORE_ERR;
4710 }
4711 for (int i = 0; i < seed_count; i++) {
4712 sqlite3_reset(ins);
4713 sqlite3_bind_int64(ins, SKIP_ONE, seed_ids[i]);
4714 (void)sqlite3_step(ins);
4715 }
4716 sqlite3_finalize(ins);
4717
4718 char types_clause[CBM_SZ_512];
4719 bfs_build_types_clause(edge_type_count, types_clause, (int)sizeof(types_clause));
4720
4721 const char *join_cond;
4722 const char *next_id;
4723 bool is_inbound = (direction != NULL) && (strcmp(direction, "inbound") == 0);
4724 if (is_inbound) {
4725 join_cond = "e.target_id = bfs.node_id";
4726 next_id = "e.source_id";
4727 } else {
4728 join_cond = "e.source_id = bfs.node_id";
4729 next_id = "e.target_id";
4730 }
4731
4732 char sql[CBM_SZ_4K];
4733 snprintf(sql, sizeof(sql),
4734 "WITH RECURSIVE bfs(node_id, hop) AS ("
4735 " SELECT id, 0 FROM bfs_seeds"
4736 " UNION"
4737 " SELECT %s, bfs.hop + 1"
4738 " FROM bfs"
4739 " JOIN edges e ON %s"
4740 " WHERE e.type IN (%s) AND bfs.hop < %d"
4741 ")"
4742 "SELECT n.id, n.project, n.label, n.name, n.qualified_name, "
4743 "n.file_path, n.start_line, n.end_line, n.properties, MIN(bfs.hop) AS hop "

Callers 2

handle_detect_changesFunction · 0.85
test_integration.cFile · 0.85

Calls 6

store_set_error_sqliteFunction · 0.85
bfs_build_types_clauseFunction · 0.85
bind_textFunction · 0.85
safe_reallocFunction · 0.85
scan_nodeFunction · 0.85
cbm_node_free_fieldsFunction · 0.85

Tested by

no test coverage detected