aboutsummaryrefslogtreecommitdiffstats
path: root/tests/hmap.c
blob: 920c854f0e5783da157b104707b41beb2047326d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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;
}