#include <stdlib.h>
Go to the source code of this file.
Defines | |
#define | GHT_HEURISTICS_NONE 0 |
#define | GHT_HEURISTICS_TRANSPOSE 1 |
#define | GHT_HEURISTICS_MOVE_TO_FRONT 2 |
#define | GHT_AUTOMATIC_REHASH 4 |
#define | TRUE 1 |
#define | FALSE 0 |
Typedefs | |
typedef unsigned int | ght_uint32_t |
typedef s_hash_key | ght_hash_key_t |
typedef s_hash_entry | ght_hash_entry_t |
typedef ght_uint32_t(* | ght_fn_hash_t )(ght_hash_key_t *p_key) |
typedef void *(* | ght_fn_alloc_t )(size_t size) |
typedef void(* | ght_fn_free_t )(void *ptr) |
typedef void(* | ght_fn_bucket_free_callback_t )(void *data, void *key) |
Functions | |
ght_hash_table_t * | ght_create (unsigned int i_size) |
void | ght_set_alloc (ght_hash_table_t *p_ht, ght_fn_alloc_t fn_alloc, ght_fn_free_t fn_free) |
void | ght_set_hash (ght_hash_table_t *p_ht, ght_fn_hash_t fn_hash) |
void | ght_set_heuristics (ght_hash_table_t *p_ht, int i_heuristics) |
void | ght_set_rehash (ght_hash_table_t *p_ht, int b_rehash) |
void | ght_set_bounded_buckets (ght_hash_table_t *p_ht, unsigned int limit, ght_fn_bucket_free_callback_t fn) |
unsigned int | ght_size (ght_hash_table_t *p_ht) |
unsigned int | ght_table_size (ght_hash_table_t *p_ht) |
int | ght_insert (ght_hash_table_t *p_ht, void *p_entry_data, unsigned int i_key_size, void *p_key_data) |
void * | ght_replace (ght_hash_table_t *p_ht, void *p_entry_data, unsigned int i_key_size, void *p_key_data) |
void * | ght_get (ght_hash_table_t *p_ht, unsigned int i_key_size, void *p_key_data) |
void * | ght_remove (ght_hash_table_t *p_ht, unsigned int i_key_size, void *p_key_data) |
void * | ght_first (ght_hash_table_t *p_ht, ght_iterator_t *p_iterator, void **pp_key) |
void * | ght_next (ght_hash_table_t *p_ht, ght_iterator_t *p_iterator, void **pp_key) |
void | ght_rehash (ght_hash_table_t *p_ht, unsigned int i_size) |
void | ght_finalize (ght_hash_table_t *p_ht) |
ght_uint32_t | ght_one_at_a_time_hash (ght_hash_key_t *p_key) |
ght_uint32_t | ght_rotating_hash (ght_hash_key_t *p_key) |
ght_uint32_t | ght_crc_hash (ght_hash_key_t *p_key) |
Libghthash really stores pointers to data - the hash table knows nothing about the actual type of the data.
A simple example to get started can be found in the example/simple.c
file found in the distribution. hash_test.c
provides a more comlpete example.
Some basic properties of the hash table are:
|
Definition of the allocation function pointers. This is simply the same definition as
|
|
Definition of the deallocation function pointers. This is simply the same definition as
|
|
Definition of the hash function pointers.
|
|
The structure for hash keys. You should not care about this structure unless you plan to write your own hash functions. |
|
unsigned 32 bit integer. |
|
CRC32 hash. CRC32 hash is a good hash function. This came from Dru Lemley <spambait@lemley.net>.
|
|
Create a new hash table. The number of buckets should be about as big as the number of elements you wish to store in the table for good performance. The number of buckets is rounded to the next higher power of two.
The hash table is created with
|
|
Free the hash table. ght_finalize() should typically be called at the end of the program. Note that only the metadata and the keys of the table is freed, not the entries. If you want to free the entries when removing the table, the entries will have to be manually freed before ght_finalize() is called like:
ght_iterator_t iterator; void *p_key; void *p_e;
for(p_e = ght_first(p_table, &iterator, &p_key); p_e; p_e = ght_next(p_table, &iterator, &p_key)) { free(p_e); }
ght_finalize(p_table);
|
|
Return the first entry in the hash table. This function should be used for iteration and is used together with ght_next(). Note that you cannot assume anything about the order in which the entries are accessed. If an entry is inserted during an iteration, the entry might or might not occur in the iteration. Note that removal during an iteration is only safe for the current entry or an entry which has already been iterated over. The use of the ght_iterator_t allows for several concurrent iterations, where you would use one ght_iterator_t for each iteration. In threaded environments, you should still lock access to the hash table for insertion and removal. A typical example might look as follows: ght_hash_table_t *p_table; ght_iterator_t iterator; void *p_key; void *p_e;
[Create table etc...] for(p_e = ght_first(p_table, &iterator, &p_key); p_e; p_e = ght_next(p_table, &iterator, &p_key)) { [Do something with the current entry p_e and it's key p_key] }
|
|
Lookup an entry in the hash table. The entry is not removed from the table.
|
|
Insert an entry into the hash table. Prior to inserting anything, make sure that the table is created with ght_create(). If an element with the same key as this one already exists in the table, the insertion will fail and -1 is returned. A typical example is shown below, where the string "blabla" (including the ''-terminator) is used as a key for the integer 15.
ght_hash_table_t *p_table; char *p_key_data; int *p_data; int ret;
[Create p_table etc...] p_data = malloc(sizeof(int)); p_key_data = "blabla"; *p_data = 15;
ret = ght_insert(p_table, p_data, sizeof(char)*(strlen(p_key_data)+1), p_key_data);
|
|
Return the next entry in the hash table. This function should be used for iteration, and must be called after ght_first().
|
|
One-at-a-time-hash. One-at-a-time-hash is a good hash function, and is the default when ght_create() is called with NULL as the fn_hash parameter. This was found in a DrDobbs article, see http://burtleburtle.net/bob/hash/doobs.html
|
|
Rehash the hash table.
Rehashing will change the size of the hash table, retaining all elements. This is very costly and should be avoided unless really needed. If
|
|
Remove an entry from the hash table. The entry is removed from the table, but not freed (that is, the data stored is not freed).
|
|
Replace an entry in the hash table. This function will return an error if the entry to be replaced does not exist, i.e. it cannot be used to insert new entries.
|
|
Rotating hash. Not so good hash function. This was found in a DrDobbs article, see http://burtleburtle.net/bob/hash/doobs.html
|
|
Set the allocation/freeing functions to use for a hash table. The allocation function will only be called when a new entry is inserted.
The allocation size will always be
If this function is not called,
|
|
Enable or disable bounded buckets. With bounded buckets, the hash table will act as a cache, only holding a fixed number of elements per bucket. limit specifies the limit of elements per bucket. When inserting elements with ght_insert into a bounded table, the last entry in the bucket chain will be free:d. libghthash will then call the callback function fn, which allow the user of the library to dispose of the key and data. Bounded buckets are disabled by default.
|
|
Set the hash function to use for a hash table.
|
|
Set the heuristics to use for the hash table. The possible values are:
|
|
Enable or disable automatic rehashing. With automatic rehashing, the table will rehash itself when the number of elements in the table are twice as many as the number of buckets. You should note that automatic rehashing will cause your application to be really slow when the table is rehashing (which might happen at times when you need speed), you should therefore be careful with this in time-constrainted applications.
|
|
Get the size (the number of items) of the hash table.
|
|
Get the table size (the number of buckets) of the hash table.
|