mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
fix(cross-repo): no row count decides which calls are matched
Each of the cross-repo scans -- a project's HTTP_CALLS, async and channel edges, a target's Route templates for fuzzy matching -- stopped after 4,096 rows and treated the rest as not there. A call examined after 4,096 others never got its CROSS_HTTP_CALLS edge even though the target serves its route; which edges existed depended on how many others the project held. No count may decide graph content. The scans now read every row; only a SQLite error counts as failure, as before. The project-cache guards (CR_MAX_PROJECTS, CR_MAX_CACHE_ENTRIES) stay: they fail the run visibly instead of dropping content. cross_repo_scan_bound_counts_examined_rows_not_matches asserted that the 4,097th call stays unmatched; as cross_repo_matches_calls_past_4096_rows it asserts the edge exists, and fails on the bounded scans. None of the 17 infra corpora has 4,096 rows in one of these scans, so their graphs are unchanged. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
1 parent
0a65d1ec80
commit
0ac529f5f4
2 files changed
+19
-32
No files matched your search
@@ -33,7 +33,6 @@ enum {
|
||||
CR_PATH_BUF = 4096,
|
||||
CR_QN_BUF = 512,
|
||||
CR_PROPS_BUF = 2048,
|
||||
CR_MAX_EDGES = 4096,
|
||||
CR_DB_EXT_LEN = 3, /* strlen(".db") */
|
||||
CR_INIT_CAP = 32,
|
||||
CR_MAX_PROJECTS = 4096,
|
||||
@@ -481,9 +480,9 @@ static bool cr_path_matches_template(const char *concrete, const char *templ) {
|
||||
* the route QN into out_qn and return the handler id; returns 0 on no match.
|
||||
*
|
||||
* COST: this scans every Route node of the target project once per unmatched
|
||||
* HTTP_CALLS edge — O(calls × routes) per project pair. Acceptable while both
|
||||
* factors stay small (calls are capped at CR_MAX_EDGES and it only runs for
|
||||
* edges the exact lookup missed); revisit with a prepared template index if
|
||||
* HTTP_CALLS edge — O(calls × routes) per project pair. It only runs for edges
|
||||
* the exact lookup missed; no row count stops a scan (a cap decided which
|
||||
* calls were matched at all); revisit with a prepared template index if
|
||||
* cross-repo matching ever shows up in profiles. (#523) */
|
||||
static int64_t find_route_handler_fuzzy(cbm_store_t *target_store, const char *concrete_path,
|
||||
const char *method, char *out_qn, size_t out_qn_sz,
|
||||
@@ -504,11 +503,8 @@ static int64_t find_route_handler_fuzzy(cbm_store_t *target_store, const char *c
|
||||
return 0;
|
||||
}
|
||||
int64_t found = 0;
|
||||
int scanned = 0;
|
||||
int step_rc = SQLITE_DONE;
|
||||
while (scanned < CR_MAX_EDGES && !cr_cancel_requested(ctx) &&
|
||||
(step_rc = sqlite3_step(s)) == SQLITE_ROW) {
|
||||
scanned++;
|
||||
while (!cr_cancel_requested(ctx) && (step_rc = sqlite3_step(s)) == SQLITE_ROW) {
|
||||
const char *qn = (const char *)sqlite3_column_text(s, 0);
|
||||
if (!qn || strncmp(qn, "__route__", CR_ROUTE_PREFIX_LEN) != 0) {
|
||||
continue;
|
||||
@@ -550,7 +546,7 @@ static int64_t find_route_handler_fuzzy(cbm_store_t *target_store, const char *c
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cr_cancel_requested(ctx) && scanned < CR_MAX_EDGES && step_rc != SQLITE_DONE) {
|
||||
if (!cr_cancel_requested(ctx) && step_rc != SQLITE_DONE) {
|
||||
*failed = true;
|
||||
}
|
||||
if (sqlite3_finalize(s) != SQLITE_OK) {
|
||||
@@ -713,12 +709,9 @@ static cr_match_result_t match_http_routes(cbm_store_t *src_store, const char *s
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
int scanned = 0;
|
||||
int step_rc = SQLITE_DONE;
|
||||
bool failed = false;
|
||||
while (scanned < CR_MAX_EDGES && !cr_cancel_requested(ctx) &&
|
||||
(step_rc = sqlite3_step(s)) == SQLITE_ROW) {
|
||||
scanned++;
|
||||
while (!cr_cancel_requested(ctx) && (step_rc = sqlite3_step(s)) == SQLITE_ROW) {
|
||||
int64_t caller_id = sqlite3_column_int64(s, 0);
|
||||
int64_t route_id = sqlite3_column_int64(s, SKIP_ONE);
|
||||
const char *props = (const char *)sqlite3_column_text(s, PAIR_LEN);
|
||||
@@ -772,7 +765,7 @@ static cr_match_result_t match_http_routes(cbm_store_t *src_store, const char *s
|
||||
|
||||
count++;
|
||||
}
|
||||
if (!failed && !cr_cancel_requested(ctx) && scanned < CR_MAX_EDGES && step_rc != SQLITE_DONE) {
|
||||
if (!failed && !cr_cancel_requested(ctx) && step_rc != SQLITE_DONE) {
|
||||
failed = true;
|
||||
}
|
||||
if (sqlite3_finalize(s) != SQLITE_OK) {
|
||||
@@ -804,12 +797,9 @@ static cr_match_result_t match_async_routes(cbm_store_t *src_store, const char *
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
int scanned = 0;
|
||||
int step_rc = SQLITE_DONE;
|
||||
bool failed = false;
|
||||
while (scanned < CR_MAX_EDGES && !cr_cancel_requested(ctx) &&
|
||||
(step_rc = sqlite3_step(s)) == SQLITE_ROW) {
|
||||
scanned++;
|
||||
while (!cr_cancel_requested(ctx) && (step_rc = sqlite3_step(s)) == SQLITE_ROW) {
|
||||
int64_t caller_id = sqlite3_column_int64(s, 0);
|
||||
int64_t route_id = sqlite3_column_int64(s, SKIP_ONE);
|
||||
const char *props = (const char *)sqlite3_column_text(s, PAIR_LEN);
|
||||
@@ -854,7 +844,7 @@ static cr_match_result_t match_async_routes(cbm_store_t *src_store, const char *
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if (!failed && !cr_cancel_requested(ctx) && scanned < CR_MAX_EDGES && step_rc != SQLITE_DONE) {
|
||||
if (!failed && !cr_cancel_requested(ctx) && step_rc != SQLITE_DONE) {
|
||||
failed = true;
|
||||
}
|
||||
if (sqlite3_finalize(s) != SQLITE_OK) {
|
||||
@@ -969,12 +959,9 @@ static cr_match_result_t match_channels(cbm_store_t *src_store, const char *src_
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
int scanned = 0;
|
||||
int step_rc = SQLITE_DONE;
|
||||
bool failed = false;
|
||||
while (scanned < CR_MAX_EDGES && !cr_cancel_requested(ctx) &&
|
||||
(step_rc = sqlite3_step(s)) == SQLITE_ROW) {
|
||||
scanned++;
|
||||
while (!cr_cancel_requested(ctx) && (step_rc = sqlite3_step(s)) == SQLITE_ROW) {
|
||||
const char *channel_name = (const char *)sqlite3_column_text(s, SKIP_ONE);
|
||||
const char *channel_qn = (const char *)sqlite3_column_text(s, PAIR_LEN);
|
||||
if (!channel_name || !channel_qn) {
|
||||
@@ -1007,7 +994,7 @@ static cr_match_result_t match_channels(cbm_store_t *src_store, const char *src_
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (!failed && !cr_cancel_requested(ctx) && scanned < CR_MAX_EDGES && step_rc != SQLITE_DONE) {
|
||||
if (!failed && !cr_cancel_requested(ctx) && step_rc != SQLITE_DONE) {
|
||||
failed = true;
|
||||
}
|
||||
if (sqlite3_finalize(s) != SQLITE_OK) {
|
||||
@@ -1084,12 +1071,9 @@ static cr_match_result_t match_typed_routes(cbm_store_t *src_store, const char *
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
int scanned = 0;
|
||||
int step_rc = SQLITE_DONE;
|
||||
bool failed = false;
|
||||
while (scanned < CR_MAX_EDGES && !cr_cancel_requested(ctx) &&
|
||||
(step_rc = sqlite3_step(s)) == SQLITE_ROW) {
|
||||
scanned++;
|
||||
while (!cr_cancel_requested(ctx) && (step_rc = sqlite3_step(s)) == SQLITE_ROW) {
|
||||
int64_t caller_id = sqlite3_column_int64(s, 0);
|
||||
int64_t route_id = sqlite3_column_int64(s, SKIP_ONE);
|
||||
const char *props = (const char *)sqlite3_column_text(s, PAIR_LEN);
|
||||
@@ -1139,7 +1123,7 @@ static cr_match_result_t match_typed_routes(cbm_store_t *src_store, const char *
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if (!failed && !cr_cancel_requested(ctx) && scanned < CR_MAX_EDGES && step_rc != SQLITE_DONE) {
|
||||
if (!failed && !cr_cancel_requested(ctx) && step_rc != SQLITE_DONE) {
|
||||
failed = true;
|
||||
}
|
||||
if (sqlite3_finalize(s) != SQLITE_OK) {
|
||||
|
||||
@@ -574,7 +574,10 @@ static bool cross_repo_seed_bounded_scan(const cross_repo_fixture_t *fixture,
|
||||
return ok;
|
||||
}
|
||||
|
||||
TEST(cross_repo_scan_bound_counts_examined_rows_not_matches) {
|
||||
/* No row count decides which calls are matched: the scans stopped after 4,096
|
||||
* rows, so a call examined after 4,096 others never got its CROSS_HTTP_CALLS
|
||||
* edge even though the target serves its route. */
|
||||
TEST(cross_repo_matches_calls_past_4096_rows) {
|
||||
cross_repo_fixture_t fixture;
|
||||
bool setup = cross_repo_fixture_begin(&fixture) &&
|
||||
cross_repo_seed_bounded_scan(&fixture, "bounded-source", "bounded-target");
|
||||
@@ -589,7 +592,7 @@ TEST(cross_repo_scan_bound_counts_examined_rows_not_matches) {
|
||||
|
||||
ASSERT_FALSE(result.failed);
|
||||
ASSERT_EQ(result.projects_scanned, 1);
|
||||
ASSERT_EQ(result.http_edges, 0);
|
||||
ASSERT_EQ(result.http_edges, 1);
|
||||
PASS();
|
||||
}
|
||||
|
||||
@@ -952,7 +955,7 @@ SUITE(cross_repo) {
|
||||
RUN_TEST(cross_repo_named_pre768_target_fails_before_cleanup_issue2133);
|
||||
RUN_TEST(cross_repo_status_distinguishes_never_run_from_ran_without_links);
|
||||
RUN_TEST(cross_repo_wildcard_reports_skipped_pre768_store);
|
||||
RUN_TEST(cross_repo_scan_bound_counts_examined_rows_not_matches);
|
||||
RUN_TEST(cross_repo_matches_calls_past_4096_rows);
|
||||
RUN_TEST(cross_repo_propagates_delete_failure);
|
||||
RUN_TEST(cross_repo_failed_bidirectional_insert_is_not_counted);
|
||||
RUN_TEST(cross_repo_cancel_mid_run_keeps_completed_target_and_stops_before_later_target);
|
||||
|
||||
Reference in new issue
Block a user