1
/* Copyright (c) 2005 PrimeBase Technologies GmbH
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
* 2005-01-15 Paul McCullagh
23
#include "xt_config.h"
27
#include "pthread_xt.h"
29
#include "thread_xt.h"
30
#include "hashtab_xt.h"
32
XTHashTabPtr xt_new_hashtable(XTThreadPtr self, XTHTCompareFunc comp_func, XTHTHashFunc hash_func, XTHTFreeFunc free_func, xtBool with_lock, xtBool with_cond)
35
xtHashValue tab_size = 223;
37
ht = (XTHashTabPtr) xt_calloc(self, offsetof(XTHashTabRec, ht_items) + (sizeof(XTHashItemPtr) * tab_size));
38
ht->ht_comp_func = comp_func;
39
ht->ht_hash_func = hash_func;
40
ht->ht_free_func = free_func;
41
ht->ht_tab_size = tab_size;
43
if (with_lock || with_cond) {
44
ht->ht_lock = (xt_mutex_type *) xt_calloc(self, sizeof(xt_mutex_type));
46
xt_init_mutex_with_autoname(self, ht->ht_lock);
49
xt_free(self, ht->ht_lock);
57
ht->ht_cond = (xt_cond_type *) xt_calloc(self, sizeof(xt_cond_type));
59
xt_init_cond(self, ht->ht_cond);
62
xt_free(self, ht->ht_cond);
64
xt_free_hashtable(self, ht);
73
void xt_free_hashtable(XTThreadPtr self, XTHashTabPtr ht)
76
XTHashItemPtr item, tmp_item;
79
xt_lock_mutex(self, ht->ht_lock);
80
for (i=0; i<ht->ht_tab_size; i++) {
81
item = ht->ht_items[i];
84
(*ht->ht_free_func)(self, item->hi_data);
87
xt_free(self, tmp_item);
91
xt_unlock_mutex(self, ht->ht_lock);
93
xt_free_mutex(ht->ht_lock);
94
xt_free(self, ht->ht_lock);
97
xt_free_cond(ht->ht_cond);
98
xt_free(self, ht->ht_cond);
103
xtPublic void xt_ht_put(XTThreadPtr self, XTHashTabPtr ht, void *data)
105
XTHashItemPtr item = NULL;
108
pushr_(ht->ht_free_func, data);
109
h = (*ht->ht_hash_func)(FALSE, data);
110
item = (XTHashItemPtr) xt_malloc(self, sizeof(XTHashItemRec));
111
item->hi_data = data;
113
item->hi_next = ht->ht_items[h % ht->ht_tab_size];
114
ht->ht_items[h % ht->ht_tab_size] = item;
118
xtPublic void *xt_ht_get(XTThreadPtr XT_UNUSED(self), XTHashTabPtr ht, void *key)
124
h = (*ht->ht_hash_func)(TRUE, key);
126
item = ht->ht_items[h % ht->ht_tab_size];
128
if (item->hi_hash == h && (*ht->ht_comp_func)(key, item->hi_data)) {
129
data = item->hi_data;
132
item = item->hi_next;
138
xtPublic xtBool xt_ht_del(XTThreadPtr self, XTHashTabPtr ht, void *key)
140
XTHashItemPtr item, pitem = NULL;
142
xtBool found = FALSE;
144
h = (*ht->ht_hash_func)(TRUE, key);
146
item = ht->ht_items[h % ht->ht_tab_size];
148
if (item->hi_hash == h && (*ht->ht_comp_func)(key, item->hi_data)) {
152
data = item->hi_data;
154
/* Unlink the item: */
156
pitem->hi_next = item->hi_next;
158
ht->ht_items[h % ht->ht_tab_size] = item->hi_next;
164
if (ht->ht_free_func)
165
(*ht->ht_free_func)(self, data);
169
item = item->hi_next;
175
xtPublic xtHashValue xt_ht_hash(char *s)
178
register xtHashValue h = 0, g;
183
/* Assignment intended here! */
184
if ((g = h & 0xF0000000)) {
194
* The case-insensitive version of the hash...
196
xtPublic xtHashValue xt_ht_casehash(char *s)
199
register xtHashValue h = 0, g;
203
h = (h << 4) + tolower(*p);
204
/* Assignment intended here! */
205
if ((g = h & 0xF0000000)) {
214
xtPublic xtBool xt_ht_lock(XTThreadPtr self, XTHashTabPtr ht)
217
return xt_lock_mutex(self, ht->ht_lock);
221
xtPublic void xt_ht_unlock(XTThreadPtr self, XTHashTabPtr ht)
224
xt_unlock_mutex(self, ht->ht_lock);
227
xtPublic void xt_ht_wait(XTThreadPtr self, XTHashTabPtr ht)
229
xt_wait_cond(self, ht->ht_cond, ht->ht_lock);
232
xtPublic void xt_ht_timed_wait(XTThreadPtr self, XTHashTabPtr ht, u_long milli_sec)
234
xt_timed_wait_cond(self, ht->ht_cond, ht->ht_lock, milli_sec);
237
xtPublic void xt_ht_signal(XTThreadPtr self, XTHashTabPtr ht)
239
xt_signal_cond(self, ht->ht_cond);
242
xtPublic void xt_ht_enum(struct XTThread *XT_UNUSED(self), XTHashTabPtr ht, XTHashEnumPtr en)
249
xtPublic void *xt_ht_next(struct XTThread *XT_UNUSED(self), XTHashEnumPtr en)
252
en->he_item = en->he_item->hi_next;
254
return en->he_item->hi_data;
257
while (en->he_i < en->he_ht->ht_tab_size) {
258
if ((en->he_item = en->he_ht->ht_items[en->he_i]))
259
return en->he_item->hi_data;