aboutsummaryrefslogtreecommitdiffstats
path: root/tests/hmap.c
diff options
context:
space:
mode:
authorjustanothercatgirl <sotov2070@gmail.com>2024-06-28 00:06:40 +0300
committerjustanothercatgirl <sotov2070@gmail.com>2024-06-28 00:52:08 +0300
commitebad5ad23dc6893b0fb75ba04aa961a25a532b5f (patch)
treec025946d4248b46aceae3e15c19efd29b2d12af2 /tests/hmap.c
parent28bb6070e64f25aa6ff64f81b59a7f52e12d4092 (diff)
Finished hash_map implementation
TODO: fix that one linked list function
Diffstat (limited to 'tests/hmap.c')
-rw-r--r--tests/hmap.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/tests/hmap.c b/tests/hmap.c
new file mode 100644
index 0000000..920c854
--- /dev/null
+++ b/tests/hmap.c
@@ -0,0 +1,105 @@
+#define CONTAINER_IMPLEMENTATION
+#define HMAP_MAX_BUCKET_SIZE 1
+#define HMAP_INIT_SIZE 1
+#include "../include/container.h"
+
+
+// Necessary for hash map to operate
+int int_eqals(const struct hmap_pair* a, const struct hmap_pair* b) {
+ return *(int*)(a->key) - *(int*)(b->key);
+}
+
+// Just a regular hash algorithm
+size_t int_hash(const int* a) {
+ return *a ^ (*a << 1);
+}
+
+// A macro for fun
+#define free_pair(pair) do { free(pair.key); free(pair.val); } while(0)
+
+// Here is an example of how you might iterate elements in hash map
+void print_hmap(struct hash_map* map) {
+ printf("hash map at %p\n", (void*)map);
+ struct hash_map_iter iter;
+ for (hmapi_begin(map, &iter); !hmapi_end(&iter); hmapi_next(&iter)) {
+ printf("key: %i, value: %i\n", *(int*)hmapi_get_key(&iter), *(int*)hmapi_get_val(&iter));
+ }
+}
+struct hmap_pair mkpr(int key, int val) {
+ struct hmap_pair ret = {malloc(sizeof(int)), malloc(sizeof(int))};
+ *(int*)ret.key = key;
+ *(int*)ret.val = val;
+ return ret;
+}
+void freepr(struct hmap_pair* pr) {
+ free(pr->key);
+ free(pr->val);
+}
+
+int main(void) {
+ // Casting functions to the right type should not break it
+ struct hmap_pair pairs[] = {mkpr(1, 2), mkpr(2, 3), mkpr(3, 4), mkpr(3, 5), mkpr(3, 6), mkpr(6, 8)};
+ struct hash_map map = hmap_create_from_buffer(
+ sizeof(int), sizeof(int),
+ (hmap_equal_fn)int_eqals, (hmap_hash_fn)int_hash,
+ pairs, sizeof(pairs)/sizeof(*pairs));
+
+ struct hmap_pair w1 = {malloc(sizeof(int)), malloc(sizeof(int))};
+ *(int*)(w1.key) = 10;
+ *(int*)(w1.val) = 15;
+ struct hmap_pair w2 = {malloc(sizeof(int)), malloc(sizeof(int))};
+ *(int*)(w2.key) = 10;
+ *(int*)(w2.val) = 15;
+ struct hmap_pair w3 = {malloc(sizeof(int)), malloc(sizeof(int))};
+ *(int*)(w3.key) = -69;
+ *(int*)(w3.val) = 12;
+
+ // Ensure there are no memory leaks
+ hmap_insert_mallocated(&map, w1);
+ hmap_insert_mallocated(&map, w2);
+ hmap_insert_mallocated(&map, w3);
+
+ int key;
+ int val;
+ struct hmap_pair p1 = {.key = &key, .val = &val};
+ key = 274;
+ val = 349;
+ hmap_insert_copy(&map, p1);
+ key = 1234;
+ val = 5678;
+ hmap_insert_copy(&map, p1);
+ key = 42;
+ val = 727;
+ hmap_insert_copy(&map, p1);
+ hmap_insert_copy(&map, p1); // Second insert does not do anything
+
+ int zero = 0;
+ hmap_update(&map, &key, &zero);
+
+ int ten = 10;
+ printf("hmap at %i: %i\n", ten, *(int*)hmap_get(&map, &ten));
+ hmap_remove(&map, &ten);
+
+ struct hmap_pair pairs_2[] = {mkpr(100, 200), mkpr(200, 600), mkpr(600, 300), mkpr(300, 420)};
+ hmap_insert_range(&map, pairs_2, sizeof(pairs_2)/sizeof(*pairs_2));
+
+ hmap_iter iter;
+ void** rmkeys = array_new(void*, 0);
+ for (hmapi_begin(&map, &iter); !hmapi_end(&iter); hmapi_next(&iter)) {
+ if (*(int*)hmapi_get_key(&iter) % 100 != 0)
+ array_push(rmkeys, hmapi_get_key(&iter));
+ }
+ for (size_t i = 0; i < array_size(rmkeys); ++i)
+ hmap_remove(&map, rmkeys[i]);
+ array_free(rmkeys);
+
+ print_hmap(&map);
+ hmap_free(&map);
+ for (size_t i = 0; i < sizeof(pairs)/sizeof(*pairs); ++i) {
+ freepr(pairs + i);
+ }
+ for (size_t i = 0; i < sizeof(pairs_2)/sizeof(*pairs_2); ++i) {
+ freepr(pairs_2 + i);
+ }
+ return 0;
+}