9 struct hashset_entry
*next
, *previous
, *bucket_next
, *bucket_previous
;
17 struct hashset_entry
**data
;
18 struct hashset_entry
*first_entry
;
21 unsigned (*hash_func
) (const void *p
);
22 int (*compare_func
) (const void*a
, const void*b
);
25 struct hashset
*hashset_new(unsigned (*hash_func
) (const void *p
), int (*compare_func
) (const void*a
, const void*b
)) {
27 h
= malloc(sizeof(struct hashset
));
29 h
->data
= malloc(sizeof(struct hashset_entry
*)*(h
->size
= 1023));
31 memset(h
->data
, 0, sizeof(struct hashset_entry
*)*(h
->size
= 1023));
32 h
->first_entry
= NULL
;
34 h
->hash_func
= hash_func
? hash_func
: idxset_trivial_hash_func
;
35 h
->compare_func
= compare_func
? compare_func
: idxset_trivial_compare_func
;
39 static void remove(struct hashset
*h
, struct hashset_entry
*e
) {
43 e
->next
->previous
= e
->previous
;
45 e
->previous
->next
= e
->next
;
47 h
->first_entry
= e
->next
;
50 e
->bucket_next
->bucket_previous
= e
->bucket_previous
;
51 if (e
->bucket_previous
)
52 e
->bucket_previous
->bucket_next
= e
->bucket_next
;
54 h
->data
[e
->hash
] = e
->bucket_next
;
60 void hashset_free(struct hashset
*h
, void (*free_func
)(void *p
, void *userdata
), void *userdata
) {
63 while (h
->first_entry
) {
65 free_func(h
->first_entry
->value
, userdata
);
66 remove(h
, h
->first_entry
);
73 static struct hashset_entry
*get(struct hashset
*h
, unsigned hash
, const void *key
) {
74 struct hashset_entry
*e
;
76 for (e
= h
->data
[hash
]; e
; e
= e
->bucket_next
)
77 if (h
->compare_func(e
->key
, key
) == 0)
83 int hashset_put(struct hashset
*h
, const void *key
, void *value
) {
84 struct hashset_entry
*e
;
88 hash
= h
->hash_func(key
) % h
->size
;
90 if ((e
= get(h
, hash
, key
)))
93 e
= malloc(sizeof(struct hashset_entry
));
101 e
->next
= h
->first_entry
;
103 h
->first_entry
->previous
= e
;
106 e
->bucket_previous
= NULL
;
107 e
->bucket_next
= h
->data
[hash
];
109 h
->data
[hash
]->bucket_previous
= e
;
116 void* hashset_get(struct hashset
*h
, const void *key
) {
118 struct hashset_entry
*e
;
121 hash
= h
->hash_func(key
) % h
->size
;
123 if (!(e
= get(h
, hash
, key
)))
129 int hashset_remove(struct hashset
*h
, const void *key
) {
130 struct hashset_entry
*e
;
134 hash
= h
->hash_func(key
) % h
->size
;
136 if (!(e
= get(h
, hash
, key
)))
143 unsigned hashset_ncontents(struct hashset
*h
) {