5 #define hash_func(k) sdbm((unsigned char *)k)
6 #define hash_func2(k1, k2) (hash_func(k1) ^ hash_func(k2))
8 typedef struct hash_bucket
{
12 struct hash_bucket
*next
;
16 hash_bucket
**buckets
;
17 unsigned int num_buckets
;
19 unsigned int max_entries
;
22 /* struct data access functions */
23 unsigned int hash_get_max_entries(hash_table
*table
)
25 return table
? table
->max_entries
: 0;
28 unsigned int hash_get_num_entries(hash_table
*table
)
30 return table
? table
->entries
: 0;
33 unsigned int hash_table_size(hash_table
*table
)
35 return table
? table
->num_buckets
: 0;
39 * polynomial conversion ignoring overflows
41 * Ozan Yigit's original sdbm algorithm, but without Duff's device
42 * so we can use it without knowing the length of the string
44 static inline unsigned int sdbm(const unsigned register char *k
)
46 register unsigned int h
= 0;
54 static inline int hash_add_bucket(hash_table
*table
, const char *k1
, const char *k2
, void *data
, unsigned int h
)
58 if (!(bkt
= malloc(sizeof(*bkt
))))
61 h
= h
% table
->num_buckets
;
66 bkt
->next
= table
->buckets
[h
];
67 table
->buckets
[h
] = bkt
;
69 if (++table
->entries
> table
->max_entries
)
70 table
->max_entries
= table
->entries
;
75 int hash_add2(hash_table
*table
, const char *k1
, const char *k2
, void *data
)
77 return hash_add_bucket(table
, k1
, k2
, data
, hash_func2(k1
, k2
));
80 int hash_add(hash_table
*table
, const char *key
, void *data
)
82 return hash_add_bucket(table
, key
, NULL
, data
, hash_func(key
));
85 static hash_bucket
*hash_get_bucket(hash_table
*table
, const char *key
)
92 bkt
= table
->buckets
[hash_func(key
) % table
->num_buckets
];
93 for (; bkt
; bkt
= bkt
->next
) {
94 if (!strcmp(key
, bkt
->key
))
101 static hash_bucket
*hash_get_bucket2(hash_table
*table
, const char *k1
, const char *k2
)
108 bkt
= table
->buckets
[hash_func2(k1
, k2
) % table
->num_buckets
];
109 for (; bkt
; bkt
= bkt
->next
) {
110 if (!strcmp(k1
, bkt
->key
) && !strcmp(k2
, bkt
->key2
))
117 void *hash_find(hash_table
*table
, const char *key
)
121 bkt
= hash_get_bucket(table
, key
);
123 return bkt
? bkt
->data
: NULL
;
126 void *hash_find2(hash_table
*table
, const char *k1
, const char *k2
)
130 bkt
= hash_get_bucket2(table
, k1
, k2
);
132 return bkt
? bkt
->data
: NULL
;
135 hash_table
*hash_init(unsigned int buckets
)
137 hash_table
*table
= calloc(sizeof(hash_table
), 1);
140 table
->buckets
= calloc(buckets
, sizeof(hash_bucket
*));
141 if (table
->buckets
) {
142 table
->num_buckets
= buckets
;
152 void *hash_update(hash_table
*table
, const char *key
, void *data
)
157 bkt
= hash_get_bucket(table
, key
);
159 hash_add(table
, key
, data
);
163 current_data
= bkt
->data
;
168 void *hash_update2(hash_table
*table
, const char *key
, const char *key2
, void *data
)
172 bkt
= hash_get_bucket2(table
, key
, key2
);
174 hash_add2(table
, key
, key2
, data
);
182 static inline void *hash_destroy_bucket(hash_bucket
*bkt
)
191 void *hash_remove(hash_table
*table
, const char *key
)
194 hash_bucket
*bkt
, *prev
;
196 h
= hash_func(key
) % table
->num_buckets
;
198 if (!(bkt
= table
->buckets
[h
]))
201 if (!strcmp(key
, bkt
->key
)) {
202 table
->buckets
[h
] = bkt
->next
;
204 return hash_destroy_bucket(bkt
);
208 for (bkt
= bkt
->next
; bkt
; bkt
= bkt
->next
) {
209 if (!strcmp(key
, bkt
->key
)) {
210 prev
->next
= bkt
->next
;
212 return hash_destroy_bucket(bkt
);
219 void *hash_remove2(hash_table
*table
, const char *k1
, const char *k2
)
222 hash_bucket
*bkt
, *prev
;
224 h
= hash_func2(k1
, k2
) % table
->num_buckets
;
226 if (!(bkt
= table
->buckets
[h
]))
229 if (!strcmp(k1
, bkt
->key
) && !strcmp(k2
, bkt
->key2
)) {
230 table
->buckets
[h
] = bkt
->next
;
232 return hash_destroy_bucket(bkt
);
236 for (bkt
= bkt
->next
; bkt
; bkt
= bkt
->next
) {
237 if (!strcmp(k1
, bkt
->key
) && !strcmp(k2
, bkt
->key2
)) {
238 prev
->next
= bkt
->next
;
240 return hash_destroy_bucket(bkt
);
247 unsigned int hash_count_entries(hash_table
*table
)
250 unsigned int count
= 0;
252 for (i
= 0; i
< table
->num_buckets
; i
++) {
254 for (bkt
= table
->buckets
[i
]; bkt
; bkt
= bkt
->next
)
261 int hash_check_table(hash_table
*table
)
263 return hash_count_entries(table
) - table
->entries
;
266 void hash_walk_data(hash_table
*table
, int (*walker
)(void *))
271 for (i
= 0; i
< table
->num_buckets
; i
++) {
273 for (bkt
= table
->buckets
[i
]; bkt
; bkt
= next
) {
280 /* inserts a guaranteed unique entry to the hash-table */
281 int hash_add_unique(hash_table
*table
, const char *key
, void *data
)
286 h
= hash_func(key
) % table
->num_buckets
;
287 for (bkt
= table
->buckets
[h
]; bkt
; bkt
= bkt
->next
)
288 if (!strcmp(bkt
->key
, key
))
291 /* it's a unique key */
292 return hash_add_bucket(table
, key
, NULL
, data
, h
);
295 int hash_add_unique2(hash_table
*table
, const char *k1
, const char *k2
, void *data
)
300 h
= hash_func2(k1
, k2
) % table
->num_buckets
;
301 for (bkt
= table
->buckets
[h
]; bkt
; bkt
= bkt
->next
)
302 if (!strcmp(bkt
->key
, k1
) && !strcmp(bkt
->key2
, k2
))
305 return hash_add_bucket(table
, k1
, k2
, data
, h
);