~ubuntu-branches/ubuntu/wily/ruby-ferret/wily

1 by Antonio Terceiro
Import upstream version 0.11.6
1
#ifndef FRT_HASH_H
2
#define FRT_HASH_H
3
4
#include "global.h"
5
6
/****************************************************************************
7
 *
8
 * HashTable
9
 *
10
 ****************************************************************************/
11
12
#define HASH_MINSIZE 8
13
#define SLOW_DOWN 50000         /* stop increasing the hash table so quickly to
14
                                 * conserve memory */
15
16
/**
17
 * Return values for h_set
18
 */
19
enum HashSetValues
20
{
21
    HASH_KEY_DOES_NOT_EXIST = 0,
22
    HASH_KEY_EQUAL = 1,
23
    HASH_KEY_SAME = 2
24
};
25
26
/**
27
 * struct used internally to store values in the HashTable
28
 */
29
typedef struct
30
{
31
    unsigned long hash;
32
    void *key;
33
    void *value;
34
} HashEntry;
35
36
/**
37
 * As the hash table is filled and entries are deleted, Dummy HashEntries are
38
 * put in place. We therefor keep two counts. +size+ is the number active
39
 * elements and +fill+ is the number of active elements together with the
40
 * number of dummy elements. +fill+ is basically just kept around so that we
41
 * know when to resize. The HashTable is resized when more than two thirds of
42
 * the HashTable is Filled. 
43
 */
44
typedef struct HashTable
45
{
46
    int fill;                   /* num Active + num Dummy */
47
    int size;                   /* num Active ie, num keys set */
48
    int mask;                   /* capacity_of_table - 1 */
49
    int ref_cnt;
50
51
    /* table points to smalltable initially. If the table grows beyond 2/3 of
52
     * HASH_MINSIZE it will point to newly malloced memory as it grows. */
53
    HashEntry *table;
54
55
    /* When a HashTable is created it needs an initial table to start if off.
56
     * All HashTables will start with smalltable and then malloc a larger
57
     * table as the HashTable grows */
58
    HashEntry smalltable[HASH_MINSIZE];
59
60
    /* the following function pointers are used internally and should not be
61
     * used outside of the HashTable methods */
62
    HashEntry    *(*lookup_i)(struct HashTable *self, register const void *key);
63
    unsigned long (*hash_i)(const void *key);
64
    int           (*eq_i)(const void *key1, const void *key2);
65
    void          (*free_key_i)(void *p);
66
    void          (*free_value_i)(void *p);
67
} HashTable;
68
69
/**
70
 * Hashing function type used by HashTable. A function of this type must be
71
 * passed to create a new HashTable.
72
 *
73
 * @param key object to hash
74
 * @return an unsigned 32-bit integer hash value
75
 */
76
typedef unsigned long (*hash_ft)(const void *key);
77
78
/**
79
 * Equals function type used by HashTable. A function of this type must be
80
 * passed to create a new HashTable.
81
 */
82
typedef int (*eq_ft)(const void *key1, const void *key2);
83
84
/**
85
 * Determine a hash value for a string. The string must be null terminated
86
 *
87
 * @param str string to hash
88
 * @return an unsigned long integer hash value
89
 */
90
extern unsigned long str_hash(const char *const str);
91
92
/**
93
 * Determine a hash value for a pointer. Just cast the pointer to an unsigned
94
 * long.
95
 *
96
 * @param ptr pointer to hash
97
 * @return an unsigned long integer hash value
98
 */
99
extern unsigned long ptr_hash(const void *const ptr);
100
101
/**
102
 * Determine if two pointers point to the same point in memory.
103
 *
104
 * @param q1 first pointer
105
 * @param q2 second pointer
106
 * @return true if the pointers are equal
107
 */
108
extern int ptr_eq(const void *q1, const void *q2);
109
110
/**
111
 * Create a new HashTable that uses any type of object as it's key. The
112
 * HashTable will store all keys and values so if you want to destroy those
113
 * values when the HashTable is destroyed then you should pass free functions.
114
 * NULL will suffice otherwise.
115
 *
116
 * @param hash function to determine the hash value of a key in the HashTable
117
 * @param eq function to determine the equality of to keys in the HashTable
118
 * @param free_key function to free the key stored in the HashTable when an
119
 *    entry is deleted, replaced or when the HashTable is destroyed. If you
120
 *    pass NULL in place of this parameter the key will not be destroyed.
121
 * @param free_value function to free the value stored in the HashTable when
122
 *    an entry is deleted, replaced or when the HashTable is destroyed. If you
123
 *    pass NULL in place of this parameter the value will not be destroyed.
124
 * @return A newly allocated HashTable
125
 */
126
extern HashTable *h_new(hash_ft hash, eq_ft eq, free_ft free_key,
127
                        free_ft free_value);
128
129
/**
130
 * Create a new HashTable that uses null-terminated strings as it's keys. The
131
 * HashTable will store all keys and values so if you want to destroy those
132
 * values when the HashTable is destroyed then you should pass free functions.
133
 * NULL will suffice otherwise.
134
 *
135
 * @param free_key function to free the key stored in the HashTable when an
136
 *    entry is deleted, replaced or when the HashTable is destroyed. If you
137
 *    pass NULL in place of this parameter the key will not be destroyed.
138
 * @param free_value function to free the value stored in the HashTable when
139
 *    an entry is deleted, replaced or when the HashTable is destroyed. If you
140
 *    pass NULL in place of this parameter the value will not be destroyed.
141
 * @return A newly allocated HashTable
142
 */
143
extern HashTable *h_new_str(free_ft free_key, free_ft free_value);
144
145
/**
146
 * Create a new HashTable that uses integers as it's keys. The
147
 * HashTable will store all values so if you want to destroy those
148
 * values when the HashTable is destroyed then you should pass a free function.
149
 * NULL will suffice otherwise.
150
 *
151
 * @param free_value function to free the value stored in the HashTable when
152
 *    an entry is deleted, replaced or when the HashTable is destroyed. If you
153
 *    pass NULL in place of this parameter the value will not be destroyed.
154
 * @return A newly allocated HashTable
155
 */
156
extern HashTable *h_new_int(free_ft free_value);
157
158
/**
159
 * Destroy the HashTable. This function will also destroy all keys and values
160
 * in the HashTable depending on how the free_key and free_value were set.
161
 *
162
 * @param self the HashTable to destroy
163
 */
164
extern void h_destroy(HashTable *self);
165
166
/**
167
 * Clear the HashTable. This function will delete all keys and values from the
168
 * hash table, also destroying all keys and values in the HashTable depending
169
 * on how the free_key and free_value were set.
170
 *
171
 * @param self the HashTable to clear
172
 */
173
extern void h_clear(HashTable *self);
174
175
/**
176
 * Get the value in the HashTable referenced by the key +key+.
177
 *
178
 * @param self the HashTable to reference
179
 * @param key the key to lookup
180
 * @return the value referenced by the key +key+. If there is no value
181
 *   referenced by that key, NULL is returned.
182
 */
183
extern void *h_get(HashTable *self, const void *key);
184
185
/**
186
 * Delete the value in HashTable referenced by the key +key+. When the value
187
 * is deleted it is also destroyed along with the key depending on how
188
 * free_key and free_value where set when the HashTable was created. If you
189
 * don't want to destroy the value use h_rem. 
190
 *
191
 * This functions returns +true+ if the value was deleted successfully or
192
 * false if the key was not found.
193
 *
194
 * @see h_rem
195
 *
196
 * @param self the HashTable to reference
197
 * @param key the key to lookup
198
 * @return true if the object was successfully deleted or false if the key was
199
 *   not found
200
 */
201
extern int h_del(HashTable *self, const void *key);
202
203
/**
204
 * Remove the value in HashTable referenced by the key +key+. When the value
205
 * is removed it is returned rather than destroyed. The key however is
206
 * destroyed using the free_key functions passed when the HashTable is created
207
 * if del_key is true.
208
 *
209
 * If you want the value to be destroyed, use the h_del function.
210
 *
211
 * @see h_del
212
 *
213
 * @param self the HashTable to reference
214
 * @param key the key to lookup
215
 * @param del_key set to true if you want the key to be deleted when the value
216
 *   is removed from the HashTable
217
 * @return the value referenced by +key+ if it can be found or NULL otherwise
218
 */
219
extern void *h_rem(HashTable *self, const void *key, bool del_key);
220
221
/**
222
 * WARNING: this function may destroy an old value or key if the key already
223
 * exists in the HashTable, depending on how free_value and free_key were set
224
 * for this HashTable.
225
 *
226
 * Add the value +value+ to the HashTable referencing it with key +key+.
227
 *
228
 * When a value is added to the HashTable it replaces any value that
229
 * might already be stored under that key. If free_value is already set then
230
 * the old value will be freed using that function.
231
 *
232
 * Similarly the old key might replace be replaced by the new key if they are
233
 * are equal (according to the HashTable's eq function) but seperately
234
 * allocated objects.
235
 *
236
 * @param self the HashTable to add the value to
237
 * @param key the key to use to reference the value
238
 * @param value the value to add to the HashTable
239
 * @return one of three values;
240
 *   <pre>
241
 *     HASH_KEY_DOES_NOT_EXIST  there was no value stored with that key
242
 *     HASH_KEY_EQUAL           the key existed and was seperately allocated.
243
 *                              In this situation the old key will have been
244
 *                              destroyed if free_key was set
245
 *     HASH_KEY_SAME            the key was identical (same memory pointer) to
246
 *                              the existing key so no key was freed
247
 *   </pre>
248
 */
249
extern int h_set(HashTable *self, const void *key, void *value);
250
251
/**
252
 * Add the value +value+ to the HashTable referencing it with key +key+. If
253
 * the key already exists in the HashTable, the value won't be added and the
254
 * function will return false. Otherwise it will return true.
255
 *
256
 * @param self the HashTable to add the value to
257
 * @param key the key to use to reference the value
258
 * @param value the value to add to the HashTable
259
 * @return true if the value was successfully added or false otherwise
260
 */
261
extern int h_set_safe(HashTable *self, const void *key, void *value);
262
263
/**
264
 * Return a hash entry object so you can handle the insert yourself. This can
265
 * be used for performance reasons or for more control over how a value is
266
 * added. Say, for example, you wanted to append a value to an array, or add a
267
 * new array if non-existed, you could use this method by checking the value
268
 * of the HashEntry returned.
269
 *
270
 * @param self the HashTable to add the value to
271
 * @param key the key to use to reference the value
272
 * @return HashEntry a pointer to the hash entry object now reserved for this
273
 * value. Be sure to set both the *key* and the *value*
274
 */
275
extern HashEntry *h_set_ext(HashTable *ht, const void *key);
276
277
/**
278
 * Check whether key +key+ exists in the HashTable.
279
 *
280
 * @param self the HashTable to check in
281
 * @param key the key to check for in the HashTable
282
 * @return true if the key exists in the HashTable, false otherwise.
283
 */
284
extern int h_has_key(HashTable *self, const void *key);
285
286
/**
287
 * Get the value in the HashTable referenced by an integer key +key+.
288
 *
289
 * @param self the HashTable to reference
290
 * @param key the integer key to lookup
291
 * @return the value referenced by the key +key+. If there is no value
292
 *   referenced by that key, NULL is returned.
293
 */
294
extern void *h_get_int(HashTable *self, const unsigned long key);
295
296
/**
297
 * Delete the value in HashTable referenced by the integer key +key+. When the
298
 * value is deleted it is also destroyed using the free_value function. If you
299
 * don't want to destroy the value use h_rem. 
300
 *
301
 * This functions returns +true+ if the value was deleted successfully or
302
 * false if the key was not found.
303
 *
304
 * @see h_rem
305
 *
306
 * @param self the HashTable to reference
307
 * @param key the integer key to lookup
308
 * @return true if the object was successfully deleted or false if the key was
309
 *   not found
310
 */
311
extern int h_del_int(HashTable *self, const unsigned long key);
312
313
/**
314
 * Remove the value in HashTable referenced by the integer key +key+. When the
315
 * value is removed it is returned rather than destroyed.
316
 *
317
 * If you want the value to be destroyed, use the h_del function.
318
 *
319
 * @see h_del
320
 *
321
 * @param self the HashTable to reference
322
 * @param key the integer key to lookup
323
 * @return the value referenced by +key+ if it can be found or NULL otherwise
324
 */
325
extern void *h_rem_int(HashTable *self, const unsigned long key);
326
327
/**
328
 * WARNING: this function may destroy an old value if the key already exists
329
 * in the HashTable, depending on how free_value was set for this HashTable.
330
 *
331
 * Add the value +value+ to the HashTable referencing it with an integer key
332
 * +key+.
333
 *
334
 * When a value is added to the HashTable it replaces any value that
335
 * might already be stored under that key. If free_value is already set then
336
 * the old value will be freed using that function.
337
 *
338
 * Similarly the old key might replace be replaced by the new key if they are
339
 * are equal (according to the HashTable's eq function) but seperately
340
 * allocated objects.
341
 *
342
 * @param self the HashTable to add the value to
343
 * @param key the integer key to use to reference the value
344
 * @param value the value to add to the HashTable
345
 * @return one of three values;
346
 *   <pre>
347
 *     HASH_KEY_DOES_NOT_EXIST  there was no value stored with that key
348
 *     HASH_KEY_EQUAL           the key existed and was seperately allocated.
349
 *                              In this situation the old key will have been
350
 *                              destroyed if free_key was set
351
 *     HASH_KEY_SAME            the key was identical (same memory pointer) to
352
 *                              the existing key so no key was freed
353
 *   </pre>
354
 */
355
extern int h_set_int(HashTable *self, const unsigned long key, void *value);
356
357
/**
358
 * Add the value +value+ to the HashTable referencing it with integer key
359
 * +key+. If the key already exists in the HashTable, the value won't be added
360
 * and the function will return false. Otherwise it will return true.
361
 *
362
 * @param self the HashTable to add the value to
363
 * @param key the integer key to use to reference the value
364
 * @param value the value to add to the HashTable
365
 * @return true if the value was successfully added or false otherwise
366
 */
367
extern int h_set_safe_int(HashTable *self, const unsigned long key, void *value);
368
/**
369
 * Check whether integer key +key+ exists in the HashTable.
370
 *
371
 * @param self the HashTable to check in
372
 * @param key the integer key to check for in the HashTable
373
 * @return true if the key exists in the HashTable, false otherwise.
374
 */
375
extern int h_has_key_int(HashTable *self, const unsigned long key);
376
377
typedef void (*h_each_key_val_ft)(void *key, void *value, void *arg);
378
379
/**
380
 * Run function +each_key_val+ on each key and value in the HashTable. The third
381
 * argument +arg+ will also be passed to +each_key_val+. If you need to pass
382
 * more than one argument to the function you should pass a struct.
383
 *
384
 * example;
385
 *
386
 * // Lets say we have stored strings in a HashTable and we want to put them
387
 * // all into an array. First we need to create a struct to store the
388
 * // strings;
389
 *
390
 * struct StringArray {
391
 *   char **strings;
392
 *   int cnt;
393
 *   int size;
394
 * };
395
 *
396
 * static void add_string_ekv(void *key, void *value,
397
 *                            struct StringArray *str_arr)
398
 * {
399
 *   str_arr->strings[str_arr->cnt] = (char *)value;
400
 *   str_arr->cnt++;
401
 * }
402
 *
403
 * struct StringArray *h_extract_strings(HashTable *ht)
404
 * {
405
 *   struct StringArray *str_arr = ALLOC(struct StringArray);
406
 *
407
 *   str_arr->strings = ALLOC_N(char *, ht->size);
408
 *   str_arr->cnt = 0;
409
 *   str_arr->size = ht->size;
410
 *
411
 *   h_each(ht, (h_each_key_val_ft)add_string_ekv, str_arr);
412
 *
413
 *   return str_arr;
414
 * }
415
 *
416
 * @param self the HashTable to run the function on
417
 * @param each_key_val function to run on on each key and value in the
418
 *   HashTable
419
 * @param arg an extra argument to pass to each_key_val each time it is called
420
 */
421
extern void h_each(HashTable *self,
422
                   void (*each_key_val)(void *key, void *value, void *arg),
423
                   void *arg);
424
425
typedef void *(*h_clone_func_t)(void *val);
426
/**
427
 * Clone the HashTable as well as cloning each of the keys and values if you
428
 * want to do a deep clone. To do a deep clone you will need to pass a
429
 * clone_key function and/or a clone_value function.
430
 *
431
 * @param self the HashTable to clone
432
 * @param clone_key the function to clone the key with
433
 * @param clone_value the function to clone the value with
434
 * @return a clone of the original HashTable
435
 */
436
extern HashTable *h_clone(HashTable *self,
437
                          h_clone_func_t clone_key,
438
                          h_clone_func_t clone_value);
439
440
/*
441
 * The following functions should only be used in static HashTable
442
 * declarations
443
 */
444
/**
445
 * This is the lookup function for a hash table keyed with strings. Since it
446
 * is so common for hash tables to be keyed with strings it gets it's own
447
 * lookup function. This method will always return a HashEntry. If there is no
448
 * entry with the given key then an empty entry will be returned with the key
449
 * set to the key that was passed.
450
 *
451
 * @param ht the hash table to look in
452
 * @param key the key to lookup
453
 * @return the HashEntry that was found
454
 */
455
extern HashEntry *h_lookup_str(HashTable *ht, register const char *key);
456
457
/**
458
 * This is the lookup function for a hash table with non-string keys. The
459
 * hash() and eq() methods used are stored in the hash table. This method will
460
 * always return a HashEntry. If there is no entry with the given key then an
461
 * empty entry will be returned with the key set to the key that was passed.
462
 *
463
 * @param ht the hash table to look in
464
 * @param key the key to lookup
465
 * @return the HashEntry that was found
466
 */
467
extern HashEntry *h_lookup(HashTable *ht, register const void *key);
468
469
typedef HashEntry *(*h_lookup_ft)(HashTable *ht, register const void *key);
470
471
extern void h_str_print_keys(HashTable *ht);
472
473
#endif