From d5af4d7bf8f654539f504ed79ca7ed2e4f85fda7 Mon Sep 17 00:00:00 2001 From: Mosder Date: Sat, 12 Sep 2026 16:46:09 +0200 Subject: feat: added hm_size; fix: fixed MOS_HM_LOAD_FACTOR not doing anything lol --- include/moslib/ds/hashmap.h | 24 +++++++++++++++++++----- src/ds/hashmap.c | 11 ++++++++--- tests/ds/hashmap_tests.c | 2 ++ 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/include/moslib/ds/hashmap.h b/include/moslib/ds/hashmap.h index b727c6c..3c50287 100644 --- a/include/moslib/ds/hashmap.h +++ b/include/moslib/ds/hashmap.h @@ -98,6 +98,12 @@ // // ---------------------------------------------------------------------------------------------------- // +// To get the count of entries in the hashmap, use: +// +// hm_size(hm); +// +// ---------------------------------------------------------------------------------------------------- +// // Free the hashmap with: // // hm_free(hm); @@ -113,7 +119,7 @@ // Load factor (in %) to use in hashmap #ifndef MOS_HM_LOAD_FACTOR -#define MOS_HM_LOAD_FACTOR 50 +#define MOS_HM_LOAD_FACTOR 75 #endif // MOS_HM_LOAD_FACTOR #ifndef MOS_FORCE_PREFIXES @@ -126,6 +132,7 @@ #define hm_get_e mos_hm_get_e #define hm_first mos_hm_first #define hm_next mos_hm_next +#define hm_size mos_hm_size #define hm_free mos_hm_free #endif // MOS_FORCE_PREFIXES @@ -168,13 +175,13 @@ typedef struct { // hm // hashmap to put into // -// key +// k // key of the entry to put // // ... // value of the entry to put // variadic to make things like (struct Val){1,1} work properly -#define mos_hm_put(hm, k, ...) (mos_hm_ini, (hm)->key = k, (hm)->val = __VA_ARGS__, mos_hm_put_fn(&(hm), mos_hm_fn_args)) +#define mos_hm_put(hm, k, ...) (mos_hm_ini, (hm)->key = k, (hm)->val = __VA_ARGS__, mos_hm_put_fn(&(hm), mos_hm_fn_args, MOS_HM_LOAD_FACTOR)) // Put a given entry in the hashmap // If entry of the same key exists - overwrites it @@ -186,7 +193,7 @@ typedef struct { // ... // entry to put into hashmap // variadic to make things like (struct Entry){"key","val"} work properly -#define mos_hm_put_e(hm, ...) (mos_hm_ini, (hm)[0] = __VA_ARGS__, mos_hm_put_fn(&(hm), mos_hm_fn_args)) +#define mos_hm_put_e(hm, ...) (mos_hm_ini, (hm)[0] = __VA_ARGS__, mos_hm_put_fn(&(hm), mos_hm_fn_args, MOS_HM_LOAD_FACTOR)) // Get the value of entry with specific key // @@ -238,6 +245,13 @@ typedef struct { // pointer to the next entry or NULL if there's no more entries #define mos_hm_next(hm, curr) mos_hm_next_fn(hm, curr, sizeof(*(hm))) +// Get the count of entries in the hashmap +// +// Arguments: +// hm +// hashmap to get the count of entries from +extern size_t mos_hm_size(void *hm); + // Free the hashmap // // Arguments: @@ -252,7 +266,7 @@ extern void mos_hm_init(void *p_hm, size_t entry_size); // Function prototypes for macros extern void *mos_hm_new_fn(MosHmInitArgs args); -extern void mos_hm_put_fn(void *p_hm, void *key, size_t entry_size, size_t key_size); +extern void mos_hm_put_fn(void *p_hm, void *key, size_t entry_size, size_t key_size, uint8_t load_factor); extern size_t mos_hm_get_fn(void *hm, void *key, size_t entry_size, size_t key_size); extern void *mos_hm_get_e_fn(void *hm, void *key, size_t entry_size, size_t key_size); extern void *mos_hm_first_fn(void *hm, size_t entry_size); diff --git a/src/ds/hashmap.c b/src/ds/hashmap.c index ca9ce62..9b92302 100644 --- a/src/ds/hashmap.c +++ b/src/ds/hashmap.c @@ -1,4 +1,3 @@ -#include #define MOS_FORCE_PREFIXES #include "moslib/ds/hashmap.h" @@ -172,7 +171,7 @@ static void expand(void *p_hm, size_t entry_size, size_t key_size, size_t key_of *(void **)p_hm = new_hm; } -void mos_hm_put_fn(void *p_hm, void *key, size_t entry_size, size_t key_size) { +void mos_hm_put_fn(void *p_hm, void *key, size_t entry_size, size_t key_size, uint8_t load_factor) { size_t key_off = (char *)key - *(char **)p_hm; Header *hdr = hm2hdr(*(void **)p_hm); @@ -184,7 +183,7 @@ void mos_hm_put_fn(void *p_hm, void *key, size_t entry_size, size_t key_size) { fill(hm, i); } - if (hdr->size * 100 > hdr->cap * MOS_HM_LOAD_FACTOR) + if (hdr->size * 100 >= hdr->cap * load_factor) expand(p_hm, entry_size, key_size, key_off); } @@ -243,6 +242,12 @@ void *mos_hm_next_fn(void *hm, void *curr, size_t entry_size) { return NULL; } +size_t mos_hm_size(void *hm) { + if (!hm) + return 0; + return hm2hdr(hm)->size; +} + void mos_hm_free(void *hm) { if (!hm) return; diff --git a/tests/ds/hashmap_tests.c b/tests/ds/hashmap_tests.c index 749564a..288bb4e 100644 --- a/tests/ds/hashmap_tests.c +++ b/tests/ds/hashmap_tests.c @@ -19,6 +19,7 @@ Test put_get() { hm_put(hm, 0.0f, 2137); test_assert(hm_get(hm, 0.0f) == 2137, "hm_put didn't update value properly"); + test_assert(hm_size(hm) == 2, "hm_size returned wrong entry count"); // a lot of puts and gets to test expansion of hashmap for (int i = 2; i < 100; i++) { @@ -30,6 +31,7 @@ Test put_get() { flag = 0; } test_assert(flag, "hm_put / hm_get failed when expansion was needed"); + test_assert(hm_size(hm) == 100, "hm_size returned wrong entry count"); hm_free(hm); } -- cgit v1.2.3