diff --git a/src/3rdparty/tommyds/tommyarrayof.c b/src/3rdparty/tommyds/tommyarrayof.c index 4f5f23b8..6af52750 100644 --- a/src/3rdparty/tommyds/tommyarrayof.c +++ b/src/3rdparty/tommyds/tommyarrayof.c @@ -30,15 +30,14 @@ /******************************************************************************/ /* array */ -TOMMY_API //!! -void tommy_arrayof_init(tommy_arrayof* array, tommy_size_t element_size) +TOMMY_API void tommy_arrayof_init(tommy_arrayof* array, tommy_size_t element_size) { tommy_uint_t i; /* fixed initial size */ array->element_size = element_size; array->bucket_bit = TOMMY_ARRAYOF_BIT; - array->bucket_max = 1 << array->bucket_bit; + array->bucket_max = (tommy_size_t)1 << array->bucket_bit; array->bucket[0] = tommy_calloc(array->bucket_max, array->element_size); for (i = 1; i < TOMMY_ARRAYOF_BIT; ++i) array->bucket[i] = array->bucket[0]; @@ -46,20 +45,18 @@ void tommy_arrayof_init(tommy_arrayof* array, tommy_size_t element_size) array->count = 0; } -TOMMY_API //!! -void tommy_arrayof_done(tommy_arrayof* array) +TOMMY_API void tommy_arrayof_done(tommy_arrayof* array) { tommy_uint_t i; tommy_free(array->bucket[0]); for (i = TOMMY_ARRAYOF_BIT; i < array->bucket_bit; ++i) { unsigned char* segment = tommy_cast(unsigned char*, array->bucket[i]); - tommy_free(segment + (((tommy_ptrdiff_t)1) << i) * array->element_size); + tommy_free(segment + ((tommy_ptrdiff_t)1 << i) * array->element_size); } } -TOMMY_API //!! -void tommy_arrayof_grow(tommy_arrayof* array, tommy_count_t count) +TOMMY_API void tommy_arrayof_grow(tommy_arrayof* array, tommy_size_t count) { if (array->count >= count) return; @@ -76,12 +73,11 @@ void tommy_arrayof_grow(tommy_arrayof* array, tommy_count_t count) array->bucket[array->bucket_bit] = segment - (tommy_ptrdiff_t)array->bucket_max * array->element_size; ++array->bucket_bit; - array->bucket_max = 1 << array->bucket_bit; + array->bucket_max = (tommy_size_t)1 << array->bucket_bit; } } -TOMMY_API //!! -tommy_size_t tommy_arrayof_memory_usage(tommy_arrayof* array) +TOMMY_API tommy_size_t tommy_arrayof_memory_usage(tommy_arrayof* array) { return array->bucket_max * (tommy_size_t)array->element_size; } diff --git a/src/3rdparty/tommyds/tommyarrayof.h b/src/3rdparty/tommyds/tommyarrayof.h index 4199a03f..2d1a16cf 100644 --- a/src/3rdparty/tommyds/tommyarrayof.h +++ b/src/3rdparty/tommyds/tommyarrayof.h @@ -54,49 +54,41 @@ */ #define TOMMY_ARRAYOF_BIT 6 -/** \internal - * Max number of elements as a power of 2. - */ -#define TOMMY_ARRAYOF_BIT_MAX 32 - /** * Array container type. * \note Don't use internal fields directly, but access the container only using functions. */ typedef struct tommy_arrayof_struct { - void* bucket[TOMMY_ARRAYOF_BIT_MAX]; /**< Dynamic array of buckets. */ + void* bucket[TOMMY_SIZE_BIT]; /**< Dynamic array of buckets. */ tommy_size_t element_size; /**< Size of the stored element in bytes. */ + tommy_size_t bucket_max; /**< Number of buckets. */ + tommy_size_t count; /**< Number of initialized elements in the array. */ tommy_uint_t bucket_bit; /**< Bits used in the bit mask. */ - tommy_count_t bucket_max; /**< Number of buckets. */ - tommy_count_t count; /**< Number of initialized elements in the array. */ } tommy_arrayof; /** * Initializes the array. * \param element_size Size in byte of the element to store in the array. */ -TOMMY_API //!! -void tommy_arrayof_init(tommy_arrayof* array, tommy_size_t element_size); +TOMMY_API void tommy_arrayof_init(tommy_arrayof* array, tommy_size_t element_size); /** * Deinitializes the array. */ -TOMMY_API //!! -void tommy_arrayof_done(tommy_arrayof* array); +TOMMY_API void tommy_arrayof_done(tommy_arrayof* array); /** * Grows the size up to the specified value. * All the new elements in the array are initialized with the 0 value. */ -TOMMY_API //!! -void tommy_arrayof_grow(tommy_arrayof* array, tommy_count_t size); +TOMMY_API void tommy_arrayof_grow(tommy_arrayof* array, tommy_size_t size); /** * Gets a reference of the element at the specified position. * You must be sure that space for this position is already * allocated calling tommy_arrayof_grow(). */ -tommy_inline void* tommy_arrayof_ref(tommy_arrayof* array, tommy_count_t pos) +tommy_inline void* tommy_arrayof_ref(tommy_arrayof* array, tommy_size_t pos) { unsigned char* ptr; tommy_uint_t bsr; @@ -104,7 +96,7 @@ tommy_inline void* tommy_arrayof_ref(tommy_arrayof* array, tommy_count_t pos) assert(pos < array->count); /* get the highest bit set, in case of all 0, return 0 */ - bsr = tommy_ilog2_u32(pos | 1); + bsr = tommy_ilog2(pos | 1); ptr = tommy_cast(unsigned char*, array->bucket[bsr]); @@ -114,7 +106,7 @@ tommy_inline void* tommy_arrayof_ref(tommy_arrayof* array, tommy_count_t pos) /** * Gets the initialized size of the array. */ -tommy_inline tommy_count_t tommy_arrayof_size(tommy_arrayof* array) +tommy_inline tommy_size_t tommy_arrayof_size(tommy_arrayof* array) { return array->count; } @@ -122,8 +114,7 @@ tommy_inline tommy_count_t tommy_arrayof_size(tommy_arrayof* array) /** * Gets the size of allocated memory. */ -TOMMY_API //!! -tommy_size_t tommy_arrayof_memory_usage(tommy_arrayof* array); +TOMMY_API tommy_size_t tommy_arrayof_memory_usage(tommy_arrayof* array); #endif diff --git a/src/3rdparty/tommyds/tommychain.h b/src/3rdparty/tommyds/tommychain.h index b15bc6ae..12d2514b 100644 --- a/src/3rdparty/tommyds/tommychain.h +++ b/src/3rdparty/tommyds/tommychain.h @@ -136,11 +136,6 @@ tommy_inline void tommy_chain_merge_degenerated(tommy_chain* first, tommy_chain* tommy_chain_merge(first, second, cmp); } -/** - * Max number of elements as a power of 2. - */ -#define TOMMY_CHAIN_BIT_MAX 32 - /** * Sorts a chain. * It's a stable merge sort using power of 2 buckets, with O(N*log(N)) complexity, @@ -158,20 +153,20 @@ tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func* /* * Bit buckets of chains. * Each bucket contains 2^i nodes or it's empty. - * The chain at address TOMMY_CHAIN_BIT_MAX is an independet variable operating as "carry". + * The chain at address TOMMY_BIT_MAX is an independet variable operating as "carry". * We keep it in the same "bit" vector to avoid reports from the valgrind tool sgcheck. */ - tommy_chain bit[TOMMY_CHAIN_BIT_MAX + 1]; + tommy_chain bit[TOMMY_SIZE_BIT + 1]; /** * Value stored inside the bit bucket. * It's used to know which bucket is empty of full. */ - tommy_count_t counter; + tommy_size_t counter; tommy_node* node = chain->head; tommy_node* tail = chain->tail; - tommy_count_t mask; - tommy_count_t i; + tommy_size_t mask; + tommy_size_t i; counter = 0; while (1) { @@ -179,9 +174,9 @@ tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func* tommy_chain* last; /* carry bit to add */ - last = &bit[TOMMY_CHAIN_BIT_MAX]; - bit[TOMMY_CHAIN_BIT_MAX].head = node; - bit[TOMMY_CHAIN_BIT_MAX].tail = node; + last = &bit[TOMMY_SIZE_BIT]; + bit[TOMMY_SIZE_BIT].head = node; + bit[TOMMY_SIZE_BIT].tail = node; next = node->next; /* add the bit, propagating the carry */ @@ -206,7 +201,7 @@ tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func* } /* merge the buckets */ - i = tommy_ctz_u32(counter); + i = tommy_ctz(counter); mask = counter >> i; while (mask != 1) { mask >>= 1; diff --git a/src/3rdparty/tommyds/tommyhash.c b/src/3rdparty/tommyds/tommyhash.c index 31ab12ee..33b11665 100644 --- a/src/3rdparty/tommyds/tommyhash.c +++ b/src/3rdparty/tommyds/tommyhash.c @@ -66,8 +66,7 @@ tommy_inline tommy_uint32_t tommy_le_uint32_read(const void* ptr) c ^= b; c -= tommy_rot(b, 24); \ } while (0) -TOMMY_API //!! -tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len) +TOMMY_API 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); tommy_uint32_t a, b, c; @@ -93,22 +92,22 @@ tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tom b += tommy_le_uint32_read(key + 4); a += tommy_le_uint32_read(key + 0); break; - case 11 : c += ((tommy_uint32_t)key[10]) << 16; - case 10 : c += ((tommy_uint32_t)key[9]) << 8; - case 9 : c += key[8]; + case 11 : c += ((tommy_uint32_t)key[10]) << 16; /* fallthrough */ + case 10 : c += ((tommy_uint32_t)key[9]) << 8; /* fallthrough */ + case 9 : c += key[8]; /* fallthrough */ case 8 : b += tommy_le_uint32_read(key + 4); a += tommy_le_uint32_read(key + 0); break; - case 7 : b += ((tommy_uint32_t)key[6]) << 16; - case 6 : b += ((tommy_uint32_t)key[5]) << 8; - case 5 : b += key[4]; + case 7 : b += ((tommy_uint32_t)key[6]) << 16; /* fallthrough */ + case 6 : b += ((tommy_uint32_t)key[5]) << 8; /* fallthrough */ + case 5 : b += key[4]; /* fallthrough */ case 4 : a += tommy_le_uint32_read(key + 0); break; - case 3 : a += ((tommy_uint32_t)key[2]) << 16; - case 2 : a += ((tommy_uint32_t)key[1]) << 8; - case 1 : a += key[0]; + case 3 : a += ((tommy_uint32_t)key[2]) << 16; /* fallthrough */ + case 2 : a += ((tommy_uint32_t)key[1]) << 8; /* fallthrough */ + case 1 : a += key[0]; /* fallthrough */ } tommy_final(a, b, c); @@ -116,8 +115,7 @@ tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tom return c; } -TOMMY_API //!! -tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tommy_size_t key_len) +TOMMY_API 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); tommy_uint32_t a, b, c; @@ -144,22 +142,22 @@ tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tom b += tommy_le_uint32_read(key + 4); a += tommy_le_uint32_read(key + 0); break; - case 11 : c += ((tommy_uint32_t)key[10]) << 16; - case 10 : c += ((tommy_uint32_t)key[9]) << 8; - case 9 : c += key[8]; + case 11 : c += ((tommy_uint32_t)key[10]) << 16; /* fallthrough */ + case 10 : c += ((tommy_uint32_t)key[9]) << 8; /* fallthrough */ + case 9 : c += key[8]; /* fallthrough */ case 8 : b += tommy_le_uint32_read(key + 4); a += tommy_le_uint32_read(key + 0); break; - case 7 : b += ((tommy_uint32_t)key[6]) << 16; - case 6 : b += ((tommy_uint32_t)key[5]) << 8; - case 5 : b += key[4]; + case 7 : b += ((tommy_uint32_t)key[6]) << 16; /* fallthrough */ + case 6 : b += ((tommy_uint32_t)key[5]) << 8; /* fallthrough */ + case 5 : b += key[4]; /* fallthrough */ case 4 : a += tommy_le_uint32_read(key + 0); break; - case 3 : a += ((tommy_uint32_t)key[2]) << 16; - case 2 : a += ((tommy_uint32_t)key[1]) << 8; - case 1 : a += key[0]; + case 3 : a += ((tommy_uint32_t)key[2]) << 16; /* fallthrough */ + case 2 : a += ((tommy_uint32_t)key[1]) << 8; /* fallthrough */ + case 1 : a += key[0]; /* fallthrough */ } tommy_final(a, b, c); @@ -167,9 +165,7 @@ tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tom return c + ((tommy_uint64_t)b << 32); } -//!! tommy_uint64_t init_val -> tommy_uint32_t init_val -TOMMY_API //!! -tommy_uint32_t tommy_strhash_u32(tommy_uint32_t init_val, const void* void_key) +TOMMY_API tommy_uint32_t tommy_strhash_u32(tommy_uint32_t init_val, const void* void_key) { const unsigned char* key = tommy_cast(const unsigned char*, void_key); tommy_uint32_t a, b, c; diff --git a/src/3rdparty/tommyds/tommyhash.h b/src/3rdparty/tommyds/tommyhash.h index 1ffb112b..8f54e0cb 100644 --- a/src/3rdparty/tommyds/tommyhash.h +++ b/src/3rdparty/tommyds/tommyhash.h @@ -37,11 +37,6 @@ /******************************************************************************/ /* hash */ -/** - * Hash type used in hashtables. - */ -typedef tommy_key_t tommy_hash_t; - /** * Hash function with a 32 bits result. * Implementation of the Robert Jenkins "lookup3" hash 32 bits version, @@ -60,8 +55,7 @@ typedef tommy_key_t tommy_hash_t; * This function is endianess independent. * \return The hash value of 32 bits. */ -TOMMY_API //!! -tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len); +TOMMY_API tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len); /** * Hash function with a 64 bits result. @@ -81,8 +75,7 @@ tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tom * This function is endianess independent. * \return The hash value of 64 bits. */ -TOMMY_API //!! -tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tommy_size_t key_len); +TOMMY_API tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tommy_size_t key_len); /** * String hash function with a 32 bits result. @@ -100,9 +93,7 @@ tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tom * This function is endianess independent. * \return The hash value of 32 bits. */ -//!! tommy_uint64_t init_val -> tommy_uint32_t init_val -TOMMY_API //!! -tommy_uint32_t tommy_strhash_u32(tommy_uint32_t init_val, const void* void_key); +TOMMY_API tommy_uint32_t tommy_strhash_u32(tommy_uint32_t init_val, const void* void_key); /** * Integer reversible hash function for 32 bits. diff --git a/src/3rdparty/tommyds/tommyhashdyn.c b/src/3rdparty/tommyds/tommyhashdyn.c index 0f5ec590..75565c8d 100644 --- a/src/3rdparty/tommyds/tommyhashdyn.c +++ b/src/3rdparty/tommyds/tommyhashdyn.c @@ -31,20 +31,18 @@ /******************************************************************************/ /* hashdyn */ -TOMMY_API //!! -void tommy_hashdyn_init(tommy_hashdyn* hashdyn) +TOMMY_API void tommy_hashdyn_init(tommy_hashdyn* hashdyn) { /* fixed initial size */ hashdyn->bucket_bit = TOMMY_HASHDYN_BIT; - hashdyn->bucket_max = 1 << hashdyn->bucket_bit; + hashdyn->bucket_max = (tommy_size_t)1 << hashdyn->bucket_bit; hashdyn->bucket_mask = hashdyn->bucket_max - 1; hashdyn->bucket = tommy_cast(tommy_hashdyn_node**, tommy_calloc(hashdyn->bucket_max, sizeof(tommy_hashdyn_node*))); hashdyn->count = 0; } -TOMMY_API //!! -void tommy_hashdyn_done(tommy_hashdyn* hashdyn) +TOMMY_API void tommy_hashdyn_done(tommy_hashdyn* hashdyn) { tommy_free(hashdyn->bucket); } @@ -52,18 +50,18 @@ void tommy_hashdyn_done(tommy_hashdyn* hashdyn) /** * Resize the bucket vector. */ -static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucket_bit) +static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_uint_t new_bucket_bit) { - tommy_count_t bucket_bit; - tommy_count_t bucket_max; - tommy_count_t new_bucket_max; - tommy_count_t new_bucket_mask; + tommy_size_t bucket_bit; + tommy_size_t bucket_max; + tommy_size_t new_bucket_max; + tommy_size_t new_bucket_mask; tommy_hashdyn_node** new_bucket; bucket_bit = hashdyn->bucket_bit; bucket_max = hashdyn->bucket_max; - new_bucket_max = 1 << new_bucket_bit; + new_bucket_max = (tommy_size_t)1 << new_bucket_bit; new_bucket_mask = new_bucket_max - 1; /* allocate the new vector using malloc() and not calloc() */ @@ -72,7 +70,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucke /* reinsert all the elements */ if (new_bucket_bit > bucket_bit) { - tommy_count_t i; + tommy_size_t i; /* grow */ for (i = 0; i < bucket_max; ++i) { @@ -86,7 +84,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucke j = hashdyn->bucket[i]; while (j) { tommy_hashdyn_node* j_next = j->next; - tommy_count_t pos = j->key & new_bucket_mask; + tommy_size_t pos = j->index & new_bucket_mask; if (new_bucket[pos]) tommy_list_insert_tail_not_empty(new_bucket[pos], j); else @@ -95,7 +93,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucke } } } else { - tommy_count_t i; + tommy_size_t i; /* shrink */ for (i = 0; i < new_bucket_max; ++i) { @@ -136,24 +134,22 @@ tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn) tommy_hashdyn_resize(hashdyn, hashdyn->bucket_bit - 1); } -TOMMY_API //!! -void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash) +TOMMY_API void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash) { - tommy_count_t pos = hash & hashdyn->bucket_mask; + tommy_size_t pos = hash & hashdyn->bucket_mask; tommy_list_insert_tail(&hashdyn->bucket[pos], node, data); - node->key = hash; + node->index = hash; ++hashdyn->count; hashdyn_grow_step(hashdyn); } -TOMMY_API //!! -void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node) +TOMMY_API void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node) { - tommy_count_t pos = node->key & hashdyn->bucket_mask; + tommy_size_t pos = node->index & hashdyn->bucket_mask; tommy_list_remove_existing(&hashdyn->bucket[pos], node); @@ -164,15 +160,14 @@ void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* return node->data; } -TOMMY_API //!! -void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash) +TOMMY_API void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash) { - tommy_count_t pos = hash & hashdyn->bucket_mask; + tommy_size_t pos = hash & hashdyn->bucket_mask; tommy_hashdyn_node* node = hashdyn->bucket[pos]; while (node) { /* we first check if the hash matches, as in the same bucket we may have multiples hash values */ - if (node->key == hash && cmp(cmp_arg, node->data) == 0) { + if (node->index == hash && cmp(cmp_arg, node->data) == 0) { tommy_list_remove_existing(&hashdyn->bucket[pos], node); --hashdyn->count; @@ -187,12 +182,11 @@ void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const return 0; } -TOMMY_API //!! -void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func) +TOMMY_API void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func) { - tommy_count_t bucket_max = hashdyn->bucket_max; + tommy_size_t bucket_max = hashdyn->bucket_max; tommy_hashdyn_node** bucket = hashdyn->bucket; - tommy_count_t pos; + tommy_size_t pos; for (pos = 0; pos < bucket_max; ++pos) { tommy_hashdyn_node* node = bucket[pos]; @@ -205,12 +199,11 @@ void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func) } } -TOMMY_API //!! -void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* func, void* arg) +TOMMY_API void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* func, void* arg) { - tommy_count_t bucket_max = hashdyn->bucket_max; + tommy_size_t bucket_max = hashdyn->bucket_max; tommy_hashdyn_node** bucket = hashdyn->bucket; - tommy_count_t pos; + tommy_size_t pos; for (pos = 0; pos < bucket_max; ++pos) { tommy_hashdyn_node* node = bucket[pos]; @@ -223,44 +216,7 @@ void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* f } } -TOMMY_API //!! -void tommy_hashdyn_foreach_node(tommy_hashdyn* hashdyn, tommy_foreach_node_func* func) -{ - tommy_count_t bucket_max = hashdyn->bucket_max; - tommy_hashdyn_node** bucket = hashdyn->bucket; - tommy_count_t pos; - - for (pos = 0; pos < bucket_max; ++pos) { - tommy_hashdyn_node* node = bucket[pos]; - - while (node) { - tommy_hashdyn_node* next = node->next; - func(node); - node = next; - } - } -} - -TOMMY_API //!! -void tommy_hashdyn_foreach_node_arg(tommy_hashdyn* hashdyn, tommy_foreach_node_arg_func* func, void* arg) -{ - tommy_count_t bucket_max = hashdyn->bucket_max; - tommy_hashdyn_node** bucket = hashdyn->bucket; - tommy_count_t pos; - - for (pos = 0; pos < bucket_max; ++pos) { - tommy_hashdyn_node* node = bucket[pos]; - - while (node) { - tommy_hashdyn_node* next = node->next; - func(arg, node); - node = next; - } - } -} - -TOMMY_API //!! -tommy_size_t tommy_hashdyn_memory_usage(tommy_hashdyn* hashdyn) +TOMMY_API 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); diff --git a/src/3rdparty/tommyds/tommyhashdyn.h b/src/3rdparty/tommyds/tommyhashdyn.h index 8786653d..caf8045f 100644 --- a/src/3rdparty/tommyds/tommyhashdyn.h +++ b/src/3rdparty/tommyds/tommyhashdyn.h @@ -160,17 +160,16 @@ typedef tommy_node tommy_hashdyn_node; */ typedef struct tommy_hashdyn_struct { tommy_hashdyn_node** bucket; /**< Hash buckets. One list for each hash modulus. */ + tommy_size_t bucket_max; /**< Number of buckets. */ + tommy_size_t bucket_mask; /**< Bit mask to access the buckets. */ + tommy_size_t count; /**< Number of elements. */ tommy_uint_t bucket_bit; /**< Bits used in the bit mask. */ - tommy_count_t bucket_max; /**< Number of buckets. */ - tommy_count_t bucket_mask; /**< Bit mask to access the buckets. */ - tommy_count_t count; /**< Number of elements. */ } tommy_hashdyn; /** * Initializes the hashtable. */ -TOMMY_API //!! -void tommy_hashdyn_init(tommy_hashdyn* hashdyn); +TOMMY_API void tommy_hashdyn_init(tommy_hashdyn* hashdyn); /** * Deinitializes the hashtable. @@ -178,14 +177,12 @@ void tommy_hashdyn_init(tommy_hashdyn* hashdyn); * You can call this function with elements still contained, * but such elements are not going to be freed by this call. */ -TOMMY_API //!! -void tommy_hashdyn_done(tommy_hashdyn* hashdyn); +TOMMY_API void tommy_hashdyn_done(tommy_hashdyn* hashdyn); /** * Inserts an element in the hashtable. */ -TOMMY_API //!! -void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash); +TOMMY_API void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash); /** * Searches and removes an element from the hashtable. @@ -198,8 +195,7 @@ void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void * \param hash Hash of the element to find and remove. * \return The removed element, or 0 if not found. */ -TOMMY_API //!! -void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash); +TOMMY_API void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash); /** * Gets the bucket of the specified hash. @@ -230,7 +226,7 @@ tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_fun 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) + if (i->index == hash && cmp(cmp_arg, i->data) == 0) return i->data; i = i->next; } @@ -242,8 +238,7 @@ tommy_inline void* tommy_hashdyn_search(tommy_hashdyn* hashdyn, tommy_search_fun * You must already have the address of the element to remove. * \return The tommy_node::data field of the node removed. */ -TOMMY_API //!! -void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node); +TOMMY_API void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node); /** * Calls the specified function for each element in the hashtable. @@ -276,31 +271,17 @@ void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* * tommy_hashdyn_done(&hashdyn); * \endcode */ -TOMMY_API //!! -void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func); +TOMMY_API void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func); /** * Calls the specified function with an argument for each element in the hashtable. */ -TOMMY_API //!! -void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* func, void* arg); - -/** - * Calls the specified function for each node in the hashtable. - */ -TOMMY_API //!! -void tommy_hashdyn_foreach_node(tommy_hashdyn* hashdyn, tommy_foreach_node_func* func); - -/** - * Calls the specified function with an argument for each node in the hashtable. - */ -TOMMY_API //!! -void tommy_hashdyn_foreach_node_arg(tommy_hashdyn* hashdyn, tommy_foreach_node_arg_func* func, void* arg); +TOMMY_API void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* func, void* arg); /** * Gets the number of elements. */ -tommy_inline tommy_count_t tommy_hashdyn_count(tommy_hashdyn* hashdyn) +tommy_inline tommy_size_t tommy_hashdyn_count(tommy_hashdyn* hashdyn) { return hashdyn->count; } @@ -309,8 +290,7 @@ tommy_inline tommy_count_t tommy_hashdyn_count(tommy_hashdyn* hashdyn) * Gets the size of allocated memory. * It includes the size of the ::tommy_hashdyn_node of the stored elements. */ -TOMMY_API //!! -tommy_size_t tommy_hashdyn_memory_usage(tommy_hashdyn* hashdyn); +TOMMY_API tommy_size_t tommy_hashdyn_memory_usage(tommy_hashdyn* hashdyn); #endif diff --git a/src/3rdparty/tommyds/tommylist.c b/src/3rdparty/tommyds/tommylist.c index 99a7c49e..d758c615 100644 --- a/src/3rdparty/tommyds/tommylist.c +++ b/src/3rdparty/tommyds/tommylist.c @@ -38,8 +38,7 @@ tommy_inline void tommy_list_set(tommy_list* list, tommy_node* head, tommy_node* *list = head; } -TOMMY_API //!! -void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp) +TOMMY_API void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp) { tommy_chain chain; tommy_node* head; diff --git a/src/3rdparty/tommyds/tommylist.h b/src/3rdparty/tommyds/tommylist.h index c455ddae..32f1b192 100644 --- a/src/3rdparty/tommyds/tommylist.h +++ b/src/3rdparty/tommyds/tommylist.h @@ -226,24 +226,6 @@ tommy_inline void tommy_list_insert_tail(tommy_list* list, tommy_node* node, voi node->data = data; } -/** \internal - * Removes an element from the head of a not empty list. - * \param list The list. The list cannot be empty. - * \return The node removed. - */ -tommy_inline tommy_node* tommy_list_remove_head_not_empty(tommy_list* list) -{ - tommy_node* head = tommy_list_head(list); - - /* remove from the "circular" prev list */ - head->next->prev = head->prev; - - /* remove from the "0 terminated" next list */ - *list = head->next; /* the new head, in case 0 */ - - return head; -} - /** * Removes an element from the list. * You must already have the address of the element to remove. @@ -314,8 +296,7 @@ tommy_inline void tommy_list_concat(tommy_list* first, tommy_list* second) * \param cmp Compare function called with two elements. * The function should return <0 if the first element is less than the second, ==0 if equal, and >0 if greather. */ -TOMMY_API //!! -void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp); +TOMMY_API void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp); /** * Checks if empty. @@ -330,9 +311,9 @@ tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list) * Gets the number of elements. * \note This operation is O(n). */ -tommy_inline tommy_count_t tommy_list_count(tommy_list* list) +tommy_inline tommy_size_t tommy_list_count(tommy_list* list) { - tommy_count_t count = 0; + tommy_size_t count = 0; tommy_node* i = tommy_list_head(list); while (i) { diff --git a/src/3rdparty/tommyds/tommytypes.h b/src/3rdparty/tommyds/tommytypes.h index eb8621ad..0cb797a1 100644 --- a/src/3rdparty/tommyds/tommytypes.h +++ b/src/3rdparty/tommyds/tommytypes.h @@ -24,7 +24,6 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ - /** \file * Generic types. */ @@ -37,17 +36,37 @@ #include -#if defined(_MSC_VER) +#ifdef _MSC_VER typedef unsigned tommy_uint32_t; /**< Generic uint32_t type. */ typedef unsigned _int64 tommy_uint64_t; /**< Generic uint64_t type. */ typedef size_t tommy_uintptr_t; /**< Generic uintptr_t type. */ +#ifdef _WIN64 +#define TOMMY_SIZE_BIT 64 +typedef unsigned _int64 tommy_size_t; /**< Generic size_t type. */ +typedef _int64 tommy_ssize_t; /**< Generic ssize_t type. */ +#else +#define TOMMY_SIZE_BIT 32 +typedef unsigned tommy_size_t; /**< Generic size_t type. */ +typedef int tommy_ssize_t; /**< Generic ssize_t type. */ +#endif #else #include typedef uint32_t tommy_uint32_t; /**< Generic uint32_t type. */ typedef uint64_t tommy_uint64_t; /**< Generic uint64_t type. */ typedef uintptr_t tommy_uintptr_t; /**< Generic uintptr_t type. */ +#if SIZE_MAX == UINT64_MAX +#define TOMMY_SIZE_BIT 64 +typedef uint64_t tommy_size_t; /**< Generic size_t type. */ +typedef int64_t tommy_ssize_t; /**< Generic ssize_t type. */ +#elif SIZE_MAX == UINT32_MAX +#define TOMMY_SIZE_BIT 32 +typedef uint32_t tommy_size_t; /**< Generic size_t type. */ +typedef int32_t tommy_ssize_t; /**< Generic ssize_t type. */ +#else +#error Unsupported SIZE_MAX #endif -typedef size_t tommy_size_t; /**< Generic size_t type. */ +#endif + typedef ptrdiff_t tommy_ptrdiff_t; /**< Generic ptrdiff_t type. */ typedef int tommy_bool_t; /**< Generic boolean type. */ @@ -59,13 +78,6 @@ typedef int tommy_bool_t; /**< Generic boolean type. */ */ typedef tommy_uint32_t tommy_uint_t; -/** - * Generic unsigned integer for counting objects. - * - * TommyDS doesn't support more than 2^32-1 objects. - */ -typedef tommy_uint32_t tommy_count_t; - /** \internal * Type cast required for the C++ compilation. * When compiling in C++ we cannot convert a void* pointer to another pointer. @@ -106,7 +118,8 @@ typedef tommy_uint32_t tommy_count_t; /* modificators */ /** \internal - * Definition of the TOMMY_API. //!! + * Definition of the TOMMY_API. + * Provide the ability to override linkage features of the interface. */ #if !defined(TOMMY_API) #define TOMMY_API @@ -159,17 +172,17 @@ typedef tommy_uint32_t tommy_count_t; #endif /******************************************************************************/ -/* key */ +/* key/hash */ /** - * Key type used in indexed data structures to store the key or the hash value. + * Type used in indexed data structures to store the key of a object. */ -typedef tommy_uint32_t tommy_key_t; +typedef tommy_size_t tommy_key_t; /** - * Bits into the ::tommy_key_t type. + * Type used in hashtables to store the hash of a object. */ -#define TOMMY_KEY_BIT (sizeof(tommy_key_t) * 8) +typedef tommy_size_t tommy_hash_t; /******************************************************************************/ /* node */ @@ -207,11 +220,12 @@ typedef struct tommy_node_struct { void* data; /** - * Key used to store the node. + * Index of the node. + * With tries this field is used to store the key. * With hashtables this field is used to store the hash value. * With lists this field is not used. */ - tommy_key_t key; + tommy_size_t index; } tommy_node; /******************************************************************************/ @@ -302,19 +316,6 @@ typedef void tommy_foreach_func(void* obj); */ typedef void tommy_foreach_arg_func(void* arg, void* obj); -/** //!! - * Foreach function. - * \param node Pointer to the node to iterate. - */ -typedef void tommy_foreach_node_func(void* node); - -/** //!! - * Foreach function with an argument. - * \param arg Pointer to a generic argument. - * \param node Pointer to the node to iterate. - */ -typedef void tommy_foreach_node_arg_func(void* arg, void* node); - /******************************************************************************/ /* bit hacks */ @@ -322,6 +323,10 @@ typedef void tommy_foreach_node_arg_func(void* arg, void* node); #include #pragma intrinsic(_BitScanReverse) #pragma intrinsic(_BitScanForward) +#if TOMMY_SIZE_BIT == 64 +#pragma intrinsic(_BitScanReverse64) +#pragma intrinsic(_BitScanForward64) +#endif #endif /** \internal @@ -383,6 +388,29 @@ tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value) #endif } +#if TOMMY_SIZE_BIT == 64 +/** + * Bit scan reverse or integer log2 for 64 bits. + */ +tommy_inline tommy_uint_t tommy_ilog2_u64(tommy_uint64_t value) +{ +#if defined(_MSC_VER) + unsigned long count; + _BitScanReverse64(&count, value); + return count; +#elif defined(__GNUC__) + return __builtin_clzll(value) ^ 63; +#else + uint32_t l = value & 0xFFFFFFFFU; + uint32_t h = value >> 32; + if (h) + return tommy_ilog2_u32(h) + 32; + else + return tommy_ilog2_u32(l); +#endif +} +#endif + /** * Bit scan forward or trailing zero count. * Return the bit index of the least significant 1 bit. @@ -411,6 +439,29 @@ tommy_inline tommy_uint_t tommy_ctz_u32(tommy_uint32_t value) #endif } +#if TOMMY_SIZE_BIT == 64 +/** + * Bit scan forward or trailing zero count for 64 bits. + */ +tommy_inline tommy_uint_t tommy_ctz_u64(tommy_uint64_t value) +{ +#if defined(_MSC_VER) + unsigned long count; + _BitScanForward64(&count, value); + return count; +#elif defined(__GNUC__) + return __builtin_ctzll(value); +#else + uint32_t l = value & 0xFFFFFFFFU; + uint32_t h = value >> 32; + if (l) + return tommy_ctz_u32(l); + else + return tommy_ctz_u32(h) + 32; +#endif +} +#endif + /** * Rounds up to the next power of 2. * For the value 0, the result is undefined. @@ -432,6 +483,23 @@ tommy_inline tommy_uint32_t tommy_roundup_pow2_u32(tommy_uint32_t value) return value; } +/** + * Rounds up to the next power of 2 for 64 bits. + */ +tommy_inline tommy_uint64_t tommy_roundup_pow2_u64(tommy_uint64_t value) +{ + --value; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value |= value >> 32; + ++value; + + return value; +} + /** * Check if the specified word has a byte at 0. * \return 0 or 1. @@ -440,5 +508,19 @@ tommy_inline int tommy_haszero_u32(tommy_uint32_t value) { return ((value - 0x01010101) & ~value & 0x80808080) != 0; } + +/* + * Bit depth mapping. + */ +#if TOMMY_SIZE_BIT == 64 +#define tommy_ilog2 tommy_ilog2_u64 +#define tommy_ctz tommy_ctz_u64 +#define tommy_roundup_pow2 tommy_roundup_pow2_u64 +#else +#define tommy_ilog2 tommy_ilog2_u32 +#define tommy_ctz tommy_ctz_u32 +#define tommy_roundup_pow2 tommy_roundup_pow2_u32 +#endif + #endif diff --git a/src/driver/fortpkt.c b/src/driver/fortpkt.c index 105935c2..d8bfb685 100644 --- a/src/driver/fortpkt.c +++ b/src/driver/fortpkt.c @@ -229,7 +229,7 @@ fort_defer_packet_get (PFORT_DEFER defer) pkt = defer->packet_free; defer->packet_free = pkt->next; } else { - const tommy_count_t size = tommy_arrayof_size(&defer->packets); + const tommy_size_t size = tommy_arrayof_size(&defer->packets); /* TODO: tommy_arrayof_grow(): check calloc()'s result for NULL */ tommy_arrayof_grow(&defer->packets, size + 1); diff --git a/src/driver/fortstat.c b/src/driver/fortstat.c index e55f1189..bf54dd1c 100644 --- a/src/driver/fortstat.c +++ b/src/driver/fortstat.c @@ -188,6 +188,13 @@ fort_stat_proc_free (PFORT_STAT stat, PFORT_STAT_PROC proc) stat->proc_free = proc; } +static void +fort_stat_proc_free_data (PFORT_STAT stat, void *data) +{ + PFORT_STAT_PROC proc = (PFORT_STAT_PROC) fort_tommyhashdyn_node(data); + fort_stat_proc_free(stat, proc); +} + static PFORT_STAT_PROC fort_stat_proc_add (PFORT_STAT stat, UINT32 process_id) { @@ -198,7 +205,7 @@ fort_stat_proc_add (PFORT_STAT stat, UINT32 process_id) proc = stat->proc_free; stat->proc_free = proc->next; } else { - const tommy_count_t size = tommy_arrayof_size(&stat->procs); + const tommy_size_t size = tommy_arrayof_size(&stat->procs); if (size + 1 >= FORT_PROC_COUNT_MAX) return NULL; @@ -261,12 +268,26 @@ fort_flow_context_remove (PFORT_STAT stat, PFORT_FLOW flow) FwpsFlowRemoveContext0(flow_id, FWPS_LAYER_OUTBOUND_TRANSPORT_V4, stat->out_transport4_id); } +static void +fort_flow_context_remove_data (PFORT_STAT stat, void *data) +{ + PFORT_FLOW flow = (PFORT_FLOW) fort_tommyhashdyn_node(data); + fort_flow_context_remove(stat, flow); +} + static void fort_flow_close (PFORT_FLOW flow) { flow->opt.proc_index = FORT_PROC_BAD_INDEX; } +static void +fort_flow_close_data (void *data) +{ + PFORT_FLOW flow = (PFORT_FLOW) fort_tommyhashdyn_node(data); + fort_flow_close(flow); +} + static PFORT_FLOW fort_flow_get (PFORT_STAT stat, UINT64 flow_id, tommy_key_t flow_hash) { @@ -317,7 +338,7 @@ fort_flow_add (PFORT_STAT stat, UINT64 flow_id, flow = stat->flow_free; stat->flow_free = flow->next; } else { - const tommy_count_t size = tommy_arrayof_size(&stat->flows); + const tommy_size_t size = tommy_arrayof_size(&stat->flows); /* TODO: tommy_arrayof_grow(): check calloc()'s result for NULL */ if (tommy_arrayof_grow(&stat->flows, size + 1), 0) @@ -370,7 +391,7 @@ fort_stat_close (PFORT_STAT stat) stat->closed = TRUE; - tommy_hashdyn_foreach_node_arg(&stat->flows_map, + tommy_hashdyn_foreach_arg(&stat->flows_map, fort_flow_context_remove, stat); tommy_arrayof_done(&stat->procs); @@ -387,8 +408,8 @@ fort_stat_clear (PFORT_STAT stat) { fort_stat_proc_active_clear(stat); - tommy_hashdyn_foreach_node_arg(&stat->procs_map, fort_stat_proc_free, stat); - tommy_hashdyn_foreach_node(&stat->flows_map, fort_flow_close); + tommy_hashdyn_foreach_arg(&stat->procs_map, fort_stat_proc_free, stat); + tommy_hashdyn_foreach(&stat->flows_map, fort_flow_close); RtlZeroMemory(stat->groups, sizeof(stat->groups)); } diff --git a/src/driver/forttds.c b/src/driver/forttds.c index 18f9dc73..b07d1717 100644 --- a/src/driver/forttds.c +++ b/src/driver/forttds.c @@ -53,3 +53,6 @@ fort_tommy_realloc (PVOID p, SIZE_T new_size) #include "..\3rdparty\tommyds\tommylist.c" #include "..\3rdparty\tommyds\tommyhash.c" #include "..\3rdparty\tommyds\tommyhashdyn.c" + +#define fort_tommyhashdyn_node(datap) \ + ((tommy_hashdyn_node *) ((char *) (datap) - offsetof(tommy_hashdyn_node, data)))