Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions internal/cbm/lsp/c_lsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
40 changes: 2 additions & 38 deletions internal/cbm/lsp/type_registry.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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 = &reg->type_short_entries[it->chain_idx];
Expand Down Expand Up @@ -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 = &reg->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));
Expand Down
29 changes: 7 additions & 22 deletions internal/cbm/lsp/type_registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
22 changes: 11 additions & 11 deletions tests/test_c_lsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(&reg, "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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -15437,19 +15437,19 @@ TEST(registry_short_name_indexes) {
t.short_name = "Trait";
cbm_registry_add_type(&reg, t);
cbm_registry_types_by_short_name(&reg, "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;
cbm_registry_types_by_short_name(&reg, "Trait", &nit);
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;
Expand Down Expand Up @@ -15479,7 +15479,7 @@ TEST(registry_short_name_indexes) {

cbm_registry_types_by_short_name(&reg, "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;
Expand Down
Loading