From: Brendan Hansen Date: Tue, 9 Jun 2020 20:38:32 +0000 (-0500) Subject: Even more bug fixes for bh_hash X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=a7a058d0ef15c07ef1b976f1f67e9a4e57881e9e;p=onyx.git Even more bug fixes for bh_hash --- diff --git a/docs/new_hash_plan b/docs/new_hash_plan index d12fc1d1..117ae146 100644 --- a/docs/new_hash_plan +++ b/docs/new_hash_plan @@ -27,9 +27,9 @@ Attempt 1 to fix these issues: table ----> | allocator | hash size | ptr | ptr | ptr | ptr | ptr | ... +-------------------------||-------------------------------- \/ - +--------------+---------------------------------------------------------------------------- - | Array header | value | key_length | key (null terminated) | v | kl | k | v | kl | k | ... - +--------------+---------------------------------------------------------------------------- + +--------------+------------------------------------------------------------------------ + | Array header | length | value | key_length | key (null terminated) | v | kl | k | ... + +--------------+------------------------------------------------------------------------ GOOD: * This implementation would allow for any size of key. diff --git a/include/bh.h b/include/bh.h index 57c04f28..8d3f6a23 100644 --- a/include/bh.h +++ b/include/bh.h @@ -546,7 +546,7 @@ typedef struct bh__hash { #define bh_hash_iter_setup(T, tab) (assert(sizeof(T) == sizeof(*(tab))), bh__hash_iter_setup((bh__hash *) tab, sizeof(T))) #define bh_hash_iter_key(it) ((char *)(bh_pointer_add(it.entry, it.elemsize + sizeof(u16)))) - #define bh_hash_iter_value(T, it) (assert(sizeof(T) == it.elemsize), *(T *)it.entry) + #define bh_hash_iter_value(T, it) (*(T *)it.entry) #else #define bh_hash_init(allocator_, tab, hs) bh__hash_init(allocator_, (bh__hash **)&(tab), hs) #define bh_hash_free(tab) bh__hash_free((bh__hash **)&(tab)) @@ -1614,10 +1614,16 @@ b32 bh__hash_free(bh__hash **table) { // Assumes NULL terminated string for key ptr bh__hash_put(bh__hash *table, i32 elemsize, char *key) { + elemsize += (elemsize & 1); + u64 index = bh__hash_function(key, 0, table->hash_size); + u8 arr_was_new = 0; ptr arrptr = table->arrs[index]; - if (arrptr == NULL) goto add_new_element; + if (arrptr == NULL) { + arr_was_new = 1; + goto add_new_element; + } u64 len = *(u64 *) arrptr; arrptr = bh_pointer_add(arrptr, sizeof(u64)); @@ -1645,7 +1651,11 @@ add_new_element: bh__arrhead(arrptr)->length = byte_len + elemsize + sizeof(u16) + key_length; table->arrs[index] = arrptr; - (*(u64 *) arrptr)++; + if (arr_was_new) { + *(u64 *) arrptr = 1; + } else { + (*(u64 *) arrptr)++; + } arrptr = bh_pointer_add(arrptr, byte_len + elemsize); *(u16 *) arrptr = key_length; @@ -1657,6 +1667,8 @@ found_matching: } b32 bh__hash_has(bh__hash *table, i32 elemsize, char *key) { + elemsize += (elemsize & 1); + u64 index = bh__hash_function(key, 0, table->hash_size); ptr arrptr = table->arrs[index]; @@ -1678,6 +1690,8 @@ b32 bh__hash_has(bh__hash *table, i32 elemsize, char *key) { } ptr bh__hash_get(bh__hash *table, i32 elemsize, char *key) { + elemsize += (elemsize & 1); + u64 index = bh__hash_function(key, 0, table->hash_size); ptr arrptr = table->arrs[index]; @@ -1701,6 +1715,8 @@ ptr bh__hash_get(bh__hash *table, i32 elemsize, char *key) { } void bh__hash_delete(bh__hash *table, i32 elemsize, char *key) { + elemsize += (elemsize & 1); + u64 index = bh__hash_function(key, 0, table->hash_size); ptr arrptr = table->arrs[index], walker; @@ -1736,6 +1752,8 @@ found_matching: } bh_hash_iterator bh__hash_iter_setup(bh__hash *table, i32 elemsize) { + elemsize += (elemsize & 1); + bh_hash_iterator it = { .tab = table->arrs, .endtab = table->arrs + table->hash_size, diff --git a/onyx b/onyx index 07abf01e..89915f07 100755 Binary files a/onyx and b/onyx differ