6 #include <sys/malloc.h>
8 #include "hashtable.h" // XXX fix path later
11 struct new_obj *next; /* Next object in the list */
12 char obj[0]; /* actually bigger */
17 int table_size; /* Size of the table (buckets) */
18 int table_obj; /* number of object in the table */
19 int obj_size; /* size of object (key + value) */
20 /* Hash function for this table */
21 uint32_t (*hash)(const void *key, uint32_t size);
22 int (*cmp)(const void *obj1, const void *obj2, int sz);
23 int hash_arg; /* hash function parameter */
24 struct malloc_type *mtype;
25 struct new_obj **table_ptr; /* Pointer to the table */
29 * initialize an hash table
30 * - size: size of table (number of buckets)
31 * - obj_size: size of the object to store in the table (key + value)
32 * - hf: pointer to the hash function for this table
33 * - compare: function to compare two objects
35 * Return value: pointer to the hash table, NULL if error occurs
38 ipfw_ht_new(int size, int obj_size,
39 uint32_t (hf)(const void *, uint32_t size),
40 int (compare)(const void *, const void *, int),
41 struct malloc_type *mtype)
45 h = malloc(sizeof(*h), mtype, M_NOWAIT | M_ZERO);
49 h->table_ptr = malloc(size * sizeof(struct new_obj*), mtype,
51 if (h->table_ptr == NULL) { /* no memory */
59 h->obj_size = obj_size;
65 ipfw_ht_insert(struct ipfw_ht *h, const void *obj)
67 int i; /* array index */
68 struct new_obj *o, *ot;
70 i = h->hash(obj, h->table_size);
72 /* same key not allowed */
73 for (ot = h->table_ptr[i]; ot; ot = ot->next) {
74 if (h->cmp(obj, ot->obj, h->obj_size) == 0)
77 /* allocate a single chunk of memory */
78 o = malloc(sizeof(*o) + h->obj_size, h->mtype, M_NOWAIT);
81 bcopy(obj, o->obj, h->obj_size);
84 o->next = h->table_ptr[i];
93 ipfw_ht_remove(struct ipfw_ht *h, const void *obj)
96 struct new_obj *obj1, *prev;
98 i = h->hash(obj, h->table_size);
100 for (prev = NULL, obj1 = h->table_ptr[i]; obj1; obj1 = obj1->next) {
101 if (h->cmp(obj, obj1->obj, h->obj_size) != 0)
103 /* Object found, delete */
105 prev->next = obj1->next;
107 h->table_ptr[i] = obj1->next;
108 free(obj1, h->mtype);
112 return 1; /* Not found */
116 ipfw_ht_extract(struct ipfw_ht *h, const void *obj)
120 if (h == NULL || h->table_obj == 0)
123 i = h->hash(obj, h->table_size);
124 for (o = h->table_ptr[i]; o; o = o->next) {
125 if (h->cmp(o->obj, obj, h->obj_size) == 0)
132 ipfw_ht_destroy(struct ipfw_ht *h)
135 struct new_obj *cur, *next;
137 if (!h || !h->table_ptr)
139 for (i = 0; i < h->table_size; i++) {
140 for (cur = h->table_ptr[i]; cur; cur = next) {
145 free (h->table_ptr, h->mtype);
151 /* returns the number of elements in the table */
153 ipfw_ht_count(const struct ipfw_ht *h)
155 return h ? h->table_obj : 0;
159 table_next(struct ipfw_ht *h, const void *o)
164 if (h == NULL || h->table_obj == 0)
167 for (i = 0; i < h->table_size; i++)
169 return h->table_ptr[i]->obj;
170 return NULL; /* XXX should not happen */
173 /* here we can optimize if we can map o to the bucket,
174 * otherwise locate o and find the next one.
176 i = h->hash(o, h->table_size);
177 for (obj = h->table_ptr[i]; obj; obj = obj->next) {
178 if (h->cmp(obj->obj, o, h->obj_size) == 0)
181 if (obj && obj->next != NULL)
182 return obj->next->obj;
183 /* take the first of the next bucket */
184 for (i++; i < h->table_size; i++) {
186 return h->table_ptr[i]->obj;