implemented lazy initialization of HashMap.table
This commit is contained in:
parent
03bebea4b2
commit
0e80a56892
@ -7,8 +7,8 @@
|
|||||||
#define __HashMapBucket_MAX_LEN 16
|
#define __HashMapBucket_MAX_LEN 16
|
||||||
|
|
||||||
static const Array(u32) __HashMap_heights = ARRAY(u32, {
|
static const Array(u32) __HashMap_heights = ARRAY(u32, {
|
||||||
17, 31, 61, 127, 257, 521, 1021, 2053, 4099, 8191, 16381, 32771,
|
0, 17, 31, 61, 127, 257, 521, 1021, 2053, 4099, 8191, 16381,
|
||||||
65521, 131071, 262147, 524287, 1048583, 2097169, 4194319,
|
32771, 65521, 131071, 262147, 524287, 1048583, 2097169, 4194319,
|
||||||
8388617, 16777213, 33554467, 67108859, 134217757, 268435493
|
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_t_size = value_t_size;
|
||||||
ptr->value_destructor = value_destructor;
|
ptr->value_destructor = value_destructor;
|
||||||
ptr->height_n = 0;
|
ptr->height_n = 0;
|
||||||
//TODO: make first height == 0 and call malloc later
|
ptr->height = 0;
|
||||||
ptr->height = ((u32*)__HashMap_heights.data)[0];
|
ptr->table = NULL;
|
||||||
u32 alloc_size = ptr->height * sizeof(HashMapBucket);
|
|
||||||
ptr->table = (HashMapBucket*)malloc(alloc_size);
|
|
||||||
memset(ptr->table, 0, alloc_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HashMap_destroy(HashMap_* ptr){
|
void HashMap_destroy(HashMap_* ptr){
|
||||||
@ -53,13 +50,19 @@ void HashMap_destroy(HashMap_* ptr){
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef struct BucketAndIndex {
|
typedef struct BucketAndIndex {
|
||||||
HashMapBucket* bu;
|
NULLABLE(HashMapBucket* bu);
|
||||||
i32 i; // -1 if not found
|
i32 i; // -1 if not found
|
||||||
} BucketAndIndex;
|
} BucketAndIndex;
|
||||||
|
|
||||||
#define BucketAndIndex_null ((BucketAndIndex){ .bu = NULL, .i = -1 })
|
#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){
|
static BucketAndIndex __HashMap_search(HashMap_* ptr, str key, u32 hash){
|
||||||
|
if(ptr->height == 0)
|
||||||
|
return BucketAndIndex_null;
|
||||||
|
|
||||||
BucketAndIndex r;
|
BucketAndIndex r;
|
||||||
r.bu = &ptr->table[hash % ptr->height];
|
r.bu = &ptr->table[hash % ptr->height];
|
||||||
for(r.i = 0; r.i < (i32)List_len(&r.bu->key_hash_list, KeyHash); r.i++){
|
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;
|
return false;
|
||||||
|
|
||||||
HashMapBucket* bu = r.bu;
|
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);
|
__HashMap_expand(ptr);
|
||||||
bu = &ptr->table[hash % ptr->height];
|
bu = &ptr->table[hash % ptr->height];
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user