-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Expand file tree
/
Copy pathhash_set.c
More file actions
101 lines (79 loc) · 2.22 KB
/
hash_set.c
File metadata and controls
101 lines (79 loc) · 2.22 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
#include <stdio.h>
#include <stdlib.h>
#include "hash_set.h"
extern hash_set_t *init_hash_set()
{
hash_set_t *set = (hash_set_t *)malloc(sizeof(hash_set_t));
set->keys = calloc(DEFAULT_HASH_SET_CAPACITY, sizeof(void **));
set->values = calloc(DEFAULT_HASH_SET_CAPACITY, sizeof(void **));
set->length = 0;
set->capacity = DEFAULT_HASH_SET_CAPACITY;
return set;
}
unsigned add(hash_set_t *set, void *value)
{
return put(set, hash(value), value);
}
unsigned put(hash_set_t *set, long long hash, void *value)
{
if (contains_hash(set, hash))
{
if (set->keys[retrieve_index_from_hash(hash, set->capacity)] == value)
{
return 0;
}
// collision
resize(set);
return put(set, hash, value);
}
set->keys[retrieve_index_from_hash(hash, set->capacity)] = value;
set->values[set->length++] = value;
return 1;
}
int contains(hash_set_t *set, void *value)
{
return set->keys[retrieve_index_from_hash(hash(value), set->capacity)] ==
value
? 1
: 0;
}
int contains_hash(hash_set_t *set, long long hash)
{
return set->keys[retrieve_index_from_hash(hash, set->capacity)] ? 1 : 0;
}
void delete (hash_set_t *set, void *value)
{
set->keys[retrieve_index_from_hash(hash(value), set->capacity)] = NULL;
}
// adler_32 hash
long long hash(void *value)
{
char *str = value;
int a = 1;
int b = 0;
const int MODADLER = 65521;
for (int i = 0; str[i] != '\0'; i++)
{
a = (a + str[i]) % MODADLER;
b = (b + a) % MODADLER;
}
return (b << 16) | a;
}
unsigned retrieve_index_from_hash(const long long hash, const unsigned capacity)
{
return (capacity - 1) & (hash ^ (hash >> 12));
}
void resize(hash_set_t *set)
{
void **keys_resized = calloc((set->capacity <<= 1), sizeof(void **));
for (int i = 0; i < set->length; i++)
{
keys_resized[retrieve_index_from_hash(hash(set->values[i]),
set->capacity)] = set->values[i];
}
free(set->keys);
set->keys = keys_resized;
void **new_values =
(void **)realloc(set->values, set->capacity * sizeof(void **));
set->values = new_values;
}