]> git.datanom.net - hashtable.git/blame - hashtable.c
print function
[hashtable.git] / hashtable.c
CommitLineData
1d8fe1f7
MR
1#include <string.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include "hashtable.h"
5
8c5be416
MR
6typedef struct _Node {
7 void* key;
1d8fe1f7 8 void* data;
8c5be416
MR
9 struct _Node* next;
10} Node;
1d8fe1f7 11
8c5be416 12struct _Hashtable {
1d8fe1f7
MR
13 uint32_t size;
14 HashFunc hash;
15 EqualFunc compare;
8c5be416 16 FreeFunc free;
f3e1ef9f 17 PrintFunc print;
8c5be416
MR
18 Node** nodes;
19};
20
21typedef struct {
22 Hashtable* table;
23 void* dummy2;
24 void* dummy3;
25 int64_t pos;
26} RealIter;
1d8fe1f7
MR
27
28static uint32_t hash_table_index(Hashtable* ht, const void* key) {
29 return (ht->hash(key) % ht->size);
30}
31
f3e1ef9f
MR
32static void hash_table_default_print(void* data) {
33 printf("%p", data);
34}
35
1d8fe1f7 36Hashtable* hash_table_create(HashFunc hf, EqualFunc ef) {
f3e1ef9f 37 return hash_table_create_full(hf, ef, TABLESIZE, NULL, NULL);
8c5be416
MR
38}
39
40Hashtable* hash_table_create_notify(HashFunc hf, EqualFunc ef, FreeFunc ff) {
f3e1ef9f 41 return hash_table_create_full(hf, ef, TABLESIZE, ff, NULL);
1d8fe1f7
MR
42}
43
f3e1ef9f 44Hashtable* hash_table_create_full(HashFunc hf, EqualFunc ef, uint32_t size, FreeFunc ff, PrintFunc pf) {
1d8fe1f7
MR
45 Hashtable* ht = malloc(sizeof(*ht));
46 ht->size = size;
47 ht->hash = hf;
48 ht->compare = ef;
8c5be416
MR
49 if (ff) {
50 ht->free = ff;
51 } else {
52 ht->free = free;
53 }
f3e1ef9f
MR
54 if (pf) {
55 ht->print = pf;
56 } else {
57 ht->print = hash_table_default_print;
58 }
8c5be416 59 ht->nodes = calloc(sizeof(Node*), ht->size);
1d8fe1f7
MR
60 return ht;
61}
62
63void hash_table_destroy(Hashtable* ht) {
64 for (uint32_t i = 0; i < ht->size; i++) {
8c5be416
MR
65 while (ht->nodes[i]) {
66 Node* node = ht->nodes[i];
67 ht->nodes[i] = ht->nodes[i]->next;
68 ht->free(node->data);
69 free(node);
1d8fe1f7
MR
70 }
71 }
72 hash_table_print(ht);
8c5be416 73 free(ht->nodes);
1d8fe1f7
MR
74 free(ht);
75}
76
f3e1ef9f
MR
77void hash_table_set_print_func(Hashtable* ht, PrintFunc pf) {
78 ht->print = pf;
79}
80
1d8fe1f7
MR
81void hash_table_print(Hashtable* ht) {
82 printf("Start Table\n");
83 for (uint32_t i = 0; i < ht->size; i++) {
8c5be416 84 if (ht->nodes[i] == NULL) {
1d8fe1f7
MR
85 //printf("\t%i\t---\n", i);
86 } else {
87 printf("\t%i\t\n", i);
8c5be416
MR
88 Node* node = ht->nodes[i];
89 while (node != NULL) {
f3e1ef9f
MR
90 printf("\"%p\" - (", node->key);
91 ht->print(node->data);
92 printf(")");
8c5be416 93 node = node->next;
1d8fe1f7
MR
94 }
95 printf("\n");
96 }
97 }
98 printf("End Table\n");
99}
100
101bool hash_table_insert(Hashtable* ht, const void* key, void* obj) {
102 if (key == NULL || obj == NULL || ht == NULL) return false;
103
104 // implement chaning
8c5be416 105 if (hash_table_lookup(ht, key) != NULL) return false;
1d8fe1f7
MR
106
107 uint32_t index = hash_table_index(ht, key);
108
8c5be416
MR
109 Node* node = malloc(sizeof(*node));
110 node->data = obj;
111 node->key = (void*)key;
1d8fe1f7 112
8c5be416
MR
113 node->next = ht->nodes[index];
114 ht->nodes[index] = node;
1d8fe1f7
MR
115 return true;
116}
117
118void* hash_table_lookup(Hashtable* ht, const void* key) {
119 if (key == NULL || ht == NULL) return false;
dd3da95a 120 uint32_t index = hash_table_index(ht, key);
1d8fe1f7 121
8c5be416
MR
122 Node* node = ht->nodes[index];
123 while (node != NULL && ht->compare(node->data, key) == false) {
124 node = node->next;
125 }
126
127 if (node == NULL) return NULL;
dd3da95a 128 //printf("find: %p -> found: %p\n", key, node->data);
1d8fe1f7 129
8c5be416 130 return node->data;
1d8fe1f7
MR
131}
132
133void* hash_table_delete(Hashtable* ht, const void* key) {
134 if (key == NULL || ht == NULL) return false;
135 uint64_t index = hash_table_index(ht, key);
136
8c5be416
MR
137 Node* node = ht->nodes[index];
138 Node* prev = NULL;
139 while (node != NULL && ht->compare(node->data, key) == false) {
140 prev = node;
141 node = node->next;
142 }
143
144 if (node == NULL) return NULL;
145 if (prev == NULL) {
146 ht->nodes[index] = node->next;
147 } else{
148 prev->next = node->next;
149 }
1d8fe1f7 150
8c5be416
MR
151 void* result = node->data;
152 free(node);
1d8fe1f7
MR
153 return result;
154}
155
8c5be416
MR
156List* hash_table_keys(Hashtable* ht) {
157 List *keys, *head;
158 keys = head = NULL;
159
160 if (ht != NULL) {
161 for (uint32_t i = 0; i < ht->size; i++) {
162 if (ht->nodes[i] != NULL) {
163 Node* node = ht->nodes[i];
164 while (node != NULL) {
165 if (head == NULL) {
166 head = calloc(sizeof(List*), 1);
167 keys = head;
168 }
169 else {
170 head->next = calloc(sizeof(List*), 1);
171 head = head->next;
172 }
173 head->data = ht->nodes[i]->key;
174 node = node->next;
175 }
176 }
177 }
178 }
179
180 return keys;
181}
182
183List* hash_table_values(Hashtable* ht) {
184 List *values, *head;
185 values = head = NULL;
186
187 if (ht != NULL) {
188 for (uint32_t i = 0; i < ht->size; i++) {
189 if (ht->nodes[i] != NULL) {
190 Node* node = ht->nodes[i];
191 while (node != NULL) {
192 if (head == NULL) {
193 head = calloc(sizeof(List*), 1);
194 values = head;
195 }
196 else {
197 head->next = calloc(sizeof(List*), 1);
198 head = head->next;
199 }
200 head->data = ht->nodes[i]->data;
201 node = node->next;
202 }
203 }
204 }
205 }
206
207 return values;
208}
209
210void hash_table_list_free(List* list) {
211 while (list != NULL) {
212 List* prev = list;
213 list = list->next;
214 free(prev);
215 }
216}
217
218void hash_table_foreach(Hashtable* ht, ForeachFunc ff, void* userdata) {
219 if (ht != NULL) {
220 for (uint32_t i = 0; i < ht->size; i++) {
221 if (ht->nodes[i] != NULL) {
222 Node* node = ht->nodes[i];
223 while (node != NULL) {
224 ff(node->key, node->data, userdata);
225 node = node->next;
226 }
227 }
228 }
229 }
230}
231
232void hash_table_iter_init (HashtableIter* iter, Hashtable* ht) {
233 RealIter* ri = (RealIter*) iter;
234
235 if (ri != NULL && ht != NULL) {
236 ri->table = ht;
237 ri->pos = -1;
238 }
239}
240
241bool hash_table_iter_next(HashtableIter* iter, void** key, void** value) {
242 RealIter* ri = (RealIter*) iter;
243 Node* node;
244 int64_t pos;
245
246 if (ri != NULL) {
247 pos = ri->pos;
248
249 do {
250 pos++;
251 if (pos >= ri->table->size) {
252 ri->pos = pos;
253 return false;
254 }
255 node = ri->table->nodes[pos];
256 } while (node == NULL);
257
258 if (key != NULL)
259 *key = node->key;
260 if (value != NULL)
261 *value = node->data;
262
263 ri->pos = pos;
264 return true;
265 }
266 return false;
267}
268
dd3da95a
MR
269bool hash_table_contains(Hashtable* ht, const void* key) {
270 if (ht == NULL || key == NULL) return false;
271
272 if (hash_table_lookup(ht, key) == NULL)
273 return false;
274 return true;
275}
276
277uint64_t hash_table_size(Hashtable *ht) {
278 uint64_t size = 0;
279
280 if (ht == NULL) return size;
281
282 for (uint32_t i = 0; i < ht->size; i++) {
283 if (ht->nodes[i] != NULL) {
284 Node* node = ht->nodes[i];
285 while (node != NULL) {
286 size++;
287 node = node->next;
288 }
289 }
290 }
291
292 return size;
293}
294
295bool hash_table_replace(Hashtable *ht, void* key, void* value) {
296 if (ht == NULL || key == NULL || value == NULL) return false;
297
298 uint32_t index = hash_table_index(ht, key);
299
300 Node* node = ht->nodes[index];
301 while (node != NULL && ht->compare(node->data, key) == false) {
302 node = node->next;
303 }
304
305 if (node == NULL)
306 return hash_table_insert(ht, key, value);
307 else {
308 free(node->data);
309 node->key = key;
310 node->data = value;
311 }
312
313 return true;
314}
315
1d8fe1f7
MR
316uint64_t int_hash(const void* key) {
317 return *(uint64_t*) key;
318}
319
320uint64_t str_hash(const void* key) {
321 const signed char* p;
322 uint64_t h = 5381;
323
324 for (p = key; *p != '\0'; p++) {
325 h = (h << 5) + h + *p;
326 }
327
328 return h;
329}
330
331uint64_t ptr_hash(const void* key) {
332 return (uint64_t)key;
333}
334
335bool int_equal(const void* a, const void* b) {
336 return *((const int*) a) == *((const int*) b);
337}
338
339bool str_equal(const void* a, const void* b) {
340 const char *string1 = (const char*) a;
341 const char *string2 = (const char*) b;
342
343 return strcmp (string1, string2) == 0;
344}
345
346bool ptr_equal(const void* a, const void* b) {
347 return a == b;
348}
349
This page took 0.133932 seconds and 5 git commands to generate.