xref: /Universal-ctags/main/htable.c (revision 553897a62077cd5c507aec7cb684135e9c82a666)
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