~posulliv/drizzle/optimizer-style-cleanup

« back to all changes in this revision

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

  • Committer: Padraig O'Sullivan
  • Date: 2010-04-17 01:38:47 UTC
  • mfrom: (1237.9.238 bad-staging)
  • Revision ID: osullivan.padraig@gmail.com-20100417013847-ibjioqsfbmf5yg4g
Merge trunk.

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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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