-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhashmap.c
140 lines (129 loc) · 3.52 KB
/
hashmap.c
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include "hashmap.h"
#include <assert.h>
struct entry {
const char *key;
void *value;
entry *next;
};
struct hashmap {
entry **buckets;
int size;
int current_size;
};
//hash function
unsigned int hash(hashmap *hm, const char *key) {
unsigned int hash = 0;
while (*key) {
hash = (hash * 31) + *key++;
}
return hash % hm->size;
}
//creates entry ADT of key value pair
entry *entry_new(const char *key, void *value) {
entry *e = malloc(sizeof(entry));
if (e == NULL) {
return NULL;
}
e->key = strdup(key); // Make a copy of the key
e->value = value;
e->next = NULL;
return e;
}
//removes entry from hashmap
void entry_delete(hashmap *hm, const char *key) {
unsigned int index = hash(hm, key);
entry *current = hm->buckets[index];
entry *prev = NULL;
while (current != NULL) {
if (strcmp(current->key, key) == 0) {
if (prev == NULL) {
hm->buckets[index] = current->next;
} else {
prev->next = current->next;
}
free(current);
return;
}
prev = current;
current = current->next;
}
}
//creates a hashmap ADT
hashmap *hashmap_new(int size) {
hashmap *hm = malloc(sizeof(hashmap));
if (hm == NULL) {
return NULL;
}
hm->buckets = calloc(size, sizeof(entry *));
if (hm->buckets == NULL) {
free(hm);
return NULL;
}
hm->size = size;
hm->current_size = 0;
return hm;
}
//deallocates memory for hashmap
void hashmap_delete(hashmap **hm) {
if (hm != NULL && *hm != NULL) {
for (int i = 0; i < (*hm)->size; i++) {
entry *current = (*hm)->buckets[i];
while (current != NULL) {
entry *temp = current;
current = current->next;
entry_delete(*hm, temp->key);
}
}
free((*hm)->buckets);
free(*hm);
}
*hm = NULL;
}
//might be mapping diff uris to same rwlock/same uris to diff rwlock
//adds key value to hashmap
void hashmap_add(hashmap *hm, const char *key, void *value) {
unsigned int index = hash(hm, key);
entry *e = entry_new(key, value);
e->next = hm->buckets[index];
hm->buckets[index] = e;
hm->current_size++;
}
//gets the value of the key from the hashmap
void *hashmap_get(hashmap *hm, const char *key) {
//printf("hashmap current size is = %d\n", hm->current_size);
unsigned int index = hash(hm, key);
//printf("hashed index = %d\n", index);
entry *e = hm->buckets[index];
while (e != NULL) {
//printf("e->key: %s & key: %s\n", e->key, key);
if (strcmp(e->key, key) == 0) {
return e->value;
}
e = e->next;
//printf("e->next THIS SHOULD NOT PRINT!!!!!!\n");
}
return NULL;
}
// int main(void) {
// hashmap *h = hashmap_new(3);
// char* s1 = "hello\n";
// char* s2 = "hi\n";
// hashmap_add(h, "filename1", s1);
// hashmap_add(h, "filename2", s2);
// void* val = hashmap_get(h, "filename1");
// assert(strcmp(s1, val) == 0);
// val = hashmap_get(h, "filename2");
// assert(strcmp(s2, val) == 0);
// val = hashmap_get(h, "filename3");
// assert(val == NULL);
// for (int i = 0; i < 100; i++) {
// void* val = hashmap_get(h, "uri");
// if (val == NULL) {
// hashmap_add(h, "uri", s1);
// printf("added uri!\n");
// }
// }
// hashmap_delete(&h);
// printf("passed!\n");
// return 0;
// }