blob: bbb4aa726b7e2ff928cd9fe3e13a8c96be42f290 [file] [log] [blame]
swissChilica0d2e22020-08-16 15:09:25 -07001#include "map.h"
2
3#include <stdlib.h>
4#include <string.h>
5#include <stdio.h>
6
7#ifdef MAP_DEBUG
8#define MAP_DEBUG_PRINTF printf
9#else
10#define MAP_DEBUG_PRINTF // nothing
11#endif
12
13map_t *new_map_sized(uint64_t size)
14{
15 map_t *m = malloc(sizeof(map_t));
16
17 /*
18 * Calloc zeroes the memory, which is what we want.
19 */
20
21 map_node empty = EMPTY_NODE;
22
23 m->items = calloc(size, sizeof(map_node));
24 m->len = MAP_ALLOC_SIZE;
25 m->full = 0;
26
27 for (int i = 0; i < m->len; i++)
28 {
29 m->items[i] = empty;
30 }
31
32 return m;
33}
34
35map_t *new_map()
36{
37 return new_map_sized(MAP_ALLOC_SIZE);
38}
39
40void free_map(map_t *m)
41{
42 free(m->items);
43 free(m);
44}
45
46void free_map_items(map_t *m)
47{
48 for (int i = 0; i < m->len; i++)
49 {
50 if (m->items[i].key != NULL)
51 {
52 free(m->items[i].key);
53 free(m->items[i].val);
54 }
55 }
56 free(m->items);
57 free(m);
58}
59
60void map_set(map_t *m, char *k, void *v)
61{
62 uint64_t h = hash(k);
63 uint32_t i = h % m->len;
64
65 MAP_DEBUG_PRINTF("hash %u i %u\n", h, i);
66
67 m->count++;
68
69 if (m->full++ < m->len)
70 {
71 map_node val =
72 {
swissChilidab15a62020-08-17 15:41:27 -070073 malloc(strlen(k) + 1),
swissChilica0d2e22020-08-16 15:09:25 -070074 v,
75 1,
76 h,
77 };
78
79 strcpy(val.key, k);
80
81 uint32_t current = i;
82
83 while (MAP_USED_AT(m->items, current))
84 {
85 if (current == m->len - 1)
86 {
87 current = 0;
88 }
89 else
90 {
91 current++;
92 }
93 }
94
95 MAP_DEBUG_PRINTF("Current %d\n", current);
96
97 m->items[current] = val;
98
99 MAP_DEBUG_PRINTF("val %d\n", *(int *) m->items[current].val);
100 }
101 else
102 {
103 /* resize map */
104 map_t *n_m = new_map_sized(m->len * 2);
105
106 for (uint64_t j = 0; j < m->len; j++)
107 {
108 if (!MAP_USED_AT(m->items, j))
109 {
110 continue;
111 }
112
113 uint32_t current = m->items[j].h;
114
115 while (MAP_USED_AT(m->items, current))
116 {
117 if (current == m->len - 1)
118 {
119 current = 0;
120 }
121 else
122 {
123 current++;
124 }
125 }
126
127 n_m->items[current] = m->items[j];
128 }
129
130 free_map(m);
131 m = n_m;
132 }
133}
134
135int map_exists(map_t *m, char *k)
136{
137 uint64_t h = hash(k);
138 uint32_t i = h % m->len;
139
140 uint32_t current = i;
141
142 while (m->items[current].used)
143 {
144 if (strcmp(m->items[current].key, k) == 0)
145 {
146 return 1;
147 }
148
149 if (current >= m->len - 1)
150 {
151 current = 0;
152 MAP_DEBUG_PRINTF("Current reset to 0\n");
153 }
154 else
155 {
156 current++;
157 MAP_DEBUG_PRINTF("Incrementing current\n");
158 }
159 }
160
161 return 0;
162}
163
164void *map_get(map_t *m, char *k)
165{
166 uint64_t h = hash(k);
167 uint32_t i = h % m->len;
168
169 uint32_t current = i;
170
171 MAP_DEBUG_PRINTF("%s should be %s\n", m->items[current].key, k);
172 MAP_DEBUG_PRINTF("streq %d\n", strcmp(m->items[current].key, k));
173
174 MAP_DEBUG_PRINTF("Current get %d\n", current);
175
176 while (strcmp(m->items[current].key, k) != 0)
177 {
178 MAP_DEBUG_PRINTF("While at %d\n", current);
179 if (current >= m->len - 1)
180 {
181 current = 0;
182 MAP_DEBUG_PRINTF("Current reset to 0\n");
183 }
184 else
185 {
186 current++;
187 MAP_DEBUG_PRINTF("Incrementing current\n");
188 }
189 }
190
191 MAP_DEBUG_PRINTF("val %d\n", *(int *) m->items[current].val);
192
193 return m->items[current].val;
194
195 //return 1;
196}
197
198void map_debug(map_t *m)
199{
200 for (int i = 0; i < m->len; i++)
201 {
202 if (m->items[i].val != NULL)
203 {
204 MAP_DEBUG_PRINTF("i = %d, k = %s, v = %d\n",
205 i, m->items[i].key, *(int *) m->items[i].val);
206 }
207 }
208}