aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMosder <git@mosder.eu>2026-09-14 11:49:59 +0200
committerMosder <git@mosder.eu>2026-09-14 11:49:59 +0200
commit74c6cbf6d883b88646c96cf46abd5ab87c36d509 (patch)
treef2eb16a73b1dbe2f8b1be39fdded9b052c0dc6e7 /src
parent979de81cc18784dd88516655a20650ce69196096 (diff)
refactor: removed dead code; feat: added shrinking of hashmap
Diffstat (limited to 'src')
-rw-r--r--src/ds/hashmap.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/ds/hashmap.c b/src/ds/hashmap.c
index c547af4..f10b687 100644
--- a/src/ds/hashmap.c
+++ b/src/ds/hashmap.c
@@ -150,19 +150,29 @@ static size_t probe(const void *hm, const void *key, size_t entry_size, size_t k
tomb = i;
i = (i + 1) % hdr->cap;
}
+
+ // NOTE: unreachable - rehash always happens after 100% fill, even at 100% load factor
return -1;
}
static void rehash(void *p_hm, size_t entry_size, size_t key_size, size_t key_off, uint8_t load_factor) {
void *hm = *(void **)p_hm;
Header *hdr = hm2hdr(hm);
- size_t new_cap = (mos_hm_size(hm) * 400 >= hdr->cap * 3 * load_factor) ? 2 * hdr->cap : hdr->cap;
+ size_t size = mos_hm_size(hm);
+ size_t new_cap = hdr->cap;
+ if (size * 400 >= new_cap * 3 * load_factor) {
+ new_cap *= 2;
+ }
+ else {
+ while (new_cap > INIT_CAP && size * 400 <= new_cap * load_factor)
+ new_cap /= 2;
+ }
Header *new_hdr = mos_safe_malloc(sizeof(Header) + (new_cap + 1) * entry_size);
*new_hdr = (Header){
.filled = mos_safe_calloc((new_cap - 1) / 8 + 1, 1),
.dead = mos_safe_calloc((new_cap - 1) / 8 + 1, 1),
- .size = mos_hm_size(hm),
+ .size = size,
.cap = new_cap,
.hash = hdr->hash,
.eq = hdr->eq,
@@ -214,7 +224,7 @@ void mos_hm_put_fn(void *p_hm, void *key, size_t entry_size, size_t key_size, ui
size_t mos_hm_get_fn(void *hm, void *key, size_t entry_size, size_t key_size) {
size_t key_off = (char *)key - (char *)hm;
size_t i = probe(hm, key, entry_size, key_size, key_off, 0);
- if (i == (size_t)-1 || !filled(hm, i) || dead(hm, i)) {
+ if (!filled(hm, i) || dead(hm, i)) {
memset(hm, 0, entry_size);
return 0;
}
@@ -224,7 +234,7 @@ size_t mos_hm_get_fn(void *hm, void *key, size_t entry_size, size_t key_size) {
void *mos_hm_get_e_fn(const void *hm, const void *key, size_t entry_size, size_t key_size) {
size_t key_off = (char *)key - (char *)hm;
size_t i = probe(hm, key, entry_size, key_size, key_off, 0);
- if (i == (size_t)-1 || !filled(hm, i) || dead(hm, i))
+ if (!filled(hm, i) || dead(hm, i))
return NULL;
return (char *)hm + (i + 1) * entry_size;
}
@@ -232,7 +242,7 @@ void *mos_hm_get_e_fn(const void *hm, const void *key, size_t entry_size, size_t
int mos_hm_del_fn(void *hm, void *key, size_t entry_size, size_t key_size) {
size_t key_off = (char *)key - (char *)hm;
size_t i = probe(hm, key, entry_size, key_size, key_off, 0);
- if (i == (size_t)-1 || !filled(hm, i) || dead(hm, i))
+ if (!filled(hm, i) || dead(hm, i))
return 0;
kill(hm, i);
return 1;