aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/moslib/ds/hashmap.h24
-rw-r--r--src/ds/hashmap.c11
-rw-r--r--tests/ds/hashmap_tests.c2
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 <stddef.h>
#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);
}