-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhash_map.c
More file actions
135 lines (113 loc) · 3.3 KB
/
hash_map.c
File metadata and controls
135 lines (113 loc) · 3.3 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
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hash_map.h"
boolean initialized = False;
HashTable getHashTable() {
/* Creating a Hash Table */
HashTable table = (HashTable) calloc(HASH_TABLE_SIZE, sizeof(List));
return table;
}
int int_key_comparator(void* key, void* data) {
int* key_val = (int*) key;
hashElement* ht_data = (hashElement*) data;
return (*key_val == ht_data->key);
}
void* checkKeyInList(HashTable table, int* key, int idx) {
/* Iterate through the list, checking for key */
if(table[idx] == NULL || table[idx]->head == NULL) {
return NULL;
}
return findInList(table[idx], key, int_key_comparator);
}
HashTable insertToTable(HashTable table, int* key, void* data, int (*hash)(void *)) {
int idx = hash(key);
// int idx = computeHash((char*) key);
if(table[idx] == NULL) {
/* Create a new List */
table[idx] = getList();
}
/* Create a new entry for hash table */
hashElement* elem = (hashElement*) malloc(sizeof(hashElement));
elem->key = (*key);
elem->data = data;
/* Insert the entry to the table */
table[idx] = insertToList(table[idx], elem, FRONT);
return table;
}
boolean isPresent(HashTable table, int* key, int (*hash)(void *)) {
int idx = hash(key);
if(table[idx] == NULL) {
return False;
}
if(checkKeyInList(table, key, idx) != NULL) {
return True;
}
/* key not found */
return False;
}
void* getDataFromTable(HashTable table, int* key, int (*hash)(void *)) {
int idx = hash(key);
// int idx = computeHash((char*) key);
if(table[idx] == NULL) {
return NULL;
}
/* Find the node containing the {key, data} */
hashElement* hashNode = checkKeyInList(table, key, idx);
if(hashNode != NULL) {
return (hashNode->data);
}
/* key not found */
return NULL;
}
HashTable removeFromTable(HashTable table, int* key, int (*hash)(void *)) {
if(table == NULL) {
fprintf(stderr, "The provided hash table is undefined\n");
return table;
}
int idx = hash(key);
if(table[idx] != NULL) {
/* Some key(s) present in this index, search for required key */
hashElement* remNode = checkKeyInList(table, key, idx);
if(remNode != NULL) {
/* key found, delete it*/
table[idx] = deleteByData(table[idx], key, int_key_comparator);
free(remNode);
}
}
return table;
}
/**
* Credits: djb2 hash function from Dan Bernstein -> http://www.cse.yorku.ca/~oz/hash.html
*/
int stringHash(void *y) {
const char *str = y;
unsigned long hash = 5381;
int c;
while (c = *str++)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash % HASH_TABLE_SIZE;
}
/**
* Credits: Answer by Thomal Mueller on https://stackoverflow.com/questions/664014/what-integer-hash-function-are-good-that-accepts-an-integer-hash-key
*/
int numberHash(void *y) {
int x = *((int *)y);
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = (x >> 16) ^ x;
return x % HASH_TABLE_SIZE;
}
/**
* Prints the 'valid entries' of hash table for debugging purposes
*/
void printHashTable(HashTable hashtable, void (*printHash)(void* data)) {
for (int i=0; i < HASH_TABLE_SIZE; i++) {
if(hashtable[i] == NULL) {
printf("[NULL]\n");
} else {
printf("[%d] --> ", i);
printList(hashtable[i], printHash);
}
}
}