-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Copy pathhashtable.c
89 lines (74 loc) · 1.74 KB
/
hashtable.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
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "hashtable.h"
struct HashNode
{
struct HashNode *next;
uint8_t value[];
};
struct HashTable
{
HashFunc func;
HashValueCmpFunc cmp;
int size;
int elemSize;
struct HashNode *table[];
};
struct HashTable *hashtable_new(HashFunc func, HashValueCmpFunc cmp, int size,
int elemSize)
{
struct HashTable *ht = malloc(sizeof(*ht) + size * sizeof(ht->table[0]));
ht->func = func;
ht->cmp = cmp;
ht->size = size;
ht->elemSize = elemSize;
memset(ht->table, 0, ht->size * sizeof(ht->table[0]));
return ht;
}
void hashtable_free(struct HashTable *ht)
{
int i;
for (i = 0; i < ht->size; i++)
{
struct HashNode *node = ht->table[i];
while (node != NULL)
{
struct HashNode *next = node->next;
free(node);
node = next;
}
}
free(ht);
}
void hashtable_insert(struct HashTable *ht, const void *value)
{
unsigned int key = ht->func(value) % ht->size;
struct HashNode *node = malloc(sizeof(*node) + ht->elemSize);
node->next = NULL;
memcpy(node->value, value, ht->elemSize);
if (ht->table[key] == NULL)
{
ht->table[key] = node;
}
else
{
struct HashNode *parent = ht->table[key];
while (parent->next != NULL)
parent = parent->next;
parent->next = node;
}
}
void *hashtable_query(struct HashTable *ht, const void *value)
{
unsigned int key = ht->func(value) % ht->size;
struct HashNode *node = ht->table[key];
while (node != NULL)
{
if (ht->cmp(node->value, value))
return node->value;
node = node->next;
}
return NULL;
}