Data Structures | |
struct | _cp_hashtable_entry |
Internal object that implements a key, value pair plus linked list. More... | |
struct | _cp_hashtable |
data structure of generic synchronized cp_hashtable More... | |
Files | |
file | hashtable.c |
Implementation of generic synchronized cp_hashtable. | |
file | hashtable.h |
generic synchronized hashtable. | |
Defines | |
#define | CP_HASHTABLE_MULTIPLE_VALUES 1 |
#define | CP_CHAR_UC(x) ((x) >= 'a' && (x) <= 'z' ? ((x) - 'a' + 'A') : (x)) |
#define | HASH_SEED 1000000001L |
1000000001 is a prime. | |
#define | CP_HASHTABLE_DEFAULT_MIN_FILL_FACTOR 5 |
#define | CP_HASHTABLE_DEFAULT_MAX_FILL_FACTOR 70 |
#define | cp_hashtable_create_by_mode(mode, size_hint, cp_hashfn, compare_fn) cp_hashtable_create_by_option((mode), (size_hint), (cp_hashfn), (compare_fn), NULL, NULL, NULL, NULL) |
creates a new cp_hashtable with the specified mode. | |
#define | cp_hashtable_rdlock(table) cp_hashtable_lock((table), COLLECTION_LOCK_READ) |
macro to get a read lock on the table | |
#define | cp_hashtable_wrlock(table) cp_hashtable_lock((table), COLLECTION_LOCK_WRITE) |
macro to get a write lock on the table | |
#define | cp_hashtable_is_empty(table) (cp_hashtable_count(table) == 0) |
Check if the collection is empty. | |
Typedefs | |
typedef unsigned long(* | cp_hashfunction )(void *) |
the hash function takes (void *) and returns unsigned long. | |
typedef CPROPS_DLL struct _cp_hashtable_entry | cp_hashtable_entry |
Internal object that implements a key, value pair plus linked list. | |
typedef CPROPS_DLL struct _cp_hashtable | cp_hashtable |
data structure of generic synchronized cp_hashtable | |
Functions | |
unsigned long | cp_hashtable_choose_size (unsigned long size_request) |
cp_hashtable * | cp_hashtable_create (unsigned long size_hint, cp_hashfunction hashfn, cp_compare_fn compare_fn) |
creates a new cp_hashtable. | |
cp_hashtable * | cp_hashtable_create_copy_mode (unsigned long size_hint, cp_hashfunction hash_fn, cp_compare_fn compare_fn, cp_copy_fn copy_key, cp_destructor_fn free_key, cp_copy_fn copy_value, cp_destructor_fn free_value) |
creates a new cp_hashtable with COLLECTION_MODE_DEEP | COLLECTION_MODE_COPY. | |
cp_hashtable * | cp_hashtable_create_by_option (int mode, unsigned long size_hint, cp_hashfunction hash_fn, cp_compare_fn compare_fn, cp_copy_fn copy_key, cp_destructor_fn free_key, cp_copy_fn copy_value, cp_destructor_fn free_value) |
create a new table, fully specifying all parameters. | |
cp_hashtable_entry * | cp_hashtable_create_entry (cp_hashtable *table, int mode, void *key, void *value, long hashcode) |
void | cp_hashtable_destroy (cp_hashtable *table) |
deletes a cp_hashtable according to the current mode settings | |
void | cp_hashtable_destroy_deep (cp_hashtable *table) |
deletes a cp_hashtable. | |
void | cp_hashtable_destroy_custom (cp_hashtable *table, cp_destructor_fn dk, cp_destructor_fn dv) |
Deep destroy with custom destructors for keys and values. | |
void | cp_hashtable_destroy_shallow (cp_hashtable *table) |
deletes a cp_hashtable. | |
int | cp_hashtable_lock_internal (cp_hashtable *table, int type) |
int | cp_hashtable_unlock_internal (cp_hashtable *table) |
int | cp_hashtable_txlock (cp_hashtable *table, int type) |
int | cp_hashtable_txunlock (cp_hashtable *table) |
int | cp_hashtable_lock (cp_hashtable *table, int type) |
by default the get, put and remove functions as well as set and unset mode perform their own locking. | |
int | cp_hashtable_unlock (cp_hashtable *table) |
unlock the table | |
int | cp_hashtable_set_mode (cp_hashtable *table, int mode) |
set the operation mode as a bit set of the following options: | |
int | cp_hashtable_get_mode (cp_hashtable *table) |
returns the current operation mode. | |
int | cp_hashtable_unset_mode (cp_hashtable *table, int mode) |
unset the mode bits defined by mode | |
void * | lookup_internal (cp_hashtable *table, void *key, long code, int option, int resize) |
Retrieves the value by key from normal or resizing table. | |
void * | cp_hashtable_get_by_option (cp_hashtable *table, void *key, int option) |
Retrieves the value by key. | |
void * | cp_hashtable_resize_thread (void *tbl) |
<<Thread>> resize a cp_hashtable. | |
int | cp_hashtable_set_min_size (cp_hashtable *table, int min_size) |
the internal table will not be resized to less than min_size | |
int | cp_hashtable_set_max_fill_factor (cp_hashtable *table, int fill_factor) |
a resize is triggered when the table contains more items than table_size * fill_factor / 100 | |
int | cp_hashtable_set_min_fill_factor (cp_hashtable *table, int fill_factor) |
a resize is triggered when the table contains less items than table_size * fill_factor / 100 | |
void * | cp_hashtable_resize (cp_hashtable *table, long new_size) |
Initiates a resize of the cp_hashtable which is executed in the background. | |
void * | cp_hashtable_resize_nosync (cp_hashtable *table, unsigned long new_size) |
Resizes the table to a new size. | |
static cp_hashtable_entry ** | cp_hashtable_replace_internal (cp_hashtable *table, void *key, void *value, unsigned long code, int option, int resize) |
Internal replace an existing entry with a new key, value pair. | |
void * | cp_hashtable_put (cp_hashtable *table, void *key, void *value) |
the key 'key' will be assigned to the value 'value'. | |
void * | cp_hashtable_put_safe (cp_hashtable *table, void *key, void *value) |
same as cp_hashtable_put(table, key, value) except that an old value is released if it exists. | |
void * | cp_hashtable_put_copy (cp_hashtable *table, void *key, void *value) |
same as cp_hashtable_put(table, key, value) except that it inserts a copy of the key and the value object. | |
void * | cp_hashtable_put_by_option (cp_hashtable *table, void *key, void *value, int mode) |
Internal put method. | |
void * | cp_hashtable_remove_internal (cp_hashtable *table, void *key, long code, int mode, int resize) |
Internal remove an entry from the table by key. | |
void * | cp_hashtable_remove_by_mode (cp_hashtable *table, void *key, int mode) |
Remove an entry from the table by key with locking mode. | |
int | cp_hashtable_remove_all (cp_hashtable *table) |
remove all entries with current mode | |
void * | cp_hashtable_remove (cp_hashtable *table, void *key) |
Attempts to remove the mapping for key from the table. | |
int | cp_hashtable_remove_deep (cp_hashtable *table, void *key) |
Remove with COLLECTION_MODE_DEEP set. | |
int | cp_hashtable_contains (cp_hashtable *table, void *key) |
Check if there is an entry with matching key. | |
void * | cp_hashtable_get (cp_hashtable *table, void *key) |
attempts to retrieve the value assigned to the key 'key'. | |
void ** | cp_hashtable_get_keys (cp_hashtable *table) |
get an array containing all keys mapped in table table. | |
unsigned long | cp_hashtable_count (cp_hashtable *table) |
Get the number of entries in the collection. | |
void ** | cp_hashtable_get_values (cp_hashtable *table) |
get an array containing all values in the table. | |
unsigned long | cp_hash_int (void *key) |
hash function for int keys | |
int | cp_hash_compare_int (void *key1, void *key2) |
comparator for int keys | |
unsigned long | cp_hash_long (void *key) |
hash function for long keys | |
int | cp_hash_compare_long (void *key1, void *key2) |
comparator for long keys | |
unsigned long | cp_hash_addr (void *addr) |
hash function for pointer keys | |
int | cp_hash_compare_addr (void *key1, void *key2) |
comparator for pointer keys | |
unsigned long | cp_hash_string (void *key) |
hash function for (char *) keys | |
int | cp_hash_compare_string (void *key1, void *key2) |
comparator for (char *) keys | |
unsigned long | cp_hash_istring (void *key) |
case insensitive hash function for (char *) keys | |
int | cp_hash_compare_istring (void *key1, void *key2) |
comparator for (char *) keys | |
void * | cp_hash_copy_string (void *element) |
copy function for cp_string copy tables | |
unsigned long | cp_hash_float (void *addr) |
int | cp_hash_compare_float (void *a1, void *a2) |
unsigned long | cp_hash_double (void *d) |
int | cp_hash_compare_double (void *a1, void *a2) |
Variables | |
static int | table_sizes [] |
static int | table_sizes_len = 40 |
#define cp_hashtable_is_empty | ( | table | ) | (cp_hashtable_count(table) == 0) |
Check if the collection is empty.
true/1 | if the collection is empty | |
false/0 | if the collection has entries |
#define HASH_SEED 1000000001L |
1000000001 is a prime.
HASH_SEED is used by cp_hash_string().
typedef unsigned long(* cp_hashfunction)(void *) |
the hash function takes (void *) and returns unsigned long.
Create a function with the name <class_name>_hash_code()
typedef CPROPS_DLL struct _cp_hashtable_entry cp_hashtable_entry |
Internal object that implements a key, value pair plus linked list.
Entries which are stored under the same index in the hashtable are stored in a linked list. The algorithm of the hashtable has to ensure that the lists do not get too long.
CPROPS_DLL int cp_hash_compare_addr | ( | void * | key1, | |
void * | key2 | |||
) |
comparator for pointer keys
key1 | pointer the first pointer | |
key2 | pointer the second pointer |
0 | if key1 equals key2; | |
<0 | if key1 is less than key2; | |
>0 | if key1 is greater than key2 |
Referenced by cp_httpclient_ctl_create().
CPROPS_DLL int cp_hash_compare_int | ( | void * | key1, | |
void * | key2 | |||
) |
comparator for int keys
key1 | pointer the first int | |
key2 | pointer the second int |
0 | if key1 equals key2; | |
<0 | if key1 is less than key2; | |
>0 | if key1 is greater than key2 |
CPROPS_DLL int cp_hash_compare_istring | ( | void * | key1, | |
void * | key2 | |||
) |
comparator for (char *) keys
key1 | pointer to the first cp_string | |
key2 | pointer to the second cp_string |
0 | if key1 equals key2 | |
<>0 | otherwise |
CPROPS_DLL int cp_hash_compare_long | ( | void * | key1, | |
void * | key2 | |||
) |
comparator for long keys
key1 | pointer the first long | |
key2 | pointer the second long |
0 | if key1 equals key2; | |
<0 | if key1 is less than key2; | |
>0 | if key1 is greater than key2 |
CPROPS_DLL int cp_hash_compare_string | ( | void * | key1, | |
void * | key2 | |||
) |
comparator for (char *) keys
key1 | pointer to the first cp_string | |
key2 | pointer to the second cp_string |
0 | if key1 equals key2 | |
<>0 | otherwise |
Referenced by cp_httpclient_set_parameter().
CPROPS_DLL unsigned long cp_hash_int | ( | void * | key | ) |
hash function for int keys
key | pointer to the int |
CPROPS_DLL unsigned long cp_hash_istring | ( | void * | key | ) |
case insensitive hash function for (char *) keys
key | pointer to the cp_string |
CPROPS_DLL unsigned long cp_hash_string | ( | void * | key | ) |
hash function for (char *) keys
key | pointer to the cp_string |
Referenced by cp_httpclient_set_parameter().
CPROPS_DLL unsigned long cp_hashtable_choose_size | ( | unsigned long | size_request | ) |
size_request
Referenced by cp_hashlist_create_by_option(), cp_hashtable_remove_by_mode(), and cp_hashtable_resize_nosync().
CPROPS_DLL int cp_hashtable_contains | ( | cp_hashtable * | table, | |
void * | key | |||
) |
Check if there is an entry with matching key.
table | the object | |
key | Key to search for. |
CPROPS_DLL unsigned long cp_hashtable_count | ( | cp_hashtable * | table | ) |
Get the number of entries in the collection.
CPROPS_DLL cp_hashtable * cp_hashtable_create | ( | unsigned long | size_hint, | |
cp_hashfunction | hashfn, | |||
cp_compare_fn | compare_fn | |||
) |
creates a new cp_hashtable.
by default there is no memory management for table content; insertion, removal and retrieval operations are synchronized; and the table will automatically resize when the fill factor goes over 70% or under 5%.
size_hint | an estimate for the initial storage requirements. The table |
handles the storage appropriately when items become too tight.
hashfn | a hash code function. This should ideally produce different results for different keys. | |
compare_fn | the comparator for your key type. |
CPROPS_DLL cp_hashtable * cp_hashtable_create_by_option | ( | int | mode, | |
unsigned long | size_hint, | |||
cp_hashfunction | hash_fn, | |||
cp_compare_fn | compare_fn, | |||
cp_copy_fn | copy_key, | |||
cp_destructor_fn | free_key, | |||
cp_copy_fn | copy_value, | |||
cp_destructor_fn | free_value | |||
) |
create a new table, fully specifying all parameters.
size_hint | initial capacity | |
hash_fn | hash function | |
compare_fn | key comparison function | |
copy_key | function to return new copies of keys | |
copy_value | function to return new copies of values | |
mode | mode flags |
Referenced by cp_httpclient_set_parameter().
CPROPS_DLL cp_hashtable * cp_hashtable_create_copy_mode | ( | unsigned long | size_hint, | |
cp_hashfunction | hash_fn, | |||
cp_compare_fn | compare_fn, | |||
cp_copy_fn | copy_key, | |||
cp_destructor_fn | free_key, | |||
cp_copy_fn | copy_value, | |||
cp_destructor_fn | free_value | |||
) |
creates a new cp_hashtable with COLLECTION_MODE_DEEP | COLLECTION_MODE_COPY.
size_hint | an estimate for the initial storage requirements. The table handles the storage appropriately when items become too tight. | |
hashfn | a hash code function. This should ideally produce different results for different keys. | |
compare_fn | the comparator for your key type. |
CPROPS_DLL void cp_hashtable_destroy | ( | cp_hashtable * | table | ) |
deletes a cp_hashtable according to the current mode settings
table | object to delete |
Referenced by cp_db_shutdown(), and cp_httpclient_destroy().
CPROPS_DLL void cp_hashtable_destroy_custom | ( | cp_hashtable * | table, | |
cp_destructor_fn | dk, | |||
cp_destructor_fn | dv | |||
) |
Deep destroy with custom destructors for keys and values.
NULL function pointers are not invoked.
CPROPS_DLL void cp_hashtable_destroy_deep | ( | cp_hashtable * | table | ) |
deletes a cp_hashtable.
Keys and values entered in the cp_hashtable are released.
table | object to delete |
CPROPS_DLL void cp_hashtable_destroy_shallow | ( | cp_hashtable * | table | ) |
deletes a cp_hashtable.
Pointers to the keys and values are not released. Use table if the keys and values you entered in the table should not be released by the cp_hashtable.
table | object to delete |
CPROPS_DLL void * cp_hashtable_get | ( | cp_hashtable * | table, | |
void * | key | |||
) |
attempts to retrieve the value assigned to the key 'key'.
To return multiple values the table mode must be set to COLLECTION_MODE_MULTIPLE_VALUES, otherwise the only first value for the given key will be returned.
(void*)value | to the value if found | |
NULL | otherwise |
Referenced by cp_error(), cp_httpclient_fetch(), and cp_perror().
CPROPS_DLL void * cp_hashtable_get_by_option | ( | cp_hashtable * | table, | |
void * | key, | |||
int | option | |||
) |
Retrieves the value by key.
retrieve the value or values for key 'key'.
table | the object | |
key | Key to search for. | |
option | operation mode |
value | of the entry with key. | |
NULL | otherwise (no entry with given key or key == NULL) |
the 'mode' parameter sets the mode for the current operation.
CPROPS_DLL void ** cp_hashtable_get_keys | ( | cp_hashtable * | table | ) |
get an array containing all keys mapped in table table.
CPROPS_DLL int cp_hashtable_get_mode | ( | cp_hashtable * | table | ) |
returns the current operation mode.
See cp_hashtable_set_mode for a list of mode bits and their effects.
CPROPS_DLL void ** cp_hashtable_get_values | ( | cp_hashtable * | table | ) |
get an array containing all values in the table.
CPROPS_DLL int cp_hashtable_lock | ( | cp_hashtable * | table, | |
int | type | |||
) |
by default the get, put and remove functions as well as set and unset mode perform their own locking.
Other functions do not synchronize, since it is assumed they would be called in a single cp_thread context - the initialization * and deletion functions in particular. You can of course set COLLECTION_MODE_NOSYNC and perform your own synchronization.
The current implementation uses a queued read/write lock where blocked cp_threads are guaranteed to be woken by the order in which they attempted
the following macros are defined for convenience:
table | cp_hashtable to lock | |
type | COLLECTION_LOCK_READ or COLLECTION_LOCK_WRITE |
CPROPS_DLL void * cp_hashtable_put | ( | cp_hashtable * | table, | |
void * | key, | |||
void * | value | |||
) |
the key 'key' will be assigned to the value 'value'.
The new value will override an old value if one exists. The old value will not be deallocated. If you would need the old value to be released call cp_hashtable_put_safe instead.
Referenced by cp_httpclient_set_header(), cp_httpclient_set_parameter(), and cp_httpclient_set_user_agent().
CPROPS_DLL void * cp_hashtable_remove | ( | cp_hashtable * | table, | |
void * | key | |||
) |
Attempts to remove the mapping for key from the table.
table | the object | |
key | Key to search for. |
value | retrieved by the key (that was removed) | |
NULL | if the table does not contain the requested key. |
Referenced by cp_httpclient_set_header(), and cp_httpclient_set_parameter().
void* cp_hashtable_remove_by_mode | ( | cp_hashtable * | table, | |
void * | key, | |||
int | mode | |||
) |
Remove an entry from the table by key with locking mode.
Get the value by key and destroy the entry.
table | the object | |
key | Key to search for. | |
mode | operation/locking mode |
value | of the entry with key. | |
NULL | otherwise (no entry with given key) |
References COLLECTION_LOCK_WRITE, cp_hashtable_choose_size(), cp_hashtable_remove_internal(), cp_hashtable_resize(), and cp_hashtable_resize_nosync().
CPROPS_DLL int cp_hashtable_remove_deep | ( | cp_hashtable * | table, | |
void * | key | |||
) |
Remove with COLLECTION_MODE_DEEP set.
removes a mapping from the table, and deallocates the memory for the mapped key and value.
table | the object | |
key | Key to search for. |
void* cp_hashtable_remove_internal | ( | cp_hashtable * | table, | |
void * | key, | |||
long | code, | |||
int | mode, | |||
int | resize | |||
) |
Internal remove an entry from the table by key.
Get the value by key and destroy the entry.
table | the object | |
key | Key to search for. | |
code | Hash code of the Key (saves recalculating it) | |
mode | operation mode | |
resize | 0: search in the normal table, 1: search in the resize table |
value | of the entry with key. | |
NULL | otherwise (no entry with given key) |
References COLLECTION_MODE_DEEP, and COLLECTION_MODE_MULTIPLE_VALUES.
Referenced by cp_hashtable_remove_by_mode().
static cp_hashtable_entry** cp_hashtable_replace_internal | ( | cp_hashtable * | table, | |
void * | key, | |||
void * | value, | |||
unsigned long | code, | |||
int | option, | |||
int | resize | |||
) | [static] |
Internal replace an existing entry with a new key, value pair.
table | the object | |
key | Key to search for. | |
value | new value | |
code | Hash code of the Key (saves recalculating it) | |
option | operation mode | |
resize | 0: search in the normal table, 1: search in the resize table |
References COLLECTION_MODE_DEEP, and COLLECTION_MODE_MULTIPLE_VALUES.
void* cp_hashtable_resize | ( | cp_hashtable * | table, | |
long | new_size | |||
) |
Initiates a resize of the cp_hashtable which is executed in the background.
References cp_hashtable_resize_thread().
Referenced by cp_hashtable_remove_by_mode().
void* cp_hashtable_resize_nosync | ( | cp_hashtable * | table, | |
unsigned long | new_size | |||
) |
Resizes the table to a new size.
This is invoked by the insertion code if the load * factor goes over the fill factor limits.
table | the object | |
new_size | desired size. The system trys to optmize the actual size for good distribution. |
References cp_hashtable_choose_size().
Referenced by cp_hashtable_remove_by_mode().
void* cp_hashtable_resize_thread | ( | void * | tbl | ) |
<<Thread>> resize a cp_hashtable.
This cp_thread does a background resize of the table. It creates a new table and moves the entries to the new table.
References COLLECTION_LOCK_WRITE.
Referenced by cp_hashtable_resize().
CPROPS_DLL int cp_hashtable_set_mode | ( | cp_hashtable * | table, | |
int | mode | |||
) |
set the operation mode as a bit set of the following options:
The parameter bits are flipped on. If the current mode is COLLECTION_MODE_DEEP and you want to change it, call cp_hashtable_unset_mode(table, COLLECTION_MODE_DEEP).
void* lookup_internal | ( | cp_hashtable * | table, | |
void * | key, | |||
long | code, | |||
int | option, | |||
int | resize | |||
) |
Retrieves the value by key from normal or resizing table.
table | the object | |
key | Key to search for. | |
code | Hash code of the Key (saves recalculating it) | |
option | operation mode | |
resize | 0: search in the normal table, 1: search in the resize table |
value | of the entry with key. | |
NULL | otherwise (no entry with given key) |
References COLLECTION_MODE_MULTIPLE_VALUES, cp_list_append(), and cp_list_insert().
int table_sizes[] [static] |
{ 5, 7, 11, 23, 47, 79, 97, 157, 197, 299, 397, 599, 797, 1297, 1597, 2499, 3199, 4799, 6397, 9599, 12799, 19199, 25597, 38399, 51199, 76799, 102397, 153599, 204797, 306797, 409597, 614399, 819199, 1288799, 1638397, 2457599, 3276799, 4915217, 6553577, 9830393 }