enum value filtering / lookup cache

This commit is contained in:
Ryan Fleury
2025-05-07 15:46:59 -07:00
parent e7a4f407bb
commit 80f1a8b7ba
4 changed files with 256 additions and 5 deletions
+2
View File
@@ -650,6 +650,8 @@ e_select_base_ctx(E_BaseCtx *ctx)
e_cache->cons_key_slots = push_array(e_cache->arena, E_ConsTypeSlot, e_cache->cons_key_slots_count);
e_cache->member_cache_slots_count = 256;
e_cache->member_cache_slots = push_array(e_cache->arena, E_MemberCacheSlot, e_cache->member_cache_slots_count);
e_cache->enum_val_cache_slots_count = 256;
e_cache->enum_val_cache_slots = push_array(e_cache->arena, E_EnumValCacheSlot, e_cache->enum_val_cache_slots_count);
e_cache->type_cache_slots_count = 1024;
e_cache->type_cache_slots = push_array(e_cache->arena, E_TypeCacheSlot, e_cache->type_cache_slots_count);
e_cache->file_type_key = e_type_key_cons(.kind = E_TypeKind_Set,
+68
View File
@@ -426,6 +426,21 @@ struct E_EnumVal
U64 val;
};
typedef struct E_EnumValNode E_EnumValNode;
struct E_EnumValNode
{
E_EnumValNode *next;
E_EnumVal v;
};
typedef struct E_EnumValList E_EnumValList;
struct E_EnumValList
{
E_EnumValNode *first;
E_EnumValNode *last;
U64 count;
};
typedef struct E_EnumValArray E_EnumValArray;
struct E_EnumValArray
{
@@ -794,6 +809,55 @@ struct E_MemberCacheSlot
E_MemberCacheNode *last;
};
//- rjf: enum val lookup cache types
typedef struct E_EnumValHashNode E_EnumValHashNode;
struct E_EnumValHashNode
{
E_EnumValHashNode *next;
U64 val_idx;
};
typedef struct E_EnumValHashSlot E_EnumValHashSlot;
struct E_EnumValHashSlot
{
E_EnumValHashNode *first;
E_EnumValHashNode *last;
};
typedef struct E_EnumValFilterNode E_EnumValFilterNode;
struct E_EnumValFilterNode
{
E_EnumValFilterNode *next;
String8 filter;
E_EnumValArray vals_filtered;
};
typedef struct E_EnumValFilterSlot E_EnumValFilterSlot;
struct E_EnumValFilterSlot
{
E_EnumValFilterNode *first;
E_EnumValFilterNode *last;
};
typedef struct E_EnumValCacheNode E_EnumValCacheNode;
struct E_EnumValCacheNode
{
E_EnumValCacheNode *next;
E_TypeKey key;
U64 val_hash_slots_count;
E_EnumValHashSlot *val_hash_slots;
U64 val_filter_slots_count;
E_EnumValFilterSlot *val_filter_slots;
};
typedef struct E_EnumValCacheSlot E_EnumValCacheSlot;
struct E_EnumValCacheSlot
{
E_EnumValCacheNode *first;
E_EnumValCacheNode *last;
};
//- rjf: used expression map
typedef struct E_UsedExprNode E_UsedExprNode;
@@ -966,6 +1030,10 @@ struct E_Cache
U64 member_cache_slots_count;
E_MemberCacheSlot *member_cache_slots;
//- rjf: [types] enum val cache table
U64 enum_val_cache_slots_count;
E_EnumValCacheSlot *enum_val_cache_slots;
//- rjf: [types] unpacked type cache
U64 type_cache_slots_count;
E_TypeCacheSlot *type_cache_slots;
+171 -5
View File
@@ -222,6 +222,34 @@ e_member_array_from_list(Arena *arena, E_MemberList *list)
return array;
}
////////////////////////////////
//~ rjf: Enum Value Functions
internal void
e_enum_val_list_push(Arena *arena, E_EnumValList *list, E_EnumVal *enum_val)
{
E_EnumValNode *n = push_array(arena, E_EnumValNode, 1);
MemoryCopyStruct(&n->v, enum_val);
SLLQueuePush(list->first, list->last, n);
list->count += 1;
}
internal E_EnumValArray
e_enum_val_array_from_list(Arena *arena, E_EnumValList *list)
{
E_EnumValArray array = {0};
array.count = list->count;
array.v = push_array(arena, E_EnumVal, array.count);
{
U64 idx = 0;
for(E_EnumValNode *n = list->first; n != 0; n = n->next, idx += 1)
{
MemoryCopyStruct(&array.v[idx], &n->v);
}
}
return array;
}
////////////////////////////////
//~ rjf: Type Operation Functions
@@ -1992,6 +2020,8 @@ e_type_from_key(E_TypeKey key)
return type;
}
//- rjf: member lookups
internal E_MemberCacheNode *
e_member_cache_node_from_type_key(E_TypeKey key)
{
@@ -2111,6 +2141,141 @@ e_type_member_from_key_name__cached(E_TypeKey key, String8 name)
return result;
}
//- rjf: enum val lookups
internal E_EnumValCacheNode *
e_enum_val_cache_node_from_type_key(E_TypeKey key)
{
U64 hash = e_hash_from_string(5381, str8_struct(&key));
U64 slot_idx = hash%e_cache->enum_val_cache_slots_count;
E_EnumValCacheSlot *slot = &e_cache->enum_val_cache_slots[slot_idx];
E_EnumValCacheNode *node = 0;
for(E_EnumValCacheNode *n = slot->first; n != 0; n = n->next)
{
if(e_type_key_match(n->key, key))
{
node = n;
break;
}
}
if(node == 0)
{
node = push_array(e_cache->arena, E_EnumValCacheNode, 1);
SLLQueuePush(slot->first, slot->last, node);
node->key = key;
E_Type *type = e_type_from_key(key);
if(type->kind == E_TypeKind_Enum)
{
node->val_hash_slots_count = type->count;
node->val_hash_slots = push_array(e_cache->arena, E_EnumValHashSlot, node->val_hash_slots_count);
node->val_filter_slots_count = 16;
node->val_filter_slots = push_array(e_cache->arena, E_EnumValFilterSlot, node->val_filter_slots_count);
for EachIndex(idx, type->count)
{
U64 hash = e_hash_from_string(5381, type->enum_vals[idx].name);
U64 slot_idx = hash%node->val_hash_slots_count;
E_EnumValHashNode *n = push_array(e_cache->arena, E_EnumValHashNode, 1);
SLLQueuePush(node->val_hash_slots[slot_idx].first, node->val_hash_slots[slot_idx].last, n);
n->val_idx = idx;
}
}
}
return node;
}
internal E_EnumValArray
e_type_enum_vals_from_key_filter__cached(E_TypeKey key, String8 filter)
{
E_EnumValArray enum_vals = {0};
E_EnumValCacheNode *node = e_enum_val_cache_node_from_type_key(key);
if(node != 0)
{
if(filter.size == 0)
{
E_Type *type = e_type_from_key(key);
if(type->kind == E_TypeKind_Enum)
{
enum_vals.v = type->enum_vals;
enum_vals.count = type->count;
}
}
else
{
U64 hash = e_hash_from_string(5381, filter);
U64 slot_idx = hash%node->val_filter_slots_count;
E_EnumValFilterSlot *slot = &node->val_filter_slots[slot_idx];
E_EnumValFilterNode *filter_node = 0;
for(E_EnumValFilterNode *n = slot->first; n != 0; n = n->next)
{
if(str8_match(n->filter, filter, 0))
{
filter_node = n;
break;
}
}
if(filter_node == 0)
{
Temp scratch = scratch_begin(0, 0);
filter_node = push_array(e_cache->arena, E_EnumValFilterNode, 1);
filter_node->filter = push_str8_copy(e_cache->arena, filter);
E_Type *type = e_type_from_key(key);
E_EnumValList enum_val_list__filtered = {0};
if(type->kind == E_TypeKind_Enum)
{
for EachIndex(idx, type->count)
{
E_EnumVal *enum_val = &type->enum_vals[idx];
FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, enum_val->name);
if(matches.count == matches.needle_part_count)
{
e_enum_val_list_push(scratch.arena, &enum_val_list__filtered, enum_val);
}
}
}
filter_node->vals_filtered = e_enum_val_array_from_list(e_cache->arena, &enum_val_list__filtered);
scratch_end(scratch);
}
enum_vals = filter_node->vals_filtered;
}
}
return enum_vals;
}
internal E_EnumValArray
e_type_enum_vals_from_key__cached(E_TypeKey key)
{
E_EnumValArray enum_vals = e_type_enum_vals_from_key_filter__cached(key, str8_zero());
return enum_vals;
}
internal E_EnumVal
e_type_enum_val_from_key_name__cached(E_TypeKey key, String8 name)
{
E_EnumVal result = {0};
E_EnumValCacheNode *node = e_enum_val_cache_node_from_type_key(key);
if(node != 0 && node->val_hash_slots_count != 0)
{
Temp scratch = scratch_begin(0, 0);
E_Type *type = e_type_from_key(key);
String8 name_qualified_0 = push_str8f(scratch.arena, "%S%S", type->name, name);
String8 name_qualified_1 = push_str8f(scratch.arena, "%S_%S", type->name, name);
U64 hash = e_hash_from_string(5381, name);
U64 slot_idx = hash%node->val_hash_slots_count;
for(E_EnumValHashNode *n = node->val_hash_slots[slot_idx].first; n != 0; n = n->next)
{
if(str8_match(type->enum_vals[n->val_idx].name, name, 0) ||
str8_match(type->enum_vals[n->val_idx].name, name_qualified_0, 0) ||
str8_match(type->enum_vals[n->val_idx].name, name_qualified_1, 0))
{
result = type->enum_vals[n->val_idx];
break;
}
}
scratch_end(scratch);
}
return result;
}
////////////////////////////////
//~ rjf: (Built-In Type Hooks) Default Hooks
@@ -2156,8 +2321,8 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(default)
E_TypeKind enum_type_kind = e_type_kind_from_key(expand_type_key);
if(enum_type_kind == E_TypeKind_Enum)
{
E_Type *enum_type = e_type_from_key(expand_type_key);
result.expr_count = enum_type->count;
E_EnumValArray enum_vals = e_type_enum_vals_from_key_filter__cached(expand_type_key, filter);
result.expr_count = enum_vals.count;
did_expansion = 1;
}
}
@@ -2195,13 +2360,14 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default)
else if(expand_type_kind == E_TypeKind_Enum)
{
E_Type *type = e_type_from_key(expand_type_key);
Rng1U64 legal_idx_range = r1u64(0, type->count);
E_EnumValArray enum_vals = e_type_enum_vals_from_key_filter__cached(expand_type_key, filter);
Rng1U64 legal_idx_range = r1u64(0, enum_vals.count);
Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range);
U64 read_range_count = dim_1u64(read_range);
for(U64 idx = 0; idx < read_range_count; idx += 1)
{
U64 member_idx = idx + read_range.min;
String8 member_name = type->enum_vals[member_idx].name;
U64 val_idx = idx + read_range.min;
String8 member_name = enum_vals.v[val_idx].name;
String8 sufficient_suffix = member_name;
if(str8_match(sufficient_suffix, type->name, StringMatchFlag_RightSideSloppy))
{
+15
View File
@@ -56,6 +56,13 @@ internal void e_member_list_push(Arena *arena, E_MemberList *list, E_Member *mem
#define e_member_list_push_new(arena, list, ...) e_member_list_push((arena), (list), &(E_Member){.kind = E_MemberKind_DataField, __VA_ARGS__})
internal E_MemberArray e_member_array_from_list(Arena *arena, E_MemberList *list);
////////////////////////////////
//~ rjf: Enum Value Functions
internal void e_enum_val_list_push(Arena *arena, E_EnumValList *list, E_EnumVal *enum_val);
#define e_enum_val_list_push_new(arena, list, ...) e_enum_val_list_push((arena), (list), &(E_EnumVal){.val = 0, __VA_ARGS__})
internal E_EnumValArray e_enum_val_array_from_list(Arena *arena, E_EnumValList *list);
////////////////////////////////
//~ rjf: Type Operation Functions
@@ -113,11 +120,19 @@ internal E_TypeKey e_default_expansion_type_from_key(E_TypeKey key);
//~ rjf: Cache Lookups
internal E_Type *e_type_from_key(E_TypeKey key);
//- rjf: member lookups
internal E_MemberCacheNode *e_member_cache_node_from_type_key(E_TypeKey key);
internal E_MemberArray e_type_data_members_from_key_filter__cached(E_TypeKey key, String8 filter);
internal E_MemberArray e_type_data_members_from_key__cached(E_TypeKey key);
internal E_Member e_type_member_from_key_name__cached(E_TypeKey key, String8 name);
//- rjf: enum val lookups
internal E_EnumValCacheNode *e_enum_val_cache_node_from_type_key(E_TypeKey key);
internal E_EnumValArray e_type_enum_vals_from_key_filter__cached(E_TypeKey key, String8 filter);
internal E_EnumValArray e_type_enum_vals_from_key__cached(E_TypeKey key);
internal E_EnumVal e_type_enum_val_from_key_name__cached(E_TypeKey key, String8 name);
////////////////////////////////
//~ rjf: (Built-In Type Hooks) Default Hooks