summaryrefslogtreecommitdiff
path: root/include/engine/hashmap.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/engine/hashmap.h')
-rw-r--r--include/engine/hashmap.h55
1 files changed, 55 insertions, 0 deletions
diff --git a/include/engine/hashmap.h b/include/engine/hashmap.h
new file mode 100644
index 0000000..4b97b8e
--- /dev/null
+++ b/include/engine/hashmap.h
@@ -0,0 +1,55 @@
+#ifndef ENGINE_HASHMAP_H
+#define ENGINE_HASHMAP_H
+
+#include "types.h"
+
+#include <stdlib.h>
+#include "list.h"
+#include "memory.h"
+
+
+i32 lolhash(const usize s, i32 v);
+
+/* Define a linked list before using this */
+/* Example: DEFINE_LLIST(i32) */
+#define DEFINE_HASHMAP(type, lsize, cmp, type_to_int) \
+typedef DEFINE_LLIST(type); \
+typedef struct hashmap_##type { \
+ usize size; \
+ List_##type elems[64]; \
+} hashmap_##type; \
+ \
+type* hashmap_##type##_lookup(hashmap_##type* hmap, const type* val) { \
+ const i32 idx = lolhash(64, type_to_int(val)); \
+ List_##type *head = &hmap->elems[idx]; \
+ while (head != NULL) { \
+ if (!cmp(&(head->value), val)) return &(head->value); \
+ head = head->next; \
+ } \
+ return NULL; \
+} \
+ \
+void hashmap_##type##_insert(memory *m, hashmap_##type *hmap, const type *val) { \
+ const i32 idx = lolhash(64, type_to_int(val)); \
+ List_##type *head = &(hmap->elems[idx]); \
+ \
+ /* This is highly dependant on whether the memory is zero-initialized */ \
+ if (!type_to_int(&(head->value))) \
+ { \
+ memcpy(&(head->value), val, sizeof(type)); \
+ return; \
+ } \
+ \
+ \
+ while (head->next != NULL && cmp(&head->value, val)) { \
+ head = head->next; \
+ } \
+ \
+ if (!cmp(&head->value, val)) memcpy(&(head->value), val, sizeof(type)); \
+ else { \
+ head->next = memory_allocate(m, sizeof(List_##type)); \
+ memcpy(&(head->next->value), val, sizeof(type)); \
+ } \
+}
+
+#endif