From 0e80a568922ae579213d5a99329fa32420f0bcb0 Mon Sep 17 00:00:00 2001 From: Timerix Date: Thu, 24 Jul 2025 18:26:25 +0300 Subject: [PATCH] implemented lazy initialization of HashMap.table --- src/collections/HashMap.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/collections/HashMap.c b/src/collections/HashMap.c index d91d1ea..e3608bd 100755 --- a/src/collections/HashMap.c +++ b/src/collections/HashMap.c @@ -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]; }