Updates with latest tommyds library.

This commit is contained in:
Andrea Mazzoleni 2014-09-26 23:50:01 +02:00
parent eeea58b42a
commit d84babb6bd
16 changed files with 189 additions and 118 deletions

View file

@ -1505,9 +1505,27 @@ void* malloc_nofail(size_t size)
return ptr;
}
void* cmalloc_nofail(size_t count, size_t size)
void* calloc_nofail(size_t count, size_t size)
{
return malloc_nofail(count * size);
void* ptr;
size *= count;
/* see the note in malloc_nofail() of why we don't use calloc() */
ptr = malloc(size);
if (!ptr) {
/* LCOV_EXCL_START */
malloc_fail(size);
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
memset(ptr, 0, size);
mcounter += size;
return ptr;
}
char* strdup_nofail(const char* str)

View file

@ -468,7 +468,7 @@ void* malloc_nofail(size_t size);
* Safe cmalloc.
* If no memory is available, it aborts.
*/
void* cmalloc_nofail(size_t count, size_t size);
void* calloc_nofail(size_t count, size_t size);
/**
* Safe aligned malloc.

View file

@ -30,6 +30,7 @@
/* redefine the malloc for tommy use */
#define tommy_malloc malloc_nofail
#define tommy_calloc calloc_nofail
#define tommy_free free
#include "tommyhash.c"

View file

@ -27,48 +27,54 @@
#include "tommyarray.h"
#include <string.h> /* for memset */
/******************************************************************************/
/* array */
void tommy_array_init(tommy_array* array)
{
unsigned i;
/* fixed initial size */
array->bucket_bit = TOMMY_ARRAY_BIT;
array->bucket_max = 1 << array->bucket_bit;
array->bucket[0] = tommy_cast(void**, tommy_malloc(array->bucket_max * sizeof(void*)));
array->bucket[0] = tommy_cast(void**, tommy_calloc(array->bucket_max, sizeof(void*)));
for (i = 1; i < TOMMY_ARRAY_BIT; ++i)
array->bucket[i] = array->bucket[0];
/* initializes it with zeros */
memset(array->bucket[0], 0, array->bucket_max * sizeof(void*));
array->bucket_mac = 1;
array->bucket_mac = TOMMY_ARRAY_BIT;
array->size = 0;
}
void tommy_array_done(tommy_array* array)
{
unsigned i;
for(i=0;i<array->bucket_mac;++i)
tommy_free(array->bucket[i]);
tommy_free(array->bucket[0]);
for (i = TOMMY_ARRAY_BIT; i < array->bucket_mac; ++i) {
void** segment = array->bucket[i];
tommy_free(&segment[1 << i]);
}
}
void tommy_array_grow(tommy_array* array, unsigned size)
{
while (size > array->bucket_max) {
/* allocate one more bucket */
array->bucket[array->bucket_mac] = tommy_cast(void**, tommy_malloc(array->bucket_max * sizeof(void*)));
if (array->size >= size)
return;
array->size = size;
/* initializes it with zeros */
memset(array->bucket[array->bucket_mac], 0, array->bucket_max * sizeof(void*));
while (size > array->bucket_max) {
void** segment;
/* allocate one more segment */
segment = tommy_cast(void**, tommy_calloc(array->bucket_max, sizeof(void*)));
/* store it adjusting the offset */
array->bucket[array->bucket_mac] = &segment[-array->bucket_max];
++array->bucket_mac;
++array->bucket_bit;
array->bucket_max = 1 << array->bucket_bit;
}
if (array->size < size)
array->size = size;
}
tommy_size_t tommy_array_memory_usage(tommy_array* array)

View file

@ -92,22 +92,14 @@ void tommy_array_grow(tommy_array* array, unsigned size);
*/
tommy_inline void** tommy_array_ref(tommy_array* array, unsigned pos)
{
unsigned bsr;
unsigned bsr;
assert(pos < array->size);
/* special case for the first bucket */
if (pos < (1 << TOMMY_ARRAY_BIT)) {
return &array->bucket[0][pos];
}
/* get the highest bit set, in case of all 0, return 0 */
bsr = tommy_ilog2_u32(pos | 1);
/* get the highest bit set */
bsr = tommy_ilog2_u32(pos);
/* clear the highest bit */
pos -= 1 << bsr;
return &array->bucket[bsr - TOMMY_ARRAY_BIT + 1][pos];
return &array->bucket[bsr][pos];
}
/**

View file

@ -27,8 +27,6 @@
#include "tommyarrayblk.h"
#include <string.h> /* for memset */
/******************************************************************************/
/* array */
@ -43,7 +41,7 @@ void tommy_arrayblk_done(tommy_arrayblk* array)
{
unsigned i;
for(i=0;i<tommy_array_size(&array->block);++i)
for (i = 0; i < tommy_array_size(&array->block); ++i)
tommy_free(tommy_array_get(&array->block, i));
tommy_array_done(&array->block);
@ -51,8 +49,15 @@ void tommy_arrayblk_done(tommy_arrayblk* array)
void tommy_arrayblk_grow(tommy_arrayblk* array, unsigned size)
{
unsigned block_max = (size + TOMMY_ARRAYBLK_SIZE - 1) / TOMMY_ARRAYBLK_SIZE;
unsigned block_mac = tommy_array_size(&array->block);
unsigned block_max;
unsigned block_mac;
if (array->size >= size)
return;
array->size = size;
block_max = (size + TOMMY_ARRAYBLK_SIZE - 1) / TOMMY_ARRAYBLK_SIZE;
block_mac = tommy_array_size(&array->block);
if (block_mac < block_max) {
/* grow the block array */
@ -60,10 +65,7 @@ void tommy_arrayblk_grow(tommy_arrayblk* array, unsigned size)
/* allocate new blocks */
while (block_mac < block_max) {
void* ptr = tommy_malloc(TOMMY_ARRAYBLK_SIZE * sizeof(void*));
/* initializes it with zeros */
memset(ptr, 0, TOMMY_ARRAYBLK_SIZE * sizeof(void*));
void* ptr = tommy_calloc(TOMMY_ARRAYBLK_SIZE, sizeof(void*));
/* set the new block */
tommy_array_set(&array->block, block_mac, ptr);
@ -71,9 +73,6 @@ void tommy_arrayblk_grow(tommy_arrayblk* array, unsigned size)
++block_mac;
}
}
if (array->size < size)
array->size = size;
}
tommy_size_t tommy_arrayblk_memory_usage(tommy_arrayblk* array)

View file

@ -52,7 +52,7 @@
/**
* Elements for each block.
*/
#define TOMMY_ARRAYBLK_SIZE (64 * 1024)
#define TOMMY_ARRAYBLK_SIZE (4 * 1024)
/**
* Array.

View file

@ -27,8 +27,6 @@
#include "tommyarrayblkof.h"
#include <string.h> /* for memset */
/******************************************************************************/
/* array */
@ -43,7 +41,7 @@ void tommy_arrayblkof_done(tommy_arrayblkof* array)
{
unsigned i;
for(i=0;i<tommy_array_size(&array->block);++i)
for (i = 0; i < tommy_array_size(&array->block); ++i)
tommy_free(tommy_array_get(&array->block, i));
tommy_array_done(&array->block);
@ -51,8 +49,15 @@ void tommy_arrayblkof_done(tommy_arrayblkof* array)
void tommy_arrayblkof_grow(tommy_arrayblkof* array, unsigned size)
{
unsigned block_max = (size + TOMMY_ARRAYBLK_SIZE - 1) / TOMMY_ARRAYBLK_SIZE;
unsigned block_mac = tommy_array_size(&array->block);
unsigned block_max;
unsigned block_mac;
if (array->size >= size)
return;
array->size = size;
block_max = (size + TOMMY_ARRAYBLK_SIZE - 1) / TOMMY_ARRAYBLK_SIZE;
block_mac = tommy_array_size(&array->block);
if (block_mac < block_max) {
/* grow the block array */
@ -60,10 +65,7 @@ void tommy_arrayblkof_grow(tommy_arrayblkof* array, unsigned size)
/* allocate new blocks */
while (block_mac < block_max) {
void* ptr = tommy_malloc(TOMMY_ARRAYBLK_SIZE * array->element_size);
/* initializes it with zeros */
memset(ptr, 0, TOMMY_ARRAYBLK_SIZE * array->element_size);
void* ptr = tommy_calloc(TOMMY_ARRAYBLK_SIZE, array->element_size);
/* set the new block */
tommy_array_set(&array->block, block_mac, ptr);
@ -71,9 +73,6 @@ void tommy_arrayblkof_grow(tommy_arrayblkof* array, unsigned size)
++block_mac;
}
}
if (array->size < size)
array->size = size;
}
tommy_size_t tommy_arrayblkof_memory_usage(tommy_arrayblkof* array)

View file

@ -51,7 +51,7 @@
/**
* Elements for each block.
*/
#define TOMMY_ARRAYBLKOF_SIZE (64 * 1024)
#define TOMMY_ARRAYBLKOF_SIZE (4 * 1024)
/**
* Array.

View file

@ -211,9 +211,9 @@ tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func*
while (mask != 1) {
mask >>= 1;
if (mask & 1) {
tommy_chain_merge_degenerated(&bit[i+1], &bit[i], cmp);
tommy_chain_merge_degenerated(&bit[i + 1], &bit[i], cmp);
} else {
bit[i+1] = bit[i];
bit[i + 1] = bit[i];
}
++i;
}

View file

@ -42,33 +42,33 @@ tommy_inline tommy_uint32_t tommy_le_uint32_read(const void* ptr)
#endif
}
#define tommy_rot(x,k) \
(((x)<<(k)) | ((x)>>(32-(k))))
#define tommy_rot(x, k) \
(((x) << (k)) | ((x) >> (32 - (k))))
#define tommy_mix(a,b,c) \
#define tommy_mix(a, b, c) \
do { \
a -= c; a ^= tommy_rot(c, 4); c += b; \
b -= a; b ^= tommy_rot(a, 6); a += c; \
c -= b; c ^= tommy_rot(b, 8); b += a; \
a -= c; a ^= tommy_rot(c,16); c += b; \
b -= a; b ^= tommy_rot(a,19); a += c; \
a -= c; a ^= tommy_rot(c, 16); c += b; \
b -= a; b ^= tommy_rot(a, 19); a += c; \
c -= b; c ^= tommy_rot(b, 4); b += a; \
} while (0)
#define tommy_final(a,b,c) \
#define tommy_final(a, b, c) \
do { \
c ^= b; c -= tommy_rot(b,14); \
a ^= c; a -= tommy_rot(c,11); \
b ^= a; b -= tommy_rot(a,25); \
c ^= b; c -= tommy_rot(b,16); \
a ^= c; a -= tommy_rot(c,4); \
b ^= a; b -= tommy_rot(a,14); \
c ^= b; c -= tommy_rot(b,24); \
c ^= b; c -= tommy_rot(b, 14); \
a ^= c; a -= tommy_rot(c, 11); \
b ^= a; b -= tommy_rot(a, 25); \
c ^= b; c -= tommy_rot(b, 16); \
a ^= c; a -= tommy_rot(c, 4); \
b ^= a; b -= tommy_rot(a, 14); \
c ^= b; c -= tommy_rot(b, 24); \
} while (0)
tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len)
{
const unsigned char* key = tommy_cast(const unsigned char*,void_key);
const unsigned char* key = tommy_cast(const unsigned char*, void_key);
tommy_uint32_t a, b, c;
a = b = c = 0xdeadbeef + ((tommy_uint32_t)key_len) + init_val;
@ -78,7 +78,7 @@ tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tom
b += tommy_le_uint32_read(key + 4);
c += tommy_le_uint32_read(key + 8);
tommy_mix(a,b,c);
tommy_mix(a, b, c);
key_len -= 12;
key += 12;
@ -110,14 +110,14 @@ tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tom
case 1 : a += key[0];
}
tommy_final(a,b,c);
tommy_final(a, b, c);
return c;
}
tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tommy_size_t key_len)
{
const unsigned char* key = tommy_cast(const unsigned char*,void_key);
const unsigned char* key = tommy_cast(const unsigned char*, void_key);
tommy_uint32_t a, b, c;
a = b = c = 0xdeadbeef + ((tommy_uint32_t)key_len) + (init_val & 0xffffffff);
@ -128,7 +128,7 @@ tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tom
b += tommy_le_uint32_read(key + 4);
c += tommy_le_uint32_read(key + 8);
tommy_mix(a,b,c);
tommy_mix(a, b, c);
key_len -= 12;
key += 12;
@ -160,7 +160,7 @@ tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tom
case 1 : a += key[0];
}
tommy_final(a,b,c);
tommy_final(a, b, c);
return c + ((tommy_uint64_t)b << 32);
}

View file

@ -24,7 +24,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/** \file
* Hash functions for the use with ::tommy_hashtable, ::tommy_hashdyn and ::tommy_hashlin.
*/
@ -65,7 +65,7 @@ tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tom
* Using a different initialization value, you can generate a completely different set of hash values.
* Use 0 if not relevalt.
* \param void_key Pointer at the data to hash.
* \param key_len Size of the data to hash.
* \param key_len Size of the data to hash.
* \note
* This function is endianess independent.
* \return The hash value of 64 bits.

View file

@ -28,8 +28,6 @@
#include "tommyhashdyn.h"
#include "tommylist.h"
#include <string.h> /* for memset */
/******************************************************************************/
/* hashdyn */
@ -39,8 +37,7 @@ void tommy_hashdyn_init(tommy_hashdyn* hashdyn)
hashdyn->bucket_bit = TOMMY_HASHDYN_BIT;
hashdyn->bucket_max = 1 << hashdyn->bucket_bit;
hashdyn->bucket_mask = hashdyn->bucket_max - 1;
hashdyn->bucket = tommy_cast(tommy_hashdyn_node**, tommy_malloc(hashdyn->bucket_max * sizeof(tommy_hashdyn_node*)));
memset(hashdyn->bucket, 0, hashdyn->bucket_max * sizeof(tommy_hashdyn_node*));
hashdyn->bucket = tommy_cast(tommy_hashdyn_node**, tommy_calloc(hashdyn->bucket_max, sizeof(tommy_hashdyn_node*)));
hashdyn->count = 0;
}
@ -66,6 +63,9 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, unsigned new_bucket_bit
new_bucket_max = 1 << new_bucket_bit;
new_bucket_mask = new_bucket_max - 1;
/* allocate the new vector using malloc() and not calloc() */
/* because data is fully initialized in the update process */
new_bucket = tommy_cast(tommy_hashdyn_node**, tommy_malloc(new_bucket_max * sizeof(tommy_hashdyn_node*)));
/* reinsert all the elements */
@ -73,7 +73,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, unsigned new_bucket_bit
unsigned i;
/* grow */
for(i=0;i<bucket_max;++i) {
for (i = 0; i < bucket_max; ++i) {
tommy_hashdyn_node* j;
/* setup the new two buckets */
@ -96,7 +96,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, unsigned new_bucket_bit
unsigned i;
/* shrink */
for(i=0;i<new_bucket_max;++i) {
for (i = 0; i < new_bucket_max; ++i) {
/* setup the new bucket with the lower bucket*/
new_bucket[i] = hashdyn->bucket[i];
@ -165,28 +165,62 @@ void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node*
void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
{
unsigned pos = hash % hashdyn->bucket_max;
tommy_hashdyn_node* i = hashdyn->bucket[pos];
tommy_hashdyn_node* node = hashdyn->bucket[pos];
while (i) {
while (node) {
/* we first check if the hash matches, as in the same bucket we may have multiples hash values */
if (i->key == hash && cmp(cmp_arg, i->data) == 0) {
tommy_list_remove_existing(&hashdyn->bucket[pos], i);
if (node->key == hash && cmp(cmp_arg, node->data) == 0) {
tommy_list_remove_existing(&hashdyn->bucket[pos], node);
--hashdyn->count;
hashdyn_shrink_step(hashdyn);
return i->data;
return node->data;
}
i = i->next;
node = node->next;
}
return 0;
}
void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func)
{
unsigned bucket_max = hashdyn->bucket_max;
tommy_hashdyn_node** bucket = hashdyn->bucket;
unsigned pos;
for (pos = 0; pos < bucket_max; ++pos) {
tommy_hashdyn_node* node = bucket[pos];
while (node) {
void* data = node->data;
node = node->next;
func(data);
}
}
}
void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* func, void* arg)
{
unsigned bucket_max = hashdyn->bucket_max;
tommy_hashdyn_node** bucket = hashdyn->bucket;
unsigned pos;
for (pos = 0; pos < bucket_max; ++pos) {
tommy_hashdyn_node* node = bucket[pos];
while (node) {
void* data = node->data;
node = node->next;
func(arg, data);
}
}
}
tommy_size_t tommy_hashdyn_memory_usage(tommy_hashdyn* hashdyn)
{
return hashdyn->bucket_max * (tommy_size_t)sizeof(hashdyn->bucket[0])
+ tommy_hashdyn_count(hashdyn) * (tommy_size_t)sizeof(tommy_hashdyn_node);
+ tommy_hashdyn_count(hashdyn) * (tommy_size_t)sizeof(tommy_hashdyn_node);
}

View file

@ -32,15 +32,15 @@
* the size then it reaches a load factor greater than 0.5 and it halves the size with a load
* factor lower than 0.125.
*
* All the elements are reallocated in a single resize operation done inside
* All the elements are reallocated in a single resize operation done inside
* tommy_hashdyn_insert() or tommy_hashdyn_remove().
*
* Note that the resize operation takes approximatively 100 [ms] with 1 million of elements,
* Note that the resize operation takes approximatively 100 [ms] with 1 million of elements,
* and 1 [second] with 10 millions. This could be a problem in real-time applications.
*
* The resize also fragment the heap, as it involves allocating a double-sized table, copy elements,
* The resize also fragment the heap, as it involves allocating a double-sized table, copy elements,
* and deallocating the older table. Leaving a big hole in the heap.
*
*
* The ::tommy_hashlin hashtable fixes both problems.
*
* To initialize the hashtable you have to call tommy_hashdyn_init().
@ -81,7 +81,7 @@
* return *(const int*)arg != ((const struct object*)obj)->value;
* }
*
* int value_to_find = 1;
* int value_to_find = 1;
* struct object* obj = tommy_hashdyn_search(&hashdyn, compare, &value_to_find, tommy_inthash_u32(value_to_find));
* if (!obj) {
* // not found
@ -96,7 +96,7 @@
* different keys.
*
* \code
* int value_to_find = 1;
* int value_to_find = 1;
* tommy_node* i = tommy_hashdyn_bucket(&hashdyn, tommy_inthash_u32(value_to_find));
* while (i) {
* struct object* obj = i->data; // gets the object pointer
@ -129,7 +129,7 @@
*
* Note that you cannot iterates over all the elements in the hashtable using the
* hashtable itself. You have to insert all the elements also in a ::tommy_list,
* and use the list to iterate. See the \ref multiindex example for more detail.
* and use the list to iterate. See the \ref multiindex example for more detail.
*/
#ifndef __TOMMYHASHDYN_H
@ -200,7 +200,7 @@ void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const
* The bucket is guaranteed to contain ALL the elements with the specified hash,
* but it can contain also others.
* You can access elements in the bucket following the ::next pointer until 0.
* \param hash Hash of the element to find.
* \param hash Hash of the element to find.
* \return The head of the bucket, or 0 if empty.
*/
tommy_inline tommy_hashdyn_node* tommy_hashdyn_bucket(tommy_hashdyn* hashdyn, tommy_hash_t hash)
@ -221,6 +221,7 @@ tommy_inline tommy_hashdyn_node* tommy_hashdyn_bucket(tommy_hashdyn* hashdyn, to
tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
{
tommy_hashdyn_node* i = tommy_hashdyn_bucket(hashdyn, hash);
while (i) {
/* we first check if the hash matches, as in the same bucket we may have multiples hash values */
if (i->key == hash && cmp(cmp_arg, i->data) == 0)
@ -237,6 +238,16 @@ tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_fun
*/
void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node);
/**
* Calls the specified function for each element in the hashtable.
*/
void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func);
/**
* Calls the specified function with argument for each element in the hashtable.
*/
void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* func, void* arg);
/**
* Gets the number of elements.
*/

View file

@ -96,7 +96,7 @@
*
* i = i_next; // goes to the next element
* }
* \endcode
* \endcode
*/
#ifndef __TOMMYLIST_H
@ -151,7 +151,7 @@ tommy_inline tommy_node* tommy_list_tail(tommy_list* list)
*/
tommy_inline void tommy_list_insert_first(tommy_list* list, tommy_node* node)
{
/* one element "circular" prev list */
/* one element "circular" prev list */
node->prev = node;
/* one element "0 terminated" next list */
@ -264,7 +264,7 @@ tommy_inline void* tommy_list_remove_existing(tommy_list* list, tommy_node* node
tommy_node* head = tommy_list_head(list);
/* remove from the "circular" prev list */
if (node->next) {
if (node->next) {
node->next->prev = node->prev;
} else {
head->prev = node->prev; /* the last */
@ -313,6 +313,7 @@ tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list)
tommy_inline void tommy_list_foreach(tommy_list* list, tommy_foreach_func* func)
{
tommy_node* node = tommy_list_head(list);
while (node) {
void* data = node->data;
node = node->next;
@ -326,6 +327,7 @@ tommy_inline void tommy_list_foreach(tommy_list* list, tommy_foreach_func* func)
tommy_inline void tommy_list_foreach_arg(tommy_list* list, tommy_foreach_arg_func* func, void* arg)
{
tommy_node* node = tommy_list_head(list);
while (node) {
void* data = node->data;
node = node->next;

View file

@ -64,16 +64,25 @@ typedef int tommy_bool_t; /**< Generic boolean type. */
/******************************************************************************/
/* heap */
/* by default uses malloc/realloc/free */
/* by default uses malloc/calloc/realloc/free */
/**
* Generic malloc(), realloc() and free() functions.
* Redefine them to what you need. By default they map to the C malloc(), realloc() and free().
* Generic malloc(), calloc(), realloc() and free() functions.
* Redefine them to what you need. By default they map to the C malloc(), calloc(), realloc() and free().
*/
#if !defined(tommy_malloc) && !defined(tommy_realloc) && !defined(tommy_free)
#if !defined(tommy_malloc) || !defined(tommy_calloc) || !defined(tommy_realloc) || !defined(tommy_free)
#include <stdlib.h>
#endif
#if !defined(tommy_malloc)
#define tommy_malloc malloc
#endif
#if !defined(tommy_calloc)
#define tommy_calloc calloc
#endif
#if !defined(tommy_realloc)
#define tommy_realloc realloc
#endif
#if !defined(tommy_free)
#define tommy_free free
#endif
@ -109,7 +118,7 @@ typedef int tommy_bool_t; /**< Generic boolean type. */
*/
#if !defined(tommy_likely)
#if defined(__GNUC__)
#define tommy_likely(x) __builtin_expect(!!(x),1)
#define tommy_likely(x) __builtin_expect(!!(x), 1)
#else
#define tommy_likely(x) (x)
#endif
@ -120,7 +129,7 @@ typedef int tommy_bool_t; /**< Generic boolean type. */
*/
#if !defined(tommy_unlikely)
#if defined(__GNUC__)
#define tommy_unlikely(x) __builtin_expect(!!(x),0)
#define tommy_unlikely(x) __builtin_expect(!!(x), 0)
#else
#define tommy_unlikely(x) (x)
#endif
@ -235,14 +244,14 @@ typedef int tommy_compare_func(const void* obj_a, const void* obj_b);
* return *(const int*)arg != ((const struct object*)obj)->value;
* }
*
* int value_to_find = 1;
* int value_to_find = 1;
* struct object* obj = tommy_hashtable_search(&hashtable, compare, &value_to_find, tommy_inthash_u32(value_to_find));
* if (!obj) {
* // not found
* } else {
* // found
* }
* \endcode
* \endcode
*
*/
typedef int tommy_search_func(const void* arg, const void* obj);
@ -278,7 +287,7 @@ typedef void tommy_foreach_arg_func(void* arg, void* obj);
* Integer log2 for constants.
* You can use it only for exact power of 2 up to 256.
*/
#define TOMMY_ILOG2(value) ((value) == 256 ? 8 : (value) == 128 ? 7 :(value) == 64 ? 6 : (value) == 32 ? 5 : (value) == 16 ? 4 : (value) == 8 ? 3 : (value) == 4 ? 2 : (value) == 2 ? 1 : 0)
#define TOMMY_ILOG2(value) ((value) == 256 ? 8 : (value) == 128 ? 7 : (value) == 64 ? 6 : (value) == 32 ? 5 : (value) == 16 ? 4 : (value) == 8 ? 3 : (value) == 4 ? 2 : (value) == 2 ? 1 : 0)
/**
* Bit scan reverse or integer log2.
@ -288,9 +297,9 @@ typedef void tommy_foreach_arg_func(void* arg, void* obj);
* To force a return 0 in this case, you can use tommy_ilog2(value | 1).
*
* Other interesting ways for bitscan can be found at:
*
* Bit Twiddling Hacks
* http://graphics.stanford.edu/~seander/bithacks.html
*
* Bit Twiddling Hacks
* http://graphics.stanford.edu/~seander/bithacks.html
*
* Chess Programming BitScan
* http://chessprogramming.wikispaces.com/BitScan
@ -356,7 +365,7 @@ tommy_inline unsigned tommy_ctz_u32(tommy_uint32_t value)
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
return TOMMY_DE_BRUIJN_INDEX_CTZ[(tommy_uint32_t)(((value & -value) * 0x077CB531U)) >> 27];
return TOMMY_DE_BRUIJN_INDEX_CTZ[(tommy_uint32_t)(((value & - value) * 0x077CB531U)) >> 27];
#endif
}