forked from measurement-factory/dnstop
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hashtbl.c
116 lines (107 loc) · 2.08 KB
/
hashtbl.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
/*
* $Id$
*
* http://dnstop.measurement-factory.com/
*
* Copyright (c) 2006, The Measurement Factory, Inc. All rights
* reserved. See the LICENSE file for details.
*/
#include "config.h"
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#if HAVE_STDINT_H
#include <stdint.h>
#endif
#include "hashtbl.h"
hashtbl
*hash_create(int N, hashfunc *hasher, hashkeycmp *cmp)
{
hashtbl *new = calloc(1, sizeof(*new));
assert(new);
new->modulus = N;
new->hasher = hasher;
new->keycmp = cmp;
new->items = calloc(N, sizeof(hashitem*));
return new;
}
int
hash_add(const void *key, void *data, hashtbl *tbl)
{
hashitem *new = calloc(1, sizeof(*new));
hashitem **I;
int slot;
new->key = key;
new->data = data;
slot = tbl->hasher(key) % tbl->modulus;
for (I = &tbl->items[slot]; *I; I = &(*I)->next);
*I = new;
return 0;
}
void *
hash_find(const void *key, hashtbl *tbl)
{
int slot = tbl->hasher(key) % tbl->modulus;
hashitem *i;
for (i = tbl->items[slot]; i; i = i->next) {
if (0 == tbl->keycmp(key, i->key))
return i->data;
}
return NULL;
}
int
hash_count(hashtbl *tbl)
{
int slot;
int count = 0;
for(slot = 0; slot < tbl->modulus; slot++) {
hashitem *i;
for (i = tbl->items[slot]; i; i=i->next)
count++;
}
return count;
}
void
hash_free(hashtbl *tbl, void freefunc(void *))
{
int slot;
for(slot = 0; slot < tbl->modulus; slot++) {
hashitem *i;
hashitem *next;
for (i = tbl->items[slot]; i; i=next) {
next = i->next;
freefunc(i->data);
free(i);
}
tbl->items[slot] = NULL;
}
}
static void
hash_iter_next_slot(hashtbl *tbl)
{
while (tbl->iter.next == NULL) {
tbl->iter.slot++;
if (tbl->iter.slot == tbl->modulus)
break;
tbl->iter.next = tbl->items[tbl->iter.slot];
}
}
void
hash_iter_init(hashtbl *tbl)
{
tbl->iter.slot = 0;
tbl->iter.next = tbl->items[tbl->iter.slot];
if (NULL == tbl->iter.next)
hash_iter_next_slot(tbl);
}
void *
hash_iterate(hashtbl *tbl)
{
hashitem *this = tbl->iter.next;
if (this) {
tbl->iter.next = this->next;
if (NULL == tbl->iter.next)
hash_iter_next_slot(tbl);
}
return this ? this->data : NULL;
}