implemented lazy initialization of HashMap.table

This commit is contained in:
Timerix 2025-07-24 18:26:25 +03:00
parent 03bebea4b2
commit 0e80a56892

View File

@ -7,8 +7,8 @@
#define __HashMapBucket_MAX_LEN 16
static const Array(u32) __HashMap_heights = ARRAY(u32, {
17, 31, 61, 127, 257, 521, 1021, 2053, 4099, 8191, 16381, 32771,
65521, 131071, 262147, 524287, 1048583, 2097169, 4194319,
0, 17, 31, 61, 127, 257, 521, 1021, 2053, 4099, 8191, 16381,
32771, 65521, 131071, 262147, 524287, 1048583, 2097169, 4194319,
8388617, 16777213, 33554467, 67108859, 134217757, 268435493
});
@ -17,11 +17,8 @@ void HashMap_construct_size(HashMap_* ptr, u32 value_t_size, FreeFunction NULLAB
ptr->value_t_size = value_t_size;
ptr->value_destructor = value_destructor;
ptr->height_n = 0;
//TODO: make first height == 0 and call malloc later
ptr->height = ((u32*)__HashMap_heights.data)[0];
u32 alloc_size = ptr->height * sizeof(HashMapBucket);
ptr->table = (HashMapBucket*)malloc(alloc_size);
memset(ptr->table, 0, alloc_size);
ptr->height = 0;
ptr->table = NULL;
}
void HashMap_destroy(HashMap_* ptr){
@ -53,13 +50,19 @@ void HashMap_destroy(HashMap_* ptr){
}
typedef struct BucketAndIndex {
HashMapBucket* bu;
NULLABLE(HashMapBucket* bu);
i32 i; // -1 if not found
} BucketAndIndex;
#define BucketAndIndex_null ((BucketAndIndex){ .bu = NULL, .i = -1 })
///@returns `HashMapBucket*` for specified key or NULL, if table hasn't been allocated yet;
/// Index of existing item with the same key or -1 if no item is present.
static BucketAndIndex __HashMap_search(HashMap_* ptr, str key, u32 hash){
if(ptr->height == 0)
return BucketAndIndex_null;
BucketAndIndex r;
r.bu = &ptr->table[hash % ptr->height];
for(r.i = 0; r.i < (i32)List_len(&r.bu->key_hash_list, KeyHash); r.i++){
@ -123,7 +126,7 @@ bool HashMap_tryPush(HashMap_* ptr, str key, void* value_ptr){
return false;
HashMapBucket* bu = r.bu;
if(List_len(&bu->key_hash_list, KeyHash) >= __HashMapBucket_MAX_LEN){
if(bu == NULL || List_len(&bu->key_hash_list, KeyHash) >= __HashMapBucket_MAX_LEN){
__HashMap_expand(ptr);
bu = &ptr->table[hash % ptr->height];
}