geany  1.38
About: Geany is a text editor (using GTK2) with basic features of an integrated development environment (syntax highlighting, code folding, symbol name auto-completion, ...). F: office T: editor programming GTK+ IDE
  Fossies Dox: geany-1.38.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

htable.c
Go to the documentation of this file.
1/*
2*
3* Copyright (c) 2014, Red Hat, Inc.
4* Copyright (c) 2014, Masatake YAMATO
5*
6* This source code is released for free distribution under the terms of the
7* GNU General Public License version 2 or (at your option) any later version.
8*
9* Defines hashtable
10*/
11
12#include "general.h"
13#include "htable.h"
14
15#ifndef MAIN
16#include <stdio.h>
17#include "routines.h"
18#else
19#include <stdlib.h>
20#ifndef xCalloc
21#define xCalloc(n,Type) (Type *)calloc((size_t)(n), sizeof (Type))
22#endif
23#ifndef xMalloc
24#define xMalloc(n,Type) (Type *)malloc((size_t)(n) * sizeof (Type))
25#endif
26#ifndef eFree
27#define eFree(x) free(x)
28#endif
29#endif /* MAIN */
30
31#include <string.h>
32
33
34typedef struct sHashEntry hentry;
35struct sHashEntry {
36 void *key;
37 void *value;
39};
40
41struct sHashTable {
43 unsigned int size;
48};
49
51 const void *const target_key;
53 void *user_data;
55};
56
57static hentry* entry_new (void *key, void *value, hentry* next)
58{
59 hentry* entry = xMalloc (1, hentry);
60
61 entry->key = key;
62 entry->value = value;
63 entry->next = next;
64
65 return entry;
66}
67
69 hashTableFreeFunc keyfreefn,
70 hashTableFreeFunc valfreefn)
71{
72 hentry* tmp;
73
74 if (keyfreefn)
75 keyfreefn (entry->key);
76 if (valfreefn)
77 valfreefn (entry->value);
78 entry->key = NULL;
79 entry->value = NULL;
80 tmp = entry->next;
81 eFree (entry);
82
83 return tmp;
84}
85
87 hashTableFreeFunc keyfreefn,
88 hashTableFreeFunc valfreefn)
89{
90 while (entry)
91 entry = entry_destroy (entry, keyfreefn, valfreefn);
92}
93
94static void *entry_find (hentry* entry, const void* const key, hashTableEqualFunc equalfn)
95{
96 while (entry)
97 {
98 if (equalfn( key, entry->key))
99 return entry->value;
100 entry = entry->next;
101 }
102 return NULL;
103}
104
105static bool entry_delete (hentry **entry, const void *key, hashTableEqualFunc equalfn,
106 hashTableFreeFunc keyfreefn, hashTableFreeFunc valfreefn)
107{
108 while (*entry)
109 {
110 if (equalfn (key, (*entry)->key))
111 {
112 *entry = entry_destroy (*entry, keyfreefn, valfreefn);
113 return true;
114 }
115
116 }
117 return false;
118}
119
120static bool entry_foreach (hentry *entry, hashTableForeachFunc proc, void *user_data)
121{
122 while (entry)
123 {
124 if (!proc (entry->key, entry->value, user_data))
125 return false;
126 entry = entry->next;
127 }
128 return true;
129}
130
131extern hashTable *hashTableNew (unsigned int size,
132 hashTableHashFunc hashfn,
133 hashTableEqualFunc equalfn,
134 hashTableFreeFunc keyfreefn,
135 hashTableFreeFunc valfreefn)
136{
137 hashTable *htable;
138
139 htable = xMalloc (1, hashTable);
140 htable->size = size;
141 htable->table = xCalloc (size, hentry*);
142
143 htable->hashfn = hashfn;
144 htable->equalfn = equalfn;
145 htable->keyfreefn = keyfreefn;
146 htable->valfreefn = valfreefn;
147
148 return htable;
149}
150
151extern hashTable* hashTableIntNew (unsigned int size,
152 hashTableHashFunc hashfn,
153 hashTableEqualFunc equalfn,
154 hashTableFreeFunc keyfreefn)
155{
156 return hashTableNew (size, hashfn, equalfn, keyfreefn, NULL);
157}
158
159extern void hashTableDelete (hashTable *htable)
160{
161 if (!htable)
162 return;
163
164 hashTableClear (htable);
165
166 eFree (htable->table);
167 eFree (htable);
168}
169
170extern void hashTableClear (hashTable *htable)
171{
172 unsigned int i;
173 if (!htable)
174 return;
175
176 for (i = 0; i < htable->size; i++)
177 {
178 hentry *entry;
179
180 entry = htable->table[i];
181 entry_reclaim (entry, htable->keyfreefn, htable->valfreefn);
182 htable->table[i] = NULL;
183 }
184}
185
186extern void hashTablePutItem (hashTable *htable, void *key, void *value)
187{
188 unsigned int i;
189
190 i = htable->hashfn (key) % htable->size;
191 htable->table[i] = entry_new(key, value, htable->table[i]);
192}
193
194extern void* hashTableGetItem (hashTable *htable, const void * key)
195{
196 unsigned int i;
197
198 i = htable->hashfn (key) % htable->size;
199 return entry_find(htable->table[i], key, htable->equalfn);
200}
201
202extern bool hashTableDeleteItem (hashTable *htable, const void *key)
203{
204 unsigned int i;
205
206 i = htable->hashfn (key) % htable->size;
207 return entry_delete(&htable->table[i], key,
208 htable->equalfn, htable->keyfreefn, htable->valfreefn);
209}
210
211extern bool hashTableHasItem (hashTable *htable, const void *key)
212{
213 return hashTableGetItem (htable, key)? true: false;
214}
215
216extern bool hashTableForeachItem (hashTable *htable, hashTableForeachFunc proc, void *user_data)
217{
218 unsigned int i;
219
220 for (i = 0; i < htable->size; i++)
221 if (!entry_foreach(htable->table[i], proc, user_data))
222 return false;
223 return true;
224}
225
226static bool track_chain (const void *const key, void *value, void *chain_data)
227{
228 struct chainTracker *chain_tracker = chain_data;
229
230 if (chain_tracker->equalfn (chain_tracker->target_key, key))
231 {
232 if (! chain_tracker->user_proc (key, value, chain_tracker->user_data))
233 return false;
234 }
235 return true;
236}
237
238extern bool hashTableForeachItemOnChain (hashTable *htable, const void *key, hashTableForeachFunc proc, void *user_data)
239{
240 unsigned int i;
241 struct chainTracker chain_tracker = {
242 .target_key = key,
243 .user_proc = proc,
244 .user_data = user_data,
245 .equalfn = htable->equalfn,
246 };
247
248 i = htable->hashfn (key) % htable->size;
249 if (!entry_foreach(htable->table[i], track_chain, &chain_tracker))
250 return false;
251 return true;
252}
253
254static bool count (const void *const key CTAGS_ATTR_UNUSED, void *value CTAGS_ATTR_UNUSED, void *data)
255{
256 int *c = data;
257 ++*c;
258 return true;
259}
260
261extern int hashTableCountItem (hashTable *htable)
262{
263 int c = 0;
264 hashTableForeachItem (htable, count, &c);
265 return c;
266}
267
268unsigned int hashPtrhash (const void * const x)
269{
270 union {
271 const void * ptr;
272 unsigned int ui;
273 } v;
274 v.ui = 0;
275 v.ptr = x;
276
277 return v.ui;
278}
279
280bool hashPtreq (const void *const a, const void *const b)
281{
282 return (a == b)? true: false;
283}
284
285
286/* http://www.cse.yorku.ca/~oz/hash.html */
287static unsigned long
288djb2(const unsigned char *str)
289{
290 unsigned long hash = 5381;
291 int c;
292
293 while ((c = *str++))
294 hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
295
296 return hash;
297}
298
299static unsigned long
300casedjb2(const unsigned char *str)
301{
302 unsigned long hash = 5381;
303 int c;
304
305 while ((c = *str++))
306 {
307 if (('a' <= c) && (c <= 'z'))
308 c += ('A' - 'a');
309 hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
310 }
311
312 return hash;
313}
314
315
316unsigned int hashCstrhash (const void *const x)
317{
318 const char *const s = x;
319 return (unsigned int)djb2((const unsigned char *)s);
320}
321
322bool hashCstreq (const void * const a, const void *const b)
323{
324 return !!(strcmp (a, b) == 0);
325}
326
327unsigned int hashInthash (const void *const x)
328{
329 union tmp {
330 unsigned int u;
331 int i;
332 } x0;
333
334 x0.u = 0;
335 x0.i = *(int *)x;
336 return x0.u;
337}
338
339bool hashInteq (const void *const a, const void *const b)
340{
341 int ai = *(int *)a;
342 int bi = *(int *)b;
343
344 return !!(ai == bi);
345}
346
347
348unsigned int hashCstrcasehash (const void *const x)
349{
350 const char *const s = x;
351 return (unsigned int)casedjb2((const unsigned char *)s);
352}
353
354bool hashCstrcaseeq (const void *const a, const void *const b)
355{
356 return !!(strcasecmp (a, b) == 0);
357}
GeanyBuildCommand ** ptr
Definition: build.c:2679
#define CTAGS_ATTR_UNUSED
Definition: gcc-attr.h:22
#define strcasecmp(s1, s2)
Definition: general.h:37
bool hashCstrcaseeq(const void *const a, const void *const b)
Definition: htable.c:354
bool hashTableForeachItemOnChain(hashTable *htable, const void *key, hashTableForeachFunc proc, void *user_data)
Definition: htable.c:238
unsigned int hashCstrhash(const void *const x)
Definition: htable.c:316
static bool track_chain(const void *const key, void *value, void *chain_data)
Definition: htable.c:226
static unsigned long djb2(const unsigned char *str)
Definition: htable.c:288
void hashTablePutItem(hashTable *htable, void *key, void *value)
Definition: htable.c:186
static hentry * entry_destroy(hentry *entry, hashTableFreeFunc keyfreefn, hashTableFreeFunc valfreefn)
Definition: htable.c:68
static hentry * entry_new(void *key, void *value, hentry *next)
Definition: htable.c:57
static void entry_reclaim(hentry *entry, hashTableFreeFunc keyfreefn, hashTableFreeFunc valfreefn)
Definition: htable.c:86
unsigned int hashPtrhash(const void *const x)
Definition: htable.c:268
bool hashTableForeachItem(hashTable *htable, hashTableForeachFunc proc, void *user_data)
Definition: htable.c:216
static void * entry_find(hentry *entry, const void *const key, hashTableEqualFunc equalfn)
Definition: htable.c:94
hashTable * hashTableNew(unsigned int size, hashTableHashFunc hashfn, hashTableEqualFunc equalfn, hashTableFreeFunc keyfreefn, hashTableFreeFunc valfreefn)
Definition: htable.c:131
void hashTableDelete(hashTable *htable)
Definition: htable.c:159
unsigned int hashCstrcasehash(const void *const x)
Definition: htable.c:348
void * hashTableGetItem(hashTable *htable, const void *key)
Definition: htable.c:194
bool hashTableHasItem(hashTable *htable, const void *key)
Definition: htable.c:211
static bool count(const void *const key, void *value, void *data)
Definition: htable.c:254
static unsigned long casedjb2(const unsigned char *str)
Definition: htable.c:300
bool hashPtreq(const void *const a, const void *const b)
Definition: htable.c:280
int hashTableCountItem(hashTable *htable)
Definition: htable.c:261
static bool entry_foreach(hentry *entry, hashTableForeachFunc proc, void *user_data)
Definition: htable.c:120
hashTable * hashTableIntNew(unsigned int size, hashTableHashFunc hashfn, hashTableEqualFunc equalfn, hashTableFreeFunc keyfreefn)
Definition: htable.c:151
bool hashTableDeleteItem(hashTable *htable, const void *key)
Definition: htable.c:202
bool hashCstreq(const void *const a, const void *const b)
Definition: htable.c:322
void hashTableClear(hashTable *htable)
Definition: htable.c:170
unsigned int hashInthash(const void *const x)
Definition: htable.c:327
static bool entry_delete(hentry **entry, const void *key, hashTableEqualFunc equalfn, hashTableFreeFunc keyfreefn, hashTableFreeFunc valfreefn)
Definition: htable.c:105
bool hashInteq(const void *const a, const void *const b)
Definition: htable.c:339
bool(* hashTableForeachFunc)(const void *key, void *value, void *user_data)
Definition: htable.h:37
void(* hashTableFreeFunc)(void *ptr)
Definition: htable.h:33
unsigned int(* hashTableHashFunc)(const void *const key)
Definition: htable.h:31
bool(* hashTableEqualFunc)(const void *a, const void *b)
Definition: htable.h:32
#define NULL
Definition: rbtree.h:150
void eFree(void *const ptr)
Definition: routines.c:252
#define xMalloc(n, Type)
Definition: routines.h:23
#define xCalloc(n, Type)
Definition: routines.h:24
GtkWidget * entry
Definition: search.c:118
hashTableEqualFunc equalfn
Definition: htable.c:54
const void *const target_key
Definition: htable.c:51
void * user_data
Definition: htable.c:53
hashTableForeachFunc user_proc
Definition: htable.c:52
void * value
Definition: htable.c:37
void * key
Definition: htable.c:36
hentry * next
Definition: htable.c:38
hentry ** table
Definition: htable.c:42
unsigned int size
Definition: htable.c:43
hashTableHashFunc hashfn
Definition: htable.c:44
hashTableFreeFunc keyfreefn
Definition: htable.c:46
hashTableEqualFunc equalfn
Definition: htable.c:45
hashTableFreeFunc valfreefn
Definition: htable.c:47