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;
}
|