1d4c6f1e6SMasatake YAMATO /*
2d4c6f1e6SMasatake YAMATO *
3d4c6f1e6SMasatake YAMATO * Copyright (c) 2014, Red Hat, Inc.
4d4c6f1e6SMasatake YAMATO * Copyright (c) 2014, Masatake YAMATO
5d4c6f1e6SMasatake YAMATO *
6d4c6f1e6SMasatake YAMATO * This source code is released for free distribution under the terms of the
70ce38835Sviccuad * GNU General Public License version 2 or (at your option) any later version.
8d4c6f1e6SMasatake YAMATO *
9d4c6f1e6SMasatake YAMATO * Defines hashtable
10d4c6f1e6SMasatake YAMATO */
11d4c6f1e6SMasatake YAMATO
122e74dc85SMasatake YAMATO #include "general.h"
13d4c6f1e6SMasatake YAMATO #include "htable.h"
14d4c6f1e6SMasatake YAMATO
15d4c6f1e6SMasatake YAMATO #ifndef MAIN
16d4c6f1e6SMasatake YAMATO #include <stdio.h>
17d4c6f1e6SMasatake YAMATO #include "routines.h"
18d4c6f1e6SMasatake YAMATO #else
19d4c6f1e6SMasatake YAMATO #include <stdlib.h>
20d4c6f1e6SMasatake YAMATO #ifndef xCalloc
21d4c6f1e6SMasatake YAMATO #define xCalloc(n,Type) (Type *)calloc((size_t)(n), sizeof (Type))
22d4c6f1e6SMasatake YAMATO #endif
23d4c6f1e6SMasatake YAMATO #ifndef xMalloc
24d4c6f1e6SMasatake YAMATO #define xMalloc(n,Type) (Type *)malloc((size_t)(n) * sizeof (Type))
25d4c6f1e6SMasatake YAMATO #endif
26d4c6f1e6SMasatake YAMATO #ifndef eFree
27d4c6f1e6SMasatake YAMATO #define eFree(x) free(x)
28d4c6f1e6SMasatake YAMATO #endif
29d4c6f1e6SMasatake YAMATO #endif /* MAIN */
30d4c6f1e6SMasatake YAMATO
31f2f92e1fSMasatake YAMATO #include <string.h>
32f2f92e1fSMasatake YAMATO
33f2f92e1fSMasatake YAMATO
34d4c6f1e6SMasatake YAMATO typedef struct sHashEntry hentry;
35d4c6f1e6SMasatake YAMATO struct sHashEntry {
36d4c6f1e6SMasatake YAMATO void *key;
37d4c6f1e6SMasatake YAMATO void *value;
38d4c6f1e6SMasatake YAMATO hentry *next;
39d4c6f1e6SMasatake YAMATO };
40d4c6f1e6SMasatake YAMATO
41d4c6f1e6SMasatake YAMATO struct sHashTable {
42d4c6f1e6SMasatake YAMATO hentry** table;
43d4c6f1e6SMasatake YAMATO unsigned int size;
44d4c6f1e6SMasatake YAMATO hashTableHashFunc hashfn;
45d4c6f1e6SMasatake YAMATO hashTableEqualFunc equalfn;
469be5bba1SMasatake YAMATO hashTableDeleteFunc keyfreefn;
479be5bba1SMasatake YAMATO hashTableDeleteFunc valfreefn;
48*553897a6SMasatake YAMATO void *valForNotUnknownKey;
49*553897a6SMasatake YAMATO hashTableDeleteFunc valForNotUnknownKeyfreefn;
50d4c6f1e6SMasatake YAMATO };
51d4c6f1e6SMasatake YAMATO
52990f41faSMasatake YAMATO struct chainTracker {
53990f41faSMasatake YAMATO const void *const target_key;
54990f41faSMasatake YAMATO hashTableForeachFunc user_proc;
55990f41faSMasatake YAMATO void *user_data;
56990f41faSMasatake YAMATO hashTableEqualFunc equalfn;
57990f41faSMasatake YAMATO };
58d4c6f1e6SMasatake YAMATO
entry_new(void * key,void * value,hentry * next)59d4c6f1e6SMasatake YAMATO static hentry* entry_new (void *key, void *value, hentry* next)
60d4c6f1e6SMasatake YAMATO {
61d4c6f1e6SMasatake YAMATO hentry* entry = xMalloc (1, hentry);
62d4c6f1e6SMasatake YAMATO
63d4c6f1e6SMasatake YAMATO entry->key = key;
64d4c6f1e6SMasatake YAMATO entry->value = value;
65d4c6f1e6SMasatake YAMATO entry->next = next;
66d4c6f1e6SMasatake YAMATO
67d4c6f1e6SMasatake YAMATO return entry;
68d4c6f1e6SMasatake YAMATO }
69d4c6f1e6SMasatake YAMATO
entry_reset(hentry * entry,void * newkey,void * newval,hashTableDeleteFunc keyfreefn,hashTableDeleteFunc valfreefn)702b57298dSMasatake YAMATO static void entry_reset (hentry* entry,
712b57298dSMasatake YAMATO void *newkey,
722b57298dSMasatake YAMATO void *newval,
732b57298dSMasatake YAMATO hashTableDeleteFunc keyfreefn,
742b57298dSMasatake YAMATO hashTableDeleteFunc valfreefn)
752b57298dSMasatake YAMATO {
762b57298dSMasatake YAMATO if (keyfreefn)
772b57298dSMasatake YAMATO keyfreefn (entry->key);
782b57298dSMasatake YAMATO if (valfreefn)
792b57298dSMasatake YAMATO valfreefn (entry->value);
802b57298dSMasatake YAMATO entry->key = newkey;
812b57298dSMasatake YAMATO entry->value = newval;
822b57298dSMasatake YAMATO }
832b57298dSMasatake YAMATO
entry_destroy(hentry * entry,hashTableDeleteFunc keyfreefn,hashTableDeleteFunc valfreefn)84d4c6f1e6SMasatake YAMATO static hentry* entry_destroy (hentry* entry,
859be5bba1SMasatake YAMATO hashTableDeleteFunc keyfreefn,
869be5bba1SMasatake YAMATO hashTableDeleteFunc valfreefn)
87d4c6f1e6SMasatake YAMATO {
88d4c6f1e6SMasatake YAMATO hentry* tmp;
89d4c6f1e6SMasatake YAMATO
902b57298dSMasatake YAMATO entry_reset (entry, NULL, NULL, keyfreefn, valfreefn);
91d4c6f1e6SMasatake YAMATO tmp = entry->next;
92d4c6f1e6SMasatake YAMATO eFree (entry);
93d4c6f1e6SMasatake YAMATO
94d4c6f1e6SMasatake YAMATO return tmp;
95d4c6f1e6SMasatake YAMATO }
96d4c6f1e6SMasatake YAMATO
entry_reclaim(hentry * entry,hashTableDeleteFunc keyfreefn,hashTableDeleteFunc valfreefn)97d4c6f1e6SMasatake YAMATO static void entry_reclaim (hentry* entry,
989be5bba1SMasatake YAMATO hashTableDeleteFunc keyfreefn,
999be5bba1SMasatake YAMATO hashTableDeleteFunc valfreefn)
100d4c6f1e6SMasatake YAMATO {
101d4c6f1e6SMasatake YAMATO while (entry)
102d4c6f1e6SMasatake YAMATO entry = entry_destroy (entry, keyfreefn, valfreefn);
103d4c6f1e6SMasatake YAMATO }
104d4c6f1e6SMasatake YAMATO
entry_find(hentry * entry,const void * const key,hashTableEqualFunc equalfn,void * valForNotUnknownKey)105*553897a6SMasatake YAMATO static void *entry_find (hentry* entry, const void* const key, hashTableEqualFunc equalfn,
106*553897a6SMasatake YAMATO void *valForNotUnknownKey)
107d4c6f1e6SMasatake YAMATO {
108d4c6f1e6SMasatake YAMATO while (entry)
109d4c6f1e6SMasatake YAMATO {
110d4c6f1e6SMasatake YAMATO if (equalfn( key, entry->key))
111d4c6f1e6SMasatake YAMATO return entry->value;
112d4c6f1e6SMasatake YAMATO entry = entry->next;
113d4c6f1e6SMasatake YAMATO }
114*553897a6SMasatake YAMATO return valForNotUnknownKey;
115d4c6f1e6SMasatake YAMATO }
116d4c6f1e6SMasatake YAMATO
entry_delete(hentry ** entry,const void * key,hashTableEqualFunc equalfn,hashTableDeleteFunc keyfreefn,hashTableDeleteFunc valfreefn)1178e77de48SMasatake YAMATO static bool entry_delete (hentry **entry, const void *key, hashTableEqualFunc equalfn,
1189be5bba1SMasatake YAMATO hashTableDeleteFunc keyfreefn, hashTableDeleteFunc valfreefn)
119d4c6f1e6SMasatake YAMATO {
120d4c6f1e6SMasatake YAMATO while (*entry)
121d4c6f1e6SMasatake YAMATO {
122d4c6f1e6SMasatake YAMATO if (equalfn (key, (*entry)->key))
123d4c6f1e6SMasatake YAMATO {
124d4c6f1e6SMasatake YAMATO *entry = entry_destroy (*entry, keyfreefn, valfreefn);
125ce990805SThomas Braun return true;
126d4c6f1e6SMasatake YAMATO }
127b554e8daSMasatake YAMATO entry = &((*entry)->next);
128d4c6f1e6SMasatake YAMATO }
129ce990805SThomas Braun return false;
130d4c6f1e6SMasatake YAMATO }
131d4c6f1e6SMasatake YAMATO
entry_update(hentry * entry,void * key,void * value,hashTableEqualFunc equalfn,hashTableDeleteFunc keyfreefn,hashTableDeleteFunc valfreefn)1322b57298dSMasatake YAMATO static bool entry_update (hentry *entry, void *key, void *value, hashTableEqualFunc equalfn,
1332b57298dSMasatake YAMATO hashTableDeleteFunc keyfreefn, hashTableDeleteFunc valfreefn)
1342b57298dSMasatake YAMATO {
1352b57298dSMasatake YAMATO while (entry)
1362b57298dSMasatake YAMATO {
1372b57298dSMasatake YAMATO if (equalfn (key, entry->key))
1382b57298dSMasatake YAMATO {
1392b57298dSMasatake YAMATO entry_reset (entry, key, value, keyfreefn, valfreefn);
1402b57298dSMasatake YAMATO return true;
1412b57298dSMasatake YAMATO }
1422b57298dSMasatake YAMATO entry = entry->next;
1432b57298dSMasatake YAMATO }
1442b57298dSMasatake YAMATO return false;
1452b57298dSMasatake YAMATO }
1462b57298dSMasatake YAMATO
entry_foreach(hentry * entry,hashTableForeachFunc proc,void * user_data)147994c1ccfSMasatake YAMATO static bool entry_foreach (hentry *entry, hashTableForeachFunc proc, void *user_data)
148d4c6f1e6SMasatake YAMATO {
149d4c6f1e6SMasatake YAMATO while (entry)
150d4c6f1e6SMasatake YAMATO {
151994c1ccfSMasatake YAMATO if (!proc (entry->key, entry->value, user_data))
152994c1ccfSMasatake YAMATO return false;
153d4c6f1e6SMasatake YAMATO entry = entry->next;
154d4c6f1e6SMasatake YAMATO }
155994c1ccfSMasatake YAMATO return true;
156d4c6f1e6SMasatake YAMATO }
157d4c6f1e6SMasatake YAMATO
hashTableNew(unsigned int size,hashTableHashFunc hashfn,hashTableEqualFunc equalfn,hashTableDeleteFunc keyfreefn,hashTableDeleteFunc valfreefn)158d4c6f1e6SMasatake YAMATO extern hashTable *hashTableNew (unsigned int size,
159d4c6f1e6SMasatake YAMATO hashTableHashFunc hashfn,
160d4c6f1e6SMasatake YAMATO hashTableEqualFunc equalfn,
1619be5bba1SMasatake YAMATO hashTableDeleteFunc keyfreefn,
1629be5bba1SMasatake YAMATO hashTableDeleteFunc valfreefn)
163d4c6f1e6SMasatake YAMATO {
164d4c6f1e6SMasatake YAMATO hashTable *htable;
165d4c6f1e6SMasatake YAMATO
166d4c6f1e6SMasatake YAMATO htable = xMalloc (1, hashTable);
167d4c6f1e6SMasatake YAMATO htable->size = size;
168d4c6f1e6SMasatake YAMATO htable->table = xCalloc (size, hentry*);
169d4c6f1e6SMasatake YAMATO
170d4c6f1e6SMasatake YAMATO htable->hashfn = hashfn;
171d4c6f1e6SMasatake YAMATO htable->equalfn = equalfn;
172d4c6f1e6SMasatake YAMATO htable->keyfreefn = keyfreefn;
173d4c6f1e6SMasatake YAMATO htable->valfreefn = valfreefn;
174*553897a6SMasatake YAMATO htable->valForNotUnknownKey = NULL;
175*553897a6SMasatake YAMATO htable->valForNotUnknownKeyfreefn = NULL;
176d4c6f1e6SMasatake YAMATO
177d4c6f1e6SMasatake YAMATO return htable;
178d4c6f1e6SMasatake YAMATO }
179d4c6f1e6SMasatake YAMATO
hashTableSetValueForUnknownKey(hashTable * htable,void * val,hashTableDeleteFunc valfreefn)180*553897a6SMasatake YAMATO extern void hashTableSetValueForUnknownKey (hashTable *htable,
181*553897a6SMasatake YAMATO void *val,
182*553897a6SMasatake YAMATO hashTableDeleteFunc valfreefn)
183c3062a32SMasatake YAMATO {
184*553897a6SMasatake YAMATO if (htable->valfreefn)
185*553897a6SMasatake YAMATO htable->valfreefn (htable->valForNotUnknownKey);
186*553897a6SMasatake YAMATO
187*553897a6SMasatake YAMATO htable->valForNotUnknownKey = val;
188*553897a6SMasatake YAMATO htable->valForNotUnknownKeyfreefn = valfreefn;
189c3062a32SMasatake YAMATO }
190c3062a32SMasatake YAMATO
hashTableDelete(hashTable * htable)191d4c6f1e6SMasatake YAMATO extern void hashTableDelete (hashTable *htable)
192d4c6f1e6SMasatake YAMATO {
193d41b6eb3SMasatake YAMATO if (!htable)
194d41b6eb3SMasatake YAMATO return;
195d41b6eb3SMasatake YAMATO
196d41b6eb3SMasatake YAMATO hashTableClear (htable);
197d41b6eb3SMasatake YAMATO
198*553897a6SMasatake YAMATO if (htable->valForNotUnknownKeyfreefn)
199*553897a6SMasatake YAMATO htable->valForNotUnknownKeyfreefn (htable->valForNotUnknownKey);
200d41b6eb3SMasatake YAMATO eFree (htable->table);
201d41b6eb3SMasatake YAMATO eFree (htable);
202d41b6eb3SMasatake YAMATO }
203d41b6eb3SMasatake YAMATO
hashTableClear(hashTable * htable)204d41b6eb3SMasatake YAMATO extern void hashTableClear (hashTable *htable)
205d41b6eb3SMasatake YAMATO {
206d4c6f1e6SMasatake YAMATO unsigned int i;
207d4c6f1e6SMasatake YAMATO if (!htable)
208d4c6f1e6SMasatake YAMATO return;
209d4c6f1e6SMasatake YAMATO
210d4c6f1e6SMasatake YAMATO for (i = 0; i < htable->size; i++)
211d4c6f1e6SMasatake YAMATO {
212d4c6f1e6SMasatake YAMATO hentry *entry;
213d4c6f1e6SMasatake YAMATO
214d4c6f1e6SMasatake YAMATO entry = htable->table[i];
215d4c6f1e6SMasatake YAMATO entry_reclaim (entry, htable->keyfreefn, htable->valfreefn);
216d4c6f1e6SMasatake YAMATO htable->table[i] = NULL;
217d4c6f1e6SMasatake YAMATO }
218d4c6f1e6SMasatake YAMATO }
219d4c6f1e6SMasatake YAMATO
hashTablePutItem(hashTable * htable,void * key,void * value)220d4c6f1e6SMasatake YAMATO extern void hashTablePutItem (hashTable *htable, void *key, void *value)
221d4c6f1e6SMasatake YAMATO {
222d4c6f1e6SMasatake YAMATO unsigned int i;
223d4c6f1e6SMasatake YAMATO
224d4c6f1e6SMasatake YAMATO i = htable->hashfn (key) % htable->size;
225d4c6f1e6SMasatake YAMATO htable->table[i] = entry_new(key, value, htable->table[i]);
226d4c6f1e6SMasatake YAMATO }
227d4c6f1e6SMasatake YAMATO
hashTableGetItem(hashTable * htable,const void * key)2281b8321bfSMasatake YAMATO extern void* hashTableGetItem (hashTable *htable, const void * key)
229d4c6f1e6SMasatake YAMATO {
230d4c6f1e6SMasatake YAMATO unsigned int i;
231d4c6f1e6SMasatake YAMATO
232d4c6f1e6SMasatake YAMATO i = htable->hashfn (key) % htable->size;
233*553897a6SMasatake YAMATO return entry_find(htable->table[i], key, htable->equalfn, htable->valForNotUnknownKey);
234d4c6f1e6SMasatake YAMATO }
235d4c6f1e6SMasatake YAMATO
hashTableDeleteItem(hashTable * htable,const void * key)2368e77de48SMasatake YAMATO extern bool hashTableDeleteItem (hashTable *htable, const void *key)
237d4c6f1e6SMasatake YAMATO {
238d4c6f1e6SMasatake YAMATO unsigned int i;
239d4c6f1e6SMasatake YAMATO
240d4c6f1e6SMasatake YAMATO i = htable->hashfn (key) % htable->size;
241d4c6f1e6SMasatake YAMATO return entry_delete(&htable->table[i], key,
242d4c6f1e6SMasatake YAMATO htable->equalfn, htable->keyfreefn, htable->valfreefn);
243d4c6f1e6SMasatake YAMATO }
244d4c6f1e6SMasatake YAMATO
hashTableUpdateItem(hashTable * htable,void * key,void * value)2452b57298dSMasatake YAMATO extern bool hashTableUpdateItem (hashTable *htable, void *key, void *value)
2462b57298dSMasatake YAMATO {
2472b57298dSMasatake YAMATO unsigned int i;
2482b57298dSMasatake YAMATO
2492b57298dSMasatake YAMATO i = htable->hashfn (key) % htable->size;
2502b57298dSMasatake YAMATO bool r = entry_update(htable->table[i], key, value,
2512b57298dSMasatake YAMATO htable->equalfn, htable->keyfreefn, htable->valfreefn);
2522b57298dSMasatake YAMATO if (!r)
2532b57298dSMasatake YAMATO htable->table[i] = entry_new(key, value, htable->table[i]);
2542b57298dSMasatake YAMATO return r;
2552b57298dSMasatake YAMATO }
2562b57298dSMasatake YAMATO
hashTableHasItem(hashTable * htable,const void * key)2571b8321bfSMasatake YAMATO extern bool hashTableHasItem (hashTable *htable, const void *key)
258d4c6f1e6SMasatake YAMATO {
259*553897a6SMasatake YAMATO return hashTableGetItem (htable, key) == htable->valForNotUnknownKey? false: true;
260d4c6f1e6SMasatake YAMATO }
261d4c6f1e6SMasatake YAMATO
hashTableForeachItem(hashTable * htable,hashTableForeachFunc proc,void * user_data)262994c1ccfSMasatake YAMATO extern bool hashTableForeachItem (hashTable *htable, hashTableForeachFunc proc, void *user_data)
263d4c6f1e6SMasatake YAMATO {
264d4c6f1e6SMasatake YAMATO unsigned int i;
265d4c6f1e6SMasatake YAMATO
266d4c6f1e6SMasatake YAMATO for (i = 0; i < htable->size; i++)
267994c1ccfSMasatake YAMATO if (!entry_foreach(htable->table[i], proc, user_data))
268994c1ccfSMasatake YAMATO return false;
269994c1ccfSMasatake YAMATO return true;
270d4c6f1e6SMasatake YAMATO }
271d4c6f1e6SMasatake YAMATO
track_chain(const void * const key,void * value,void * chain_data)272990f41faSMasatake YAMATO static bool track_chain (const void *const key, void *value, void *chain_data)
273990f41faSMasatake YAMATO {
274990f41faSMasatake YAMATO struct chainTracker *chain_tracker = chain_data;
275990f41faSMasatake YAMATO
276990f41faSMasatake YAMATO if (chain_tracker->equalfn (chain_tracker->target_key, key))
277990f41faSMasatake YAMATO {
278990f41faSMasatake YAMATO if (! chain_tracker->user_proc (key, value, chain_tracker->user_data))
279990f41faSMasatake YAMATO return false;
280990f41faSMasatake YAMATO }
281990f41faSMasatake YAMATO return true;
282990f41faSMasatake YAMATO }
283990f41faSMasatake YAMATO
hashTableForeachItemOnChain(hashTable * htable,const void * key,hashTableForeachFunc proc,void * user_data)284990f41faSMasatake YAMATO extern bool hashTableForeachItemOnChain (hashTable *htable, const void *key, hashTableForeachFunc proc, void *user_data)
285990f41faSMasatake YAMATO {
286990f41faSMasatake YAMATO unsigned int i;
287990f41faSMasatake YAMATO struct chainTracker chain_tracker = {
288990f41faSMasatake YAMATO .target_key = key,
289990f41faSMasatake YAMATO .user_proc = proc,
290990f41faSMasatake YAMATO .user_data = user_data,
291990f41faSMasatake YAMATO .equalfn = htable->equalfn,
292990f41faSMasatake YAMATO };
293990f41faSMasatake YAMATO
294990f41faSMasatake YAMATO i = htable->hashfn (key) % htable->size;
295990f41faSMasatake YAMATO if (!entry_foreach(htable->table[i], track_chain, &chain_tracker))
296990f41faSMasatake YAMATO return false;
297990f41faSMasatake YAMATO return true;
298990f41faSMasatake YAMATO }
299990f41faSMasatake YAMATO
count(const void * const key CTAGS_ATTR_UNUSED,void * value CTAGS_ATTR_UNUSED,void * data)3008e77de48SMasatake YAMATO static bool count (const void *const key CTAGS_ATTR_UNUSED, void *value CTAGS_ATTR_UNUSED, void *data)
301d4c6f1e6SMasatake YAMATO {
302d4c6f1e6SMasatake YAMATO int *c = data;
303d4c6f1e6SMasatake YAMATO ++*c;
304994c1ccfSMasatake YAMATO return true;
305d4c6f1e6SMasatake YAMATO }
306d4c6f1e6SMasatake YAMATO
hashTableCountItem(hashTable * htable)307d198ad0cSMasatake YAMATO extern unsigned int hashTableCountItem (hashTable *htable)
308d4c6f1e6SMasatake YAMATO {
309d4c6f1e6SMasatake YAMATO int c = 0;
310d4c6f1e6SMasatake YAMATO hashTableForeachItem (htable, count, &c);
311d4c6f1e6SMasatake YAMATO return c;
312d4c6f1e6SMasatake YAMATO }
3131b8321bfSMasatake YAMATO
hashPtrhash(const void * const x)3141b8321bfSMasatake YAMATO unsigned int hashPtrhash (const void * const x)
315d4c6f1e6SMasatake YAMATO {
316d4c6f1e6SMasatake YAMATO union {
317a0398817SMasatake YAMATO const void * ptr;
318d4c6f1e6SMasatake YAMATO unsigned int ui;
319a0398817SMasatake YAMATO } v;
320a0398817SMasatake YAMATO v.ui = 0;
321a0398817SMasatake YAMATO v.ptr = x;
322d4c6f1e6SMasatake YAMATO
323d4c6f1e6SMasatake YAMATO return v.ui;
324d4c6f1e6SMasatake YAMATO }
325d4c6f1e6SMasatake YAMATO
hashPtreq(const void * const a,const void * const b)3261b8321bfSMasatake YAMATO bool hashPtreq (const void *const a, const void *const b)
327d4c6f1e6SMasatake YAMATO {
328ce990805SThomas Braun return (a == b)? true: false;
329d4c6f1e6SMasatake YAMATO }
330d4c6f1e6SMasatake YAMATO
331f2f92e1fSMasatake YAMATO
332f2f92e1fSMasatake YAMATO /* http://www.cse.yorku.ca/~oz/hash.html */
333f2f92e1fSMasatake YAMATO static unsigned long
djb2(const unsigned char * str)3341b8321bfSMasatake YAMATO djb2(const unsigned char *str)
335f2f92e1fSMasatake YAMATO {
336f2f92e1fSMasatake YAMATO unsigned long hash = 5381;
337f2f92e1fSMasatake YAMATO int c;
338f2f92e1fSMasatake YAMATO
339f2f92e1fSMasatake YAMATO while ((c = *str++))
340f2f92e1fSMasatake YAMATO hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
341f2f92e1fSMasatake YAMATO
342f2f92e1fSMasatake YAMATO return hash;
343f2f92e1fSMasatake YAMATO }
344f2f92e1fSMasatake YAMATO
34593ce570cSMasatake YAMATO static unsigned long
casedjb2(const unsigned char * str)34693ce570cSMasatake YAMATO casedjb2(const unsigned char *str)
34793ce570cSMasatake YAMATO {
34893ce570cSMasatake YAMATO unsigned long hash = 5381;
34993ce570cSMasatake YAMATO int c;
35093ce570cSMasatake YAMATO
35193ce570cSMasatake YAMATO while ((c = *str++))
35293ce570cSMasatake YAMATO {
35393ce570cSMasatake YAMATO if (('a' <= c) && (c <= 'z'))
35493ce570cSMasatake YAMATO c += ('A' - 'a');
35593ce570cSMasatake YAMATO hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
35693ce570cSMasatake YAMATO }
35793ce570cSMasatake YAMATO
35893ce570cSMasatake YAMATO return hash;
35993ce570cSMasatake YAMATO }
36093ce570cSMasatake YAMATO
36193ce570cSMasatake YAMATO
hashCstrhash(const void * const x)3621b8321bfSMasatake YAMATO unsigned int hashCstrhash (const void *const x)
363f2f92e1fSMasatake YAMATO {
3641b8321bfSMasatake YAMATO const char *const s = x;
3651b8321bfSMasatake YAMATO return (unsigned int)djb2((const unsigned char *)s);
366f2f92e1fSMasatake YAMATO }
367f2f92e1fSMasatake YAMATO
hashCstreq(const void * const a,const void * const b)3681b8321bfSMasatake YAMATO bool hashCstreq (const void * const a, const void *const b)
369f2f92e1fSMasatake YAMATO {
370f2f92e1fSMasatake YAMATO return !!(strcmp (a, b) == 0);
371f2f92e1fSMasatake YAMATO }
372f416402fSMasatake YAMATO
hashInthash(const void * const x)3731b8321bfSMasatake YAMATO unsigned int hashInthash (const void *const x)
374f416402fSMasatake YAMATO {
375f416402fSMasatake YAMATO union tmp {
376f416402fSMasatake YAMATO unsigned int u;
377f416402fSMasatake YAMATO int i;
378f416402fSMasatake YAMATO } x0;
379f416402fSMasatake YAMATO
380f416402fSMasatake YAMATO x0.u = 0;
381f416402fSMasatake YAMATO x0.i = *(int *)x;
382f416402fSMasatake YAMATO return x0.u;
383f416402fSMasatake YAMATO }
384f416402fSMasatake YAMATO
hashInteq(const void * const a,const void * const b)3851b8321bfSMasatake YAMATO bool hashInteq (const void *const a, const void *const b)
386f416402fSMasatake YAMATO {
387f416402fSMasatake YAMATO int ai = *(int *)a;
388f416402fSMasatake YAMATO int bi = *(int *)b;
389f416402fSMasatake YAMATO
390f416402fSMasatake YAMATO return !!(ai == bi);
391f416402fSMasatake YAMATO }
39293ce570cSMasatake YAMATO
39393ce570cSMasatake YAMATO
hashCstrcasehash(const void * const x)39493ce570cSMasatake YAMATO unsigned int hashCstrcasehash (const void *const x)
39593ce570cSMasatake YAMATO {
39693ce570cSMasatake YAMATO const char *const s = x;
39793ce570cSMasatake YAMATO return (unsigned int)casedjb2((const unsigned char *)s);
39893ce570cSMasatake YAMATO }
39993ce570cSMasatake YAMATO
hashCstrcaseeq(const void * const a,const void * const b)40093ce570cSMasatake YAMATO bool hashCstrcaseeq (const void *const a, const void *const b)
40193ce570cSMasatake YAMATO {
40293ce570cSMasatake YAMATO return !!(strcasecmp (a, b) == 0);
40393ce570cSMasatake YAMATO }
404