diff --git a/internal/cbm/lsp/c_lsp.c b/internal/cbm/lsp/c_lsp.c index 77736a4f8..c5991561e 100644 --- a/internal/cbm/lsp/c_lsp.c +++ b/internal/cbm/lsp/c_lsp.c @@ -2818,10 +2818,10 @@ static const CBMRegisteredFunc *c_lookup_member_depth(CLSPContext *ctx, const ch const char *shortn = dot ? dot + 1 : type_qn; size_t slen = strlen(shortn); const char *best_qn = NULL; - CBMTypeNameIter it; + CBMTypeShortIter it; cbm_registry_types_by_short_name(ctx->registry, shortn, &it); int i; - while ((i = cbm_type_name_iter_next(&it)) >= 0) { + while ((i = cbm_type_short_iter_next(&it)) >= 0) { const char *q = ctx->registry->types[i].qualified_name; if (!q) { continue; diff --git a/internal/cbm/lsp/type_registry.c b/internal/cbm/lsp/type_registry.c index c0136b7ed..30c551899 100644 --- a/internal/cbm/lsp/type_registry.c +++ b/internal/cbm/lsp/type_registry.c @@ -299,7 +299,7 @@ static void build_ffunc_short_index(CBMTypeRegistry *reg, CBMArena *idx_arena) { } void cbm_registry_types_by_short_name(const CBMTypeRegistry *reg, const char *short_name, - CBMTypeNameIter *out) { + CBMTypeShortIter *out) { out->reg = reg; out->hash = fnv1a(short_name); if (reg->type_qn_buckets && reg->type_qn_bucket_count > 0) { @@ -319,7 +319,7 @@ void cbm_registry_types_by_short_name(const CBMTypeRegistry *reg, const char *sh } } -int cbm_type_name_iter_next(CBMTypeNameIter *it) { +int cbm_type_short_iter_next(CBMTypeShortIter *it) { const CBMTypeRegistry *reg = it->reg; while (it->chain_idx >= 0) { const CBMRegistryHashEntry *e = ®->type_short_entries[it->chain_idx]; @@ -413,42 +413,6 @@ int cbm_free_func_iter_next(CBMFreeFuncIter *it) { return -1; } -void cbm_registry_types_by_short_name(const CBMTypeRegistry *reg, const char *short_name, - CBMTypeShortIter *out) { - out->reg = reg; - out->hash = fnv1a(short_name); - if (reg->type_qn_buckets && reg->type_qn_bucket_count > 0) { - if (reg->type_short_buckets && reg->type_short_bucket_count > 0) { - int slot = (int)(out->hash & (uint64_t)(reg->type_short_bucket_count - 1)); - out->chain_idx = reg->type_short_buckets[slot]; - } else { - out->chain_idx = -1; - } - out->tail_i = reg->type_qn_entry_count; - out->tail_end = reg->type_count; - } else { - out->chain_idx = -1; - out->tail_i = 0; - out->tail_end = reg->type_count; - } -} - -int cbm_type_short_iter_next(CBMTypeShortIter *it) { - const CBMTypeRegistry *reg = it->reg; - while (it->chain_idx >= 0) { - const CBMRegistryHashEntry *e = ®->type_short_entries[it->chain_idx]; - int p = e->payload_index; - uint64_t h = e->hash; - it->chain_idx = e->next_index; - if (h != it->hash) - continue; - return p; - } - if (it->tail_i < it->tail_end) - return it->tail_i++; - return -1; -} - void cbm_registry_methods(const CBMTypeRegistry *reg, const char *receiver_qn, const char *method_name, CBMMethodIter *out) { memset(out, 0, sizeof(*out)); diff --git a/internal/cbm/lsp/type_registry.h b/internal/cbm/lsp/type_registry.h index 074e2bf7c..7f7737448 100644 --- a/internal/cbm/lsp/type_registry.h +++ b/internal/cbm/lsp/type_registry.h @@ -119,6 +119,7 @@ typedef struct CBMTypeRegistry { int *type_short_buckets; CBMRegistryHashEntry *type_short_entries; int type_short_bucket_count; + int type_short_entry_count; // Embedded-type index: fnv1a(bare last-'.'-segment of each embedded_type) -> chain // of TYPE indices declaring it. payload_index = type index (a type may appear once // per embedded entry; consumers dedup adjacent same-type via the iterator). @@ -128,10 +129,6 @@ typedef struct CBMTypeRegistry { int type_embed_entry_count; // Free-function short-name index: fnv1a(short_name) -> chain of FREE-function // (receiver_type==NULL) indices. payload_index = func index. - int *type_short_buckets; - CBMRegistryHashEntry *type_short_entries; - int type_short_bucket_count; - int type_short_entry_count; int *ffunc_short_buckets; CBMRegistryHashEntry *ffunc_short_entries; int ffunc_short_bucket_count; @@ -236,16 +233,19 @@ const CBMRegisteredFunc *cbm_registry_lookup_symbol_by_types(const CBMTypeRegist // any post-finalize tail; otherwise it degrades to the original full scan. Results // preserve ascending registry order. The index is a hash prefilter; callers must // re-check their exact predicate, including tail entries. +// Built by finalize into type_short_buckets. Shared by the C++ short-name lookup +// and by cs_resolve_type_name's step-9 fallback, which scanned type_count per +// unresolved name — quadratic against the shared Tier-2 registry. typedef struct { const CBMTypeRegistry *reg; uint64_t hash; int chain_idx; int tail_i; int tail_end; -} CBMTypeNameIter; +} CBMTypeShortIter; void cbm_registry_types_by_short_name(const CBMTypeRegistry *reg, const char *short_name, - CBMTypeNameIter *out); -int cbm_type_name_iter_next(CBMTypeNameIter *it); + CBMTypeShortIter *out); +int cbm_type_short_iter_next(CBMTypeShortIter *it); // Iterate registry TYPE indices whose embedded_types contain an entry whose BARE // name (last '.'-segment) equals `bare`. On a finalized registry this walks the @@ -278,21 +278,6 @@ typedef struct { int tail_i; int tail_end; } CBMFreeFuncIter; -/* Iterate TYPE indices sharing a short name — the type-side twin of the free- - * function iterator. Built by finalize into type_short_buckets; degrades to a - * full types[] scan on an unfinalized registry (same correctness, old cost). - * Added for cs_resolve_type_name's step-9 fallback, which scanned type_count - * per unresolved name — quadratic against the shared Tier-2 registry. */ -typedef struct { - const CBMTypeRegistry *reg; - uint64_t hash; - int chain_idx; - int tail_i; - int tail_end; -} CBMTypeShortIter; -void cbm_registry_types_by_short_name(const CBMTypeRegistry *reg, const char *short_name, - CBMTypeShortIter *out); -int cbm_type_short_iter_next(CBMTypeShortIter *it); void cbm_registry_free_funcs_by_short_name(const CBMTypeRegistry *reg, const char *short_name, CBMFreeFuncIter *out); diff --git a/tests/test_c_lsp.c b/tests/test_c_lsp.c index a9f3437a6..0ba216ce0 100644 --- a/tests/test_c_lsp.c +++ b/tests/test_c_lsp.c @@ -15331,13 +15331,13 @@ TEST(registry_short_name_indexes) { /* Qualified-name bare segment "Trait": types 0, 4, then the bare-QN type * 5. The iterator is a hash prefilter, so apply the exact predicate before * asserting its order just like production consumers do. */ - CBMTypeNameIter nit; + CBMTypeShortIter nit; cbm_registry_types_by_short_name(®, "Trait", &nit); { int expected[] = {0, 4, 5}; int exact_count = 0; int candidate; - while ((candidate = cbm_type_name_iter_next(&nit)) >= 0) { + while ((candidate = cbm_type_short_iter_next(&nit)) >= 0) { const char *qn = reg.types[candidate].qualified_name; const char *last_dot = qn ? strrchr(qn, '.') : NULL; const char *candidate_short = last_dot ? last_dot + 1 : qn; @@ -15352,7 +15352,7 @@ TEST(registry_short_name_indexes) { { int exact_count = 0; int candidate; - while ((candidate = cbm_type_name_iter_next(&nit)) >= 0) { + while ((candidate = cbm_type_short_iter_next(&nit)) >= 0) { const char *qn = reg.types[candidate].qualified_name; const char *last_dot = qn ? strrchr(qn, '.') : NULL; const char *candidate_short = last_dot ? last_dot + 1 : qn; @@ -15382,7 +15382,7 @@ TEST(registry_short_name_indexes) { int actual; for (;;) { - actual = cbm_type_name_iter_next(&nit); + actual = cbm_type_short_iter_next(&nit); if (actual < 0) break; const char *qn = reg.types[actual].qualified_name; @@ -15437,11 +15437,11 @@ TEST(registry_short_name_indexes) { t.short_name = "Trait"; cbm_registry_add_type(®, t); cbm_registry_types_by_short_name(®, "Trait", &nit); - ASSERT_EQ(cbm_type_name_iter_next(&nit), 0); - ASSERT_EQ(cbm_type_name_iter_next(&nit), 4); - ASSERT_EQ(cbm_type_name_iter_next(&nit), 5); - ASSERT_EQ(cbm_type_name_iter_next(&nit), tail_type_i); - ASSERT_EQ(cbm_type_name_iter_next(&nit), -1); + ASSERT_EQ(cbm_type_short_iter_next(&nit), 0); + ASSERT_EQ(cbm_type_short_iter_next(&nit), 4); + ASSERT_EQ(cbm_type_short_iter_next(&nit), 5); + ASSERT_EQ(cbm_type_short_iter_next(&nit), tail_type_i); + ASSERT_EQ(cbm_type_short_iter_next(&nit), -1); int *saved_type_short_buckets = reg.type_short_buckets; reg.type_short_buckets = NULL; @@ -15449,7 +15449,7 @@ TEST(registry_short_name_indexes) { int fallback_expected[] = {0, 4, 5, tail_type_i}; int fallback_count = 0; int candidate; - while ((candidate = cbm_type_name_iter_next(&nit)) >= 0) { + while ((candidate = cbm_type_short_iter_next(&nit)) >= 0) { const char *qn = reg.types[candidate].qualified_name; const char *last_dot = qn ? strrchr(qn, '.') : NULL; const char *candidate_short = last_dot ? last_dot + 1 : qn; @@ -15479,7 +15479,7 @@ TEST(registry_short_name_indexes) { cbm_registry_types_by_short_name(®, "Trait", &nit); fallback_count = 0; - while ((candidate = cbm_type_name_iter_next(&nit)) >= 0) { + while ((candidate = cbm_type_short_iter_next(&nit)) >= 0) { const char *qn = reg.types[candidate].qualified_name; const char *last_dot = qn ? strrchr(qn, '.') : NULL; const char *candidate_short = last_dot ? last_dot + 1 : qn;