~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbxt/src/hashtab_xt.cc

  • Committer: pcrews
  • Date: 2011-05-24 17:36:24 UTC
  • mfrom: (1099.4.232 drizzle)
  • Revision ID: pcrews@lucid32-20110524173624-mwr1bvq6fa1r01ao
Updated translations + 2011.05.18 tarball tag

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2005 PrimeBase Technologies GmbH
2
 
 *
3
 
 * PrimeBase XT
4
 
 *
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.
9
 
 *
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.
14
 
 *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
 
 *
19
 
 * 2005-01-15   Paul McCullagh
20
 
 *
21
 
 */
22
 
 
23
 
#include "xt_config.h"
24
 
 
25
 
#include <ctype.h>
26
 
 
27
 
#include "pthread_xt.h"
28
 
#include "heap_xt.h"
29
 
#include "thread_xt.h"
30
 
#include "hashtab_xt.h"
31
 
 
32
 
XTHashTabPtr xt_new_hashtable(XTThreadPtr self, XTHTCompareFunc comp_func, XTHTHashFunc hash_func, XTHTFreeFunc free_func, xtBool with_lock, xtBool with_cond)
33
 
{
34
 
        XTHashTabPtr    ht;
35
 
        xtHashValue             tab_size = 223;
36
 
 
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;
42
 
 
43
 
        if (with_lock || with_cond) {
44
 
                ht->ht_lock = (xt_mutex_type *) xt_calloc(self, sizeof(xt_mutex_type));
45
 
                try_(a) {
46
 
                        xt_init_mutex_with_autoname(self, ht->ht_lock);
47
 
                }
48
 
                catch_(a) {
49
 
                        xt_free(self, ht->ht_lock);
50
 
                        xt_free(self, ht);
51
 
                        throw_();
52
 
                }
53
 
                cont_(a);
54
 
        }
55
 
 
56
 
        if (with_cond) {
57
 
                ht->ht_cond = (xt_cond_type *) xt_calloc(self, sizeof(xt_cond_type));
58
 
                try_(b) {
59
 
                        xt_init_cond(self, ht->ht_cond);
60
 
                }
61
 
                catch_(b) {
62
 
                        xt_free(self, ht->ht_cond);
63
 
                        ht->ht_cond = NULL;
64
 
                        xt_free_hashtable(self, ht);
65
 
                        throw_();
66
 
                }
67
 
                cont_(b);
68
 
        }
69
 
 
70
 
        return ht;
71
 
}
72
 
 
73
 
void xt_free_hashtable(XTThreadPtr self, XTHashTabPtr ht)
74
 
{
75
 
        xtHashValue             i;
76
 
        XTHashItemPtr   item, tmp_item;
77
 
 
78
 
        if (ht->ht_lock)
79
 
                xt_lock_mutex(self, ht->ht_lock);
80
 
        for (i=0; i<ht->ht_tab_size; i++) {
81
 
                item = ht->ht_items[i];
82
 
                while (item) {
83
 
                        if (ht->ht_free_func)
84
 
                                (*ht->ht_free_func)(self, item->hi_data);
85
 
                        tmp_item = item;
86
 
                        item = item->hi_next;
87
 
                        xt_free(self, tmp_item);
88
 
                }
89
 
        }
90
 
        if (ht->ht_lock)
91
 
                xt_unlock_mutex(self, ht->ht_lock);
92
 
        if (ht->ht_lock) {
93
 
                xt_free_mutex(ht->ht_lock);
94
 
                xt_free(self, ht->ht_lock);
95
 
        }
96
 
        if (ht->ht_cond) {
97
 
                xt_free_cond(ht->ht_cond);
98
 
                xt_free(self, ht->ht_cond);
99
 
        }
100
 
        xt_free(self, ht);
101
 
}
102
 
 
103
 
xtPublic void xt_ht_put(XTThreadPtr self, XTHashTabPtr ht, void *data)
104
 
{
105
 
        XTHashItemPtr   item = NULL;
106
 
        xtHashValue             h;
107
 
 
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;
112
 
        item->hi_hash = h;
113
 
        item->hi_next = ht->ht_items[h % ht->ht_tab_size];
114
 
        ht->ht_items[h % ht->ht_tab_size] = item;
115
 
        popr_();
116
 
}
117
 
 
118
 
xtPublic void *xt_ht_get(XTThreadPtr XT_UNUSED(self), XTHashTabPtr ht, void *key)
119
 
{
120
 
        XTHashItemPtr   item;
121
 
        xtHashValue             h;
122
 
        void                    *data = NULL;
123
 
 
124
 
        h = (*ht->ht_hash_func)(TRUE, key);
125
 
 
126
 
        item = ht->ht_items[h % ht->ht_tab_size];
127
 
        while (item) {
128
 
                if (item->hi_hash == h && (*ht->ht_comp_func)(key, item->hi_data)) {
129
 
                        data = item->hi_data;
130
 
                        break;
131
 
                }
132
 
                item = item->hi_next;
133
 
        }
134
 
        
135
 
        return data;
136
 
}
137
 
 
138
 
xtPublic xtBool xt_ht_del(XTThreadPtr self, XTHashTabPtr ht, void *key)
139
 
{
140
 
        XTHashItemPtr   item, pitem = NULL;
141
 
        xtHashValue             h;
142
 
        xtBool                  found = FALSE;
143
 
 
144
 
        h = (*ht->ht_hash_func)(TRUE, key);
145
 
 
146
 
        item = ht->ht_items[h % ht->ht_tab_size];
147
 
        while (item) {
148
 
                if (item->hi_hash == h && (*ht->ht_comp_func)(key, item->hi_data)) {
149
 
                        void *data;
150
 
 
151
 
                        found = TRUE;
152
 
                        data = item->hi_data;
153
 
                        
154
 
                        /* Unlink the item: */
155
 
                        if (pitem)
156
 
                                pitem->hi_next = item->hi_next;
157
 
                        else
158
 
                                ht->ht_items[h % ht->ht_tab_size] = item->hi_next;
159
 
 
160
 
                        /* Free the item: */
161
 
                        xt_free(self, item);
162
 
 
163
 
                        /* Free the data */
164
 
                        if (ht->ht_free_func)
165
 
                                (*ht->ht_free_func)(self, data);
166
 
                        break;
167
 
                }
168
 
                pitem = item;
169
 
                item = item->hi_next;
170
 
        }
171
 
        
172
 
        return found;
173
 
}
174
 
 
175
 
xtPublic xtHashValue xt_ht_hash(char *s)
176
 
{
177
 
        register char *p;
178
 
        register xtHashValue h = 0, g;
179
 
        
180
 
        p = s; 
181
 
        while (*p) {
182
 
                h = (h << 4) + *p;
183
 
                /* Assignment intended here! */
184
 
                if ((g = h & 0xF0000000)) {
185
 
                        h = h ^ (g >> 24);
186
 
                        h = h ^ g;
187
 
                }
188
 
                p++;
189
 
        }
190
 
        return h;
191
 
}
192
 
 
193
 
/*
194
 
 * The case-insensitive version of the hash...
195
 
 */
196
 
xtPublic xtHashValue xt_ht_casehash(char *s)
197
 
{
198
 
        register char *p;
199
 
        register xtHashValue h = 0, g;
200
 
        
201
 
        p = s; 
202
 
        while (*p) {
203
 
                h = (h << 4) + tolower(*p);
204
 
                /* Assignment intended here! */
205
 
                if ((g = h & 0xF0000000)) {
206
 
                        h = h ^ (g >> 24);
207
 
                        h = h ^ g;
208
 
                }
209
 
                p++;
210
 
        }
211
 
        return h;
212
 
}
213
 
 
214
 
xtPublic xtBool xt_ht_lock(XTThreadPtr self, XTHashTabPtr ht)
215
 
{
216
 
        if (ht->ht_lock)
217
 
                return xt_lock_mutex(self, ht->ht_lock);
218
 
        return TRUE;
219
 
}
220
 
 
221
 
xtPublic void xt_ht_unlock(XTThreadPtr self, XTHashTabPtr ht)
222
 
{
223
 
        if (ht->ht_lock)
224
 
                xt_unlock_mutex(self, ht->ht_lock);
225
 
}
226
 
 
227
 
xtPublic void xt_ht_wait(XTThreadPtr self, XTHashTabPtr ht)
228
 
{
229
 
        xt_wait_cond(self, ht->ht_cond, ht->ht_lock);
230
 
}
231
 
 
232
 
xtPublic void xt_ht_timed_wait(XTThreadPtr self, XTHashTabPtr ht, u_long milli_sec)
233
 
{
234
 
        xt_timed_wait_cond(self, ht->ht_cond, ht->ht_lock, milli_sec);
235
 
}
236
 
 
237
 
xtPublic void xt_ht_signal(XTThreadPtr self, XTHashTabPtr ht)
238
 
{
239
 
        xt_signal_cond(self, ht->ht_cond);
240
 
}
241
 
 
242
 
xtPublic void xt_ht_enum(struct XTThread *XT_UNUSED(self), XTHashTabPtr ht, XTHashEnumPtr en)
243
 
{
244
 
        en->he_i = 0;
245
 
        en->he_item = NULL;
246
 
        en->he_ht = ht;
247
 
}
248
 
 
249
 
xtPublic void *xt_ht_next(struct XTThread *XT_UNUSED(self), XTHashEnumPtr en)
250
 
{
251
 
        if (en->he_item) {
252
 
                en->he_item = en->he_item->hi_next;
253
 
                if (en->he_item)
254
 
                        return en->he_item->hi_data;
255
 
                en->he_i++;
256
 
        }
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;
260
 
                en->he_i++;
261
 
        }
262
 
        return NULL;
263
 
}
264