-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhashmap.c
More file actions
94 lines (74 loc) · 2.47 KB
/
hashmap.c
File metadata and controls
94 lines (74 loc) · 2.47 KB
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
#include "hashmap.h"
#include <assert.h>
#include <err.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Hashmap Function Provided by Tutorial Section from Jared Pon, which allows Hashmap Structures to be created in C.
static size_t hash(char *str) {
size_t acc = 0;
int c;
while ((c = *str++)) {
acc = c + 420 * acc;
}
return acc;
}
static size_t probe(struct HashMap *hashmap, char *key) {
size_t i = hash(key) % hashmap->capacity;
while (hashmap->buffer[i].key != NULL &&
strcmp(hashmap->buffer[i].key, key) != 0)
i = (i + 1) % hashmap->capacity;
return i;
}
void hashMapInit(struct HashMap *hashmap, size_t capacity) {
assert(capacity > 0);
hashmap->length = 0;
hashmap->capacity = capacity;
hashmap->buffer = malloc(sizeof(struct HashMapElem) * capacity);
for (size_t i = 0; i < capacity; ++i) {
hashmap->buffer[i].key = NULL;
hashmap->buffer[i].value = NULL;
}
if (hashmap->buffer == NULL)
err(EXIT_FAILURE, "error `hashMapInit` memory allocation failed");
return;
}
void *hashMapFind(struct HashMap *hashmap, char *key) {
return hashmap->buffer[probe(hashmap, key)].value;
}
void hashMapInsert(struct HashMap *hashmap, char *key, void *value) {
assert(key != NULL);
assert(value != NULL);
if (2 * (hashmap->length + 1) >= hashmap->capacity) {
struct HashMap newHashMap;
hashMapInit(&newHashMap, 2 * (hashmap->capacity + 1));
// reinsert everything in the new hashmap
for (size_t i = 0; i < hashmap->capacity; ++i) {
if (hashmap->buffer[i].value == NULL)
continue;
size_t slot = probe(&newHashMap, hashmap->buffer[i].key);
newHashMap.buffer[slot] = hashmap->buffer[i];
++newHashMap.length;
}
free(hashmap->buffer);
memcpy(hashmap, &newHashMap, sizeof newHashMap);
}
size_t slot = probe(hashmap, key);
if (hashmap->buffer[slot].key == NULL)
++hashmap->length;
hashmap->buffer[slot].key = key;
hashmap->buffer[slot].value = value;
}
void hashMapPrint(struct HashMap *hashmap) {
fprintf(stderr, "Hashmap:\n");
fprintf(stderr, "\tLength: %zu\n", hashmap->length);
fprintf(stderr, "\tCapacity: %zu\n", hashmap->capacity);
fprintf(stderr, "\tBuffer:\n");
for (size_t i = 0; i < hashmap->capacity; ++i) {
fprintf(stderr, "\t\t%zu:\n", i);
fprintf(stderr, "\t\t\tKey: %s\n",
hashmap->buffer[i].key ? hashmap->buffer[i].key : "NULL");
fprintf(stderr, "\t\t\tValue:%p\n", hashmap->buffer[i].value);
}
}