| 1517 | /* ── Combined scoring ────────────────────────────────────────────── */ |
| 1518 | |
| 1519 | float cbm_sem_proximity(const char *path_a, const char *path_b) { |
| 1520 | if (!path_a || !path_b) { |
| 1521 | return CBM_SEM_UNIT_POS; |
| 1522 | } |
| 1523 | /* Count shared directory components */ |
| 1524 | int shared = 0; |
| 1525 | int total_a = 0; |
| 1526 | int total_b = 0; |
| 1527 | const char *a = path_a; |
| 1528 | const char *b = path_b; |
| 1529 | while (*a && *b && *a == *b) { |
| 1530 | if (*a == '/') { |
| 1531 | shared++; |
| 1532 | } |
| 1533 | a++; |
| 1534 | b++; |
| 1535 | } |
| 1536 | for (const char *p = path_a; *p; p++) { |
| 1537 | if (*p == '/') { |
| 1538 | total_a++; |
| 1539 | } |
| 1540 | } |
| 1541 | for (const char *p = path_b; *p; p++) { |
| 1542 | if (*p == '/') { |
| 1543 | total_b++; |
| 1544 | } |
| 1545 | } |
| 1546 | int max_total = total_a > total_b ? total_a : total_b; |
| 1547 | if (max_total == 0) { |
| 1548 | return CBM_SEM_UNIT_POS; |
| 1549 | } |
| 1550 | float ratio = (float)shared / (float)max_total; |
| 1551 | /* Same file = 1.10, same dir = 1.05, distant = 1.00 */ |
| 1552 | return CBM_SEM_UNIT_POS + (ratio * CBM_SEM_PROX_MAX_BOOST); |
| 1553 | } |
| 1554 | |
| 1555 | /* Cosine similarity for small float arrays (AST profile). */ |
| 1556 | static float small_cosine(const float *a, const float *b, int dims) { |
no outgoing calls
no test coverage detected