This source file includes following definitions.
- FT_DECLARE
- hash
- hashtable_expand
- FT_DECLARE
- FT_DECLARE
- FT_DECLARE
- FT_DECLARE
- FT_DECLARE
- FT_DECLARE
- FT_DECLARE
- FT_DECLARE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include "private/ftdm_core.h"
35 #include "hashtable.h"
36 #include "hashtable_private.h"
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <math.h>
41
42
43
44
45
46
47 static const unsigned int primes[] = {
48 53, 97, 193, 389,
49 769, 1543, 3079, 6151,
50 12289, 24593, 49157, 98317,
51 196613, 393241, 786433, 1572869,
52 3145739, 6291469, 12582917, 25165843,
53 50331653, 100663319, 201326611, 402653189,
54 805306457, 1610612741
55 };
56 const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
57 const float max_load_factor = 0.65f;
58
59
60 FT_DECLARE(struct hashtable *)
61 create_hashtable(unsigned int minsize,
62 unsigned int (*hashf) (void*),
63 int (*eqf) (void*,void*))
64 {
65 struct hashtable *h;
66 unsigned int pindex, size = primes[0];
67
68 if (minsize > (1u << 30)) return NULL;
69
70 for (pindex=0; pindex < prime_table_length; pindex++) {
71 if (primes[pindex] > minsize) { size = primes[pindex]; break; }
72 }
73 h = (struct hashtable *)ftdm_malloc(sizeof(struct hashtable));
74 if (NULL == h) return NULL;
75 h->table = (struct entry **)ftdm_malloc(sizeof(struct entry*) * size);
76 if (NULL == h->table) { ftdm_safe_free(h); return NULL; }
77 memset(h->table, 0, size * sizeof(struct entry *));
78 h->tablelength = size;
79 h->primeindex = pindex;
80 h->entrycount = 0;
81 h->hashfn = hashf;
82 h->eqfn = eqf;
83 h->loadlimit = (unsigned int) ceil(size * max_load_factor);
84 return h;
85 }
86
87
88 unsigned int
89 hash(struct hashtable *h, void *k)
90 {
91
92
93 unsigned int i = h->hashfn(k);
94 i += ~(i << 9);
95 i ^= ((i >> 14) | (i << 18));
96 i += (i << 4);
97 i ^= ((i >> 10) | (i << 22));
98 return i;
99 }
100
101
102 static int
103 hashtable_expand(struct hashtable *h)
104 {
105
106 struct entry **newtable;
107 struct entry *e;
108 struct entry **pE;
109 unsigned int newsize, i, index;
110
111 if (h->primeindex == (prime_table_length - 1)) return 0;
112 newsize = primes[++(h->primeindex)];
113
114 newtable = (struct entry **)ftdm_malloc(sizeof(struct entry*) * newsize);
115 if (NULL != newtable)
116 {
117 memset(newtable, 0, newsize * sizeof(struct entry *));
118
119
120 for (i = 0; i < h->tablelength; i++) {
121 while (NULL != (e = h->table[i])) {
122 h->table[i] = e->next;
123 index = indexFor(newsize,e->h);
124 e->next = newtable[index];
125 newtable[index] = e;
126 }
127 }
128 ftdm_safe_free(h->table);
129 h->table = newtable;
130 }
131
132 else
133 {
134 newtable = (struct entry **)
135 realloc(h->table, newsize * sizeof(struct entry *));
136 if (NULL == newtable) { (h->primeindex)--; return 0; }
137 h->table = newtable;
138 memset(newtable[h->tablelength], 0, newsize - h->tablelength);
139 for (i = 0; i < h->tablelength; i++) {
140 for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
141 index = indexFor(newsize,e->h);
142 if (index == i)
143 {
144 pE = &(e->next);
145 }
146 else
147 {
148 *pE = e->next;
149 e->next = newtable[index];
150 newtable[index] = e;
151 }
152 }
153 }
154 }
155 h->tablelength = newsize;
156 h->loadlimit = (unsigned int) ceil(newsize * max_load_factor);
157 return -1;
158 }
159
160
161 FT_DECLARE(unsigned int)
162 hashtable_count(struct hashtable *h)
163 {
164 return h->entrycount;
165 }
166
167
168 FT_DECLARE(int)
169 hashtable_insert(struct hashtable *h, void *k, void *v, hashtable_flag_t flags)
170 {
171
172 unsigned int index;
173 struct entry *e;
174 if (++(h->entrycount) > h->loadlimit)
175 {
176
177
178
179
180 hashtable_expand(h);
181 }
182 e = (struct entry *)ftdm_malloc(sizeof(struct entry));
183 if (NULL == e) { --(h->entrycount); return 0; }
184 e->h = hash(h,k);
185 index = indexFor(h->tablelength,e->h);
186 e->k = k;
187 e->v = v;
188 e->flags = flags;
189 e->next = h->table[index];
190 h->table[index] = e;
191 return -1;
192 }
193
194
195 FT_DECLARE(void *)
196 hashtable_search(struct hashtable *h, void *k)
197 {
198 struct entry *e;
199 unsigned int hashvalue, index;
200 hashvalue = hash(h,k);
201 index = indexFor(h->tablelength,hashvalue);
202 e = h->table[index];
203 while (NULL != e)
204 {
205
206 if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
207 e = e->next;
208 }
209 return NULL;
210 }
211
212
213 FT_DECLARE(void *)
214 hashtable_remove(struct hashtable *h, void *k)
215 {
216
217
218
219 struct entry *e;
220 struct entry **pE;
221 void *v;
222 unsigned int hashvalue, index;
223
224 hashvalue = hash(h,k);
225 index = indexFor(h->tablelength,hash(h,k));
226 pE = &(h->table[index]);
227 e = *pE;
228 while (NULL != e)
229 {
230
231 if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
232 {
233 *pE = e->next;
234 h->entrycount--;
235 v = e->v;
236 if (e->flags & HASHTABLE_FLAG_FREE_KEY) {
237 freekey(e->k);
238 }
239 ftdm_safe_free(e);
240 return v;
241 }
242 pE = &(e->next);
243 e = e->next;
244 }
245 return NULL;
246 }
247
248
249
250 FT_DECLARE(void)
251 hashtable_destroy(struct hashtable *h)
252 {
253 unsigned int i;
254 struct entry *e, *f;
255 struct entry **table = h->table;
256
257 for (i = 0; i < h->tablelength; i++)
258 {
259 e = table[i];
260 while (NULL != e)
261 { f = e; e = e->next; if (f->flags & HASHTABLE_FLAG_FREE_KEY) freekey(f->k); if (f->flags & HASHTABLE_FLAG_FREE_VALUE) ftdm_safe_free(f->v); ftdm_safe_free(f); }
262 }
263
264 ftdm_safe_free(h->table);
265 ftdm_safe_free(h);
266 }
267
268 FT_DECLARE(struct hashtable_iterator *) hashtable_next(struct hashtable_iterator *i)
269 {
270
271 if (i->e) {
272 if ((i->e = i->e->next) != 0) {
273 return i;
274 } else {
275 i->pos++;
276 }
277 }
278
279 while(i->pos < i->h->tablelength && !i->h->table[i->pos]) {
280 i->pos++;
281 }
282
283 if (i->pos >= i->h->tablelength) {
284 return NULL;
285 }
286
287 if ((i->e = i->h->table[i->pos]) != 0) {
288 return i;
289 }
290
291 return NULL;
292 }
293
294 FT_DECLARE(struct hashtable_iterator *) hashtable_first(struct hashtable *h)
295 {
296 h->iterator.pos = 0;
297 h->iterator.e = NULL;
298 h->iterator.h = h;
299 return hashtable_next(&h->iterator);
300 }
301
302
303
304 FT_DECLARE(void) hashtable_this(struct hashtable_iterator *i, const void **key, int *klen, void **val)
305 {
306 if (i->e) {
307 if (key) {
308 *key = i->e->k;
309 }
310 if (klen) {
311 *klen = (int)strlen(i->e->k);
312 }
313 if (val) {
314 *val = i->e->v;
315 }
316 } else {
317 if (key) {
318 *key = NULL;
319 }
320 if (klen) {
321 *klen = 0;
322 }
323 if (val) {
324 *val = NULL;
325 }
326 }
327 }
328
329
330
331
332
333
334
335
336
337
338
339
340