32#define HASHTABLE_BUCKET_POOL_BLOCK_SIZE 128 
   35#define HASHTABLE_INITIAL_SIZE           257 
   38static const size_t PRIMES[] =
 
   57    #if SIZE_MAX == 18446744073709551615UL 
   95#define HASHTABLE_INDEX(table, key) table->hash(key) % table->size 
  102    assert(hash_func != NULL);
 
  103    assert(compare_keys != NULL);
 
  104    assert(size <= SIZE_MAX / 
sizeof(
struct _Bucket *));
 
  114    hashtable_init(table, size, hash_func, compare_keys, free_key, free_value);
 
 
  122    assert(table != NULL);
 
  123    assert(hash_func != NULL);
 
  124    assert(compare_keys != NULL);
 
  125    assert(size <= SIZE_MAX / 
sizeof(
struct _Bucket *));
 
  127    size_t table_size = HASHTABLE_INITIAL_SIZE;
 
  134    table->
buckets = (
struct _Bucket **)calloc(table_size, 
sizeof(
struct _Bucket *));
 
  147    table->
size = table_size;
 
  160    table->
hash = hash_func;
 
 
  169    assert(table != NULL);
 
 
  178    assert(table != NULL);
 
  182        for(
size_t i = 0; i < table->
size; ++i)
 
  184            struct _Bucket *iter;
 
  210    assert(table != NULL);
 
  212    _hashtable_free_memory(table);
 
 
  220    assert(table != NULL);
 
  224    _hashtable_free_memory(table);
 
  225    memset(table->
buckets, 0, 
sizeof(
struct _Bucket *) * table->
size);
 
 
  234    assert(table != NULL);
 
  235    assert(table->
size > 0);
 
  237    size_t old_size = table->
size;
 
  242    if(!table->
size || table->
size > SIZE_MAX / 
sizeof(
struct _Bucket *))
 
  244        fprintf(stderr, 
"%s(): integer overflow.\n", __func__);
 
  248    struct _Bucket **buckets = table->
buckets;
 
  250    table->
buckets = (
struct _Bucket **)calloc(table->
size, 
sizeof(
struct _Bucket *));
 
  258    for(
size_t i = 0; i < old_size; ++i)
 
  260        struct _Bucket *iter = buckets[i];
 
  264            struct _Bucket *next = iter->next;
 
  265            size_t index = HASHTABLE_INDEX(table, iter->key);
 
  269                iter->next = table->
buckets[index];
 
  285static struct _Bucket *
 
  286_hashtable_find_bucket(
const HashTable *table, 
struct _Bucket *head, 
const void *key)
 
  288    assert(table != NULL);
 
  291    struct _Bucket *iter = head;
 
  292    struct _Bucket *item = NULL;
 
  312    assert(table != NULL);
 
  317        _hashtable_resize(table);
 
  320    size_t index = HASHTABLE_INDEX(table, key);
 
  321    struct _Bucket *head = table->
buckets[index];
 
  322    struct _Bucket *item = _hashtable_find_bucket(table, head, key);
 
  345    else if(table->
count < SIZE_MAX)
 
  360        fprintf(stderr, 
"%s(): integer overflow.\n", __func__);
 
 
  369    assert(table != NULL);
 
  372    struct _Bucket *iter;
 
  373    size_t index = HASHTABLE_INDEX(table, key);
 
  375    if((iter = table->
buckets[index]))
 
  377        struct _Bucket *prev = NULL;
 
  378        bool removed = 
false;
 
  380        while(iter && !removed)
 
  396                    prev->next = iter->next;
 
 
  418    assert(table != NULL);
 
  421    struct _Bucket *head = table->
buckets[HASHTABLE_INDEX(table, key)];
 
  422    struct _Bucket *item = _hashtable_find_bucket(table, head, key);
 
 
  437    assert(pair != NULL);
 
  438    assert(pair->bucket != NULL);
 
  439    assert(pair->bucket->key != NULL);
 
  441    return pair->bucket->key;
 
 
  447    assert(pair != NULL);
 
  448    assert(pair->bucket != NULL);
 
  449    assert(pair->bucket->key != NULL);
 
  451    return pair->bucket->data;
 
 
  457    assert(pair != NULL);
 
  458    assert(pair->bucket != NULL);
 
  459    assert(pair->bucket->key != NULL);
 
  461    if(pair->free_value && pair->bucket->data)
 
  463        pair->free_value(pair->bucket->data);
 
  466    pair->bucket->data = value;
 
 
  472    assert(table != NULL);
 
  475    struct _Bucket *head = table->
buckets[HASHTABLE_INDEX(table, key)];
 
  477    return _hashtable_find_bucket(table, head, key) != NULL;
 
 
  483    assert(table != NULL);
 
 
  491    assert(table != NULL);
 
 
  500    assert(iter != NULL);
 
  509    return iter->
liter != NULL;
 
  515    assert(iter != NULL);
 
  517    bool success = 
false;
 
  524            success = iter->
liter != NULL;
 
  528            success = _hashtable_iter_get_next_bucket(iter);
 
 
  539    assert(iter != NULL);
 
  541    return iter->
liter->key;
 
 
  547    assert(iter != NULL);
 
  549    return iter->
liter->data;
 
 
bool(* EqualFunc)(const void *a, const void *b)
void(* FreeFunc)(void *p)
uint32_t(* HashFunc)(const void *ptr)
void hashtable_clear(HashTable *table)
void * hashtable_pair_get_key(const HashTablePair *pair)
void * hashtable_pair_get_value(const HashTablePair *pair)
void hashtable_iter_init(const HashTable *table, HashTableIter *iter)
void * hashtable_iter_get_value(const HashTableIter *iter)
size_t hashtable_count(const HashTable *table)
void * hashtable_iter_get_key(const HashTableIter *iter)
HashTable * hashtable_new(size_t size, HashFunc hash_func, EqualFunc compare_keys, FreeFunc free_key, FreeFunc free_value)
bool hashtable_key_exists(const HashTable *table, const void *key)
void hashtable_remove(HashTable *table, const void *key)
void hashtable_pair_set_value(HashTablePair *pair, void *value)
bool hashtable_iter_next(HashTableIter *iter)
void hashtable_init(HashTable *table, size_t size, HashFunc hash_func, EqualFunc compare_keys, FreeFunc free_key, FreeFunc free_value)
void hashtable_free(HashTable *table)
void hashtable_destroy(HashTable *table)
HashTableInsertResult hashtable_set(HashTable *table, void *key, void *value, bool overwrite_key)
HashTablePair * hashtable_lookup(HashTable *table, const void *key)
struct HashTable::_Bucket ** buckets
Array containing pointers to buckets.
#define HASHTABLE_AUTO_RESIZE
struct HashTable::_HashTablePair pair
Last found key-value pair.
HashTableInsertResult
result of hashtable_set() method.
@ HASHTABLE_INSERT_RESULT_NEW
@ HASHTABLE_INSERT_RESULT_REPLACED
@ HASHTABLE_INSERT_RESULT_FAILED
struct _HashTablePair HashTablePair
Table containing lists of buckets to create associations between keys and values.
Structure to iterate over the elements of a HashTable.
void memory_pool_destroy(MemoryPool *pool)
MemoryPool * memory_pool_new(size_t item_size, size_t block_size)
This memory pool allocates blocks of memory and grows automatically.
Allocate groups of equal-sized chunks of memory.
void(* free)(struct _Pool *pool, void *ptr)
void *(* alloc)(struct _Pool *pool)