mirror of
https://github.com/tnodir/fort
synced 2024-11-15 10:35:10 +00:00
Update tommyds.
This commit is contained in:
parent
c6e38fb5f7
commit
bdbd11ec55
18
src/3rdparty/tommyds/tommyarrayof.c
vendored
18
src/3rdparty/tommyds/tommyarrayof.c
vendored
@ -30,15 +30,14 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* array */
|
/* array */
|
||||||
|
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_arrayof_init(tommy_arrayof* array, tommy_size_t element_size)
|
||||||
void tommy_arrayof_init(tommy_arrayof* array, tommy_size_t element_size)
|
|
||||||
{
|
{
|
||||||
tommy_uint_t i;
|
tommy_uint_t i;
|
||||||
|
|
||||||
/* fixed initial size */
|
/* fixed initial size */
|
||||||
array->element_size = element_size;
|
array->element_size = element_size;
|
||||||
array->bucket_bit = TOMMY_ARRAYOF_BIT;
|
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);
|
array->bucket[0] = tommy_calloc(array->bucket_max, array->element_size);
|
||||||
for (i = 1; i < TOMMY_ARRAYOF_BIT; ++i)
|
for (i = 1; i < TOMMY_ARRAYOF_BIT; ++i)
|
||||||
array->bucket[i] = array->bucket[0];
|
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;
|
array->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_arrayof_done(tommy_arrayof* array)
|
||||||
void tommy_arrayof_done(tommy_arrayof* array)
|
|
||||||
{
|
{
|
||||||
tommy_uint_t i;
|
tommy_uint_t i;
|
||||||
|
|
||||||
tommy_free(array->bucket[0]);
|
tommy_free(array->bucket[0]);
|
||||||
for (i = TOMMY_ARRAYOF_BIT; i < array->bucket_bit; ++i) {
|
for (i = TOMMY_ARRAYOF_BIT; i < array->bucket_bit; ++i) {
|
||||||
unsigned char* segment = tommy_cast(unsigned char*, array->bucket[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 //!!
|
TOMMY_API void tommy_arrayof_grow(tommy_arrayof* array, tommy_size_t count)
|
||||||
void tommy_arrayof_grow(tommy_arrayof* array, tommy_count_t count)
|
|
||||||
{
|
{
|
||||||
if (array->count >= count)
|
if (array->count >= count)
|
||||||
return;
|
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[array->bucket_bit] = segment - (tommy_ptrdiff_t)array->bucket_max * array->element_size;
|
||||||
|
|
||||||
++array->bucket_bit;
|
++array->bucket_bit;
|
||||||
array->bucket_max = 1 << array->bucket_bit;
|
array->bucket_max = (tommy_size_t)1 << array->bucket_bit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TOMMY_API //!!
|
TOMMY_API tommy_size_t tommy_arrayof_memory_usage(tommy_arrayof* array)
|
||||||
tommy_size_t tommy_arrayof_memory_usage(tommy_arrayof* array)
|
|
||||||
{
|
{
|
||||||
return array->bucket_max * (tommy_size_t)array->element_size;
|
return array->bucket_max * (tommy_size_t)array->element_size;
|
||||||
}
|
}
|
||||||
|
29
src/3rdparty/tommyds/tommyarrayof.h
vendored
29
src/3rdparty/tommyds/tommyarrayof.h
vendored
@ -54,49 +54,41 @@
|
|||||||
*/
|
*/
|
||||||
#define TOMMY_ARRAYOF_BIT 6
|
#define TOMMY_ARRAYOF_BIT 6
|
||||||
|
|
||||||
/** \internal
|
|
||||||
* Max number of elements as a power of 2.
|
|
||||||
*/
|
|
||||||
#define TOMMY_ARRAYOF_BIT_MAX 32
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array container type.
|
* Array container type.
|
||||||
* \note Don't use internal fields directly, but access the container only using functions.
|
* \note Don't use internal fields directly, but access the container only using functions.
|
||||||
*/
|
*/
|
||||||
typedef struct tommy_arrayof_struct {
|
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 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_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;
|
} tommy_arrayof;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the array.
|
* Initializes the array.
|
||||||
* \param element_size Size in byte of the element to store in the array.
|
* \param element_size Size in byte of the element to store in the array.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_arrayof_init(tommy_arrayof* array, tommy_size_t element_size);
|
||||||
void tommy_arrayof_init(tommy_arrayof* array, tommy_size_t element_size);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deinitializes the array.
|
* Deinitializes the array.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_arrayof_done(tommy_arrayof* array);
|
||||||
void tommy_arrayof_done(tommy_arrayof* array);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Grows the size up to the specified value.
|
* Grows the size up to the specified value.
|
||||||
* All the new elements in the array are initialized with the 0 value.
|
* All the new elements in the array are initialized with the 0 value.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_arrayof_grow(tommy_arrayof* array, tommy_size_t size);
|
||||||
void tommy_arrayof_grow(tommy_arrayof* array, tommy_count_t size);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a reference of the element at the specified position.
|
* Gets a reference of the element at the specified position.
|
||||||
* You must be sure that space for this position is already
|
* You must be sure that space for this position is already
|
||||||
* allocated calling tommy_arrayof_grow().
|
* 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;
|
unsigned char* ptr;
|
||||||
tommy_uint_t bsr;
|
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);
|
assert(pos < array->count);
|
||||||
|
|
||||||
/* get the highest bit set, in case of all 0, return 0 */
|
/* 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]);
|
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.
|
* 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;
|
return array->count;
|
||||||
}
|
}
|
||||||
@ -122,8 +114,7 @@ tommy_inline tommy_count_t tommy_arrayof_size(tommy_arrayof* array)
|
|||||||
/**
|
/**
|
||||||
* Gets the size of allocated memory.
|
* Gets the size of allocated memory.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API tommy_size_t tommy_arrayof_memory_usage(tommy_arrayof* array);
|
||||||
tommy_size_t tommy_arrayof_memory_usage(tommy_arrayof* array);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
23
src/3rdparty/tommyds/tommychain.h
vendored
23
src/3rdparty/tommyds/tommychain.h
vendored
@ -136,11 +136,6 @@ tommy_inline void tommy_chain_merge_degenerated(tommy_chain* first, tommy_chain*
|
|||||||
tommy_chain_merge(first, second, cmp);
|
tommy_chain_merge(first, second, cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Max number of elements as a power of 2.
|
|
||||||
*/
|
|
||||||
#define TOMMY_CHAIN_BIT_MAX 32
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sorts a chain.
|
* Sorts a chain.
|
||||||
* It's a stable merge sort using power of 2 buckets, with O(N*log(N)) complexity,
|
* 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.
|
* Bit buckets of chains.
|
||||||
* Each bucket contains 2^i nodes or it's empty.
|
* 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.
|
* 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.
|
* Value stored inside the bit bucket.
|
||||||
* It's used to know which bucket is empty of full.
|
* 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* node = chain->head;
|
||||||
tommy_node* tail = chain->tail;
|
tommy_node* tail = chain->tail;
|
||||||
tommy_count_t mask;
|
tommy_size_t mask;
|
||||||
tommy_count_t i;
|
tommy_size_t i;
|
||||||
|
|
||||||
counter = 0;
|
counter = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -179,9 +174,9 @@ tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func*
|
|||||||
tommy_chain* last;
|
tommy_chain* last;
|
||||||
|
|
||||||
/* carry bit to add */
|
/* carry bit to add */
|
||||||
last = &bit[TOMMY_CHAIN_BIT_MAX];
|
last = &bit[TOMMY_SIZE_BIT];
|
||||||
bit[TOMMY_CHAIN_BIT_MAX].head = node;
|
bit[TOMMY_SIZE_BIT].head = node;
|
||||||
bit[TOMMY_CHAIN_BIT_MAX].tail = node;
|
bit[TOMMY_SIZE_BIT].tail = node;
|
||||||
next = node->next;
|
next = node->next;
|
||||||
|
|
||||||
/* add the bit, propagating the carry */
|
/* 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 */
|
/* merge the buckets */
|
||||||
i = tommy_ctz_u32(counter);
|
i = tommy_ctz(counter);
|
||||||
mask = counter >> i;
|
mask = counter >> i;
|
||||||
while (mask != 1) {
|
while (mask != 1) {
|
||||||
mask >>= 1;
|
mask >>= 1;
|
||||||
|
46
src/3rdparty/tommyds/tommyhash.c
vendored
46
src/3rdparty/tommyds/tommyhash.c
vendored
@ -66,8 +66,7 @@ tommy_inline tommy_uint32_t tommy_le_uint32_read(const void* ptr)
|
|||||||
c ^= b; c -= tommy_rot(b, 24); \
|
c ^= b; c -= tommy_rot(b, 24); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
TOMMY_API //!!
|
TOMMY_API tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len)
|
||||||
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;
|
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);
|
b += tommy_le_uint32_read(key + 4);
|
||||||
a += tommy_le_uint32_read(key + 0);
|
a += tommy_le_uint32_read(key + 0);
|
||||||
break;
|
break;
|
||||||
case 11 : c += ((tommy_uint32_t)key[10]) << 16;
|
case 11 : c += ((tommy_uint32_t)key[10]) << 16; /* fallthrough */
|
||||||
case 10 : c += ((tommy_uint32_t)key[9]) << 8;
|
case 10 : c += ((tommy_uint32_t)key[9]) << 8; /* fallthrough */
|
||||||
case 9 : c += key[8];
|
case 9 : c += key[8]; /* fallthrough */
|
||||||
case 8 :
|
case 8 :
|
||||||
b += tommy_le_uint32_read(key + 4);
|
b += tommy_le_uint32_read(key + 4);
|
||||||
a += tommy_le_uint32_read(key + 0);
|
a += tommy_le_uint32_read(key + 0);
|
||||||
break;
|
break;
|
||||||
case 7 : b += ((tommy_uint32_t)key[6]) << 16;
|
case 7 : b += ((tommy_uint32_t)key[6]) << 16; /* fallthrough */
|
||||||
case 6 : b += ((tommy_uint32_t)key[5]) << 8;
|
case 6 : b += ((tommy_uint32_t)key[5]) << 8; /* fallthrough */
|
||||||
case 5 : b += key[4];
|
case 5 : b += key[4]; /* fallthrough */
|
||||||
case 4 :
|
case 4 :
|
||||||
a += tommy_le_uint32_read(key + 0);
|
a += tommy_le_uint32_read(key + 0);
|
||||||
break;
|
break;
|
||||||
case 3 : a += ((tommy_uint32_t)key[2]) << 16;
|
case 3 : a += ((tommy_uint32_t)key[2]) << 16; /* fallthrough */
|
||||||
case 2 : a += ((tommy_uint32_t)key[1]) << 8;
|
case 2 : a += ((tommy_uint32_t)key[1]) << 8; /* fallthrough */
|
||||||
case 1 : a += key[0];
|
case 1 : a += key[0]; /* fallthrough */
|
||||||
}
|
}
|
||||||
|
|
||||||
tommy_final(a, b, c);
|
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;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
TOMMY_API //!!
|
TOMMY_API tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tommy_size_t key_len)
|
||||||
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;
|
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);
|
b += tommy_le_uint32_read(key + 4);
|
||||||
a += tommy_le_uint32_read(key + 0);
|
a += tommy_le_uint32_read(key + 0);
|
||||||
break;
|
break;
|
||||||
case 11 : c += ((tommy_uint32_t)key[10]) << 16;
|
case 11 : c += ((tommy_uint32_t)key[10]) << 16; /* fallthrough */
|
||||||
case 10 : c += ((tommy_uint32_t)key[9]) << 8;
|
case 10 : c += ((tommy_uint32_t)key[9]) << 8; /* fallthrough */
|
||||||
case 9 : c += key[8];
|
case 9 : c += key[8]; /* fallthrough */
|
||||||
case 8 :
|
case 8 :
|
||||||
b += tommy_le_uint32_read(key + 4);
|
b += tommy_le_uint32_read(key + 4);
|
||||||
a += tommy_le_uint32_read(key + 0);
|
a += tommy_le_uint32_read(key + 0);
|
||||||
break;
|
break;
|
||||||
case 7 : b += ((tommy_uint32_t)key[6]) << 16;
|
case 7 : b += ((tommy_uint32_t)key[6]) << 16; /* fallthrough */
|
||||||
case 6 : b += ((tommy_uint32_t)key[5]) << 8;
|
case 6 : b += ((tommy_uint32_t)key[5]) << 8; /* fallthrough */
|
||||||
case 5 : b += key[4];
|
case 5 : b += key[4]; /* fallthrough */
|
||||||
case 4 :
|
case 4 :
|
||||||
a += tommy_le_uint32_read(key + 0);
|
a += tommy_le_uint32_read(key + 0);
|
||||||
break;
|
break;
|
||||||
case 3 : a += ((tommy_uint32_t)key[2]) << 16;
|
case 3 : a += ((tommy_uint32_t)key[2]) << 16; /* fallthrough */
|
||||||
case 2 : a += ((tommy_uint32_t)key[1]) << 8;
|
case 2 : a += ((tommy_uint32_t)key[1]) << 8; /* fallthrough */
|
||||||
case 1 : a += key[0];
|
case 1 : a += key[0]; /* fallthrough */
|
||||||
}
|
}
|
||||||
|
|
||||||
tommy_final(a, b, c);
|
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);
|
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);
|
const unsigned char* key = tommy_cast(const unsigned char*, void_key);
|
||||||
tommy_uint32_t a, b, c;
|
tommy_uint32_t a, b, c;
|
||||||
|
15
src/3rdparty/tommyds/tommyhash.h
vendored
15
src/3rdparty/tommyds/tommyhash.h
vendored
@ -37,11 +37,6 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* hash */
|
/* hash */
|
||||||
|
|
||||||
/**
|
|
||||||
* Hash type used in hashtables.
|
|
||||||
*/
|
|
||||||
typedef tommy_key_t tommy_hash_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash function with a 32 bits result.
|
* Hash function with a 32 bits result.
|
||||||
* Implementation of the Robert Jenkins "lookup3" hash 32 bits version,
|
* 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.
|
* This function is endianess independent.
|
||||||
* \return The hash value of 32 bits.
|
* \return The hash value of 32 bits.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API tommy_uint32_t tommy_hash_u32(tommy_uint32_t init_val, const void* void_key, tommy_size_t key_len);
|
||||||
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.
|
* 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.
|
* This function is endianess independent.
|
||||||
* \return The hash value of 64 bits.
|
* \return The hash value of 64 bits.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API tommy_uint64_t tommy_hash_u64(tommy_uint64_t init_val, const void* void_key, tommy_size_t key_len);
|
||||||
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.
|
* 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.
|
* This function is endianess independent.
|
||||||
* \return The hash value of 32 bits.
|
* \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.
|
* Integer reversible hash function for 32 bits.
|
||||||
|
98
src/3rdparty/tommyds/tommyhashdyn.c
vendored
98
src/3rdparty/tommyds/tommyhashdyn.c
vendored
@ -31,20 +31,18 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* hashdyn */
|
/* hashdyn */
|
||||||
|
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_hashdyn_init(tommy_hashdyn* hashdyn)
|
||||||
void tommy_hashdyn_init(tommy_hashdyn* hashdyn)
|
|
||||||
{
|
{
|
||||||
/* fixed initial size */
|
/* fixed initial size */
|
||||||
hashdyn->bucket_bit = TOMMY_HASHDYN_BIT;
|
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_mask = hashdyn->bucket_max - 1;
|
||||||
hashdyn->bucket = tommy_cast(tommy_hashdyn_node**, tommy_calloc(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;
|
hashdyn->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_hashdyn_done(tommy_hashdyn* hashdyn)
|
||||||
void tommy_hashdyn_done(tommy_hashdyn* hashdyn)
|
|
||||||
{
|
{
|
||||||
tommy_free(hashdyn->bucket);
|
tommy_free(hashdyn->bucket);
|
||||||
}
|
}
|
||||||
@ -52,18 +50,18 @@ void tommy_hashdyn_done(tommy_hashdyn* hashdyn)
|
|||||||
/**
|
/**
|
||||||
* Resize the bucket vector.
|
* 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_size_t bucket_bit;
|
||||||
tommy_count_t bucket_max;
|
tommy_size_t bucket_max;
|
||||||
tommy_count_t new_bucket_max;
|
tommy_size_t new_bucket_max;
|
||||||
tommy_count_t new_bucket_mask;
|
tommy_size_t new_bucket_mask;
|
||||||
tommy_hashdyn_node** new_bucket;
|
tommy_hashdyn_node** new_bucket;
|
||||||
|
|
||||||
bucket_bit = hashdyn->bucket_bit;
|
bucket_bit = hashdyn->bucket_bit;
|
||||||
bucket_max = hashdyn->bucket_max;
|
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;
|
new_bucket_mask = new_bucket_max - 1;
|
||||||
|
|
||||||
/* allocate the new vector using malloc() and not calloc() */
|
/* 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 */
|
/* reinsert all the elements */
|
||||||
if (new_bucket_bit > bucket_bit) {
|
if (new_bucket_bit > bucket_bit) {
|
||||||
tommy_count_t i;
|
tommy_size_t i;
|
||||||
|
|
||||||
/* grow */
|
/* grow */
|
||||||
for (i = 0; i < bucket_max; ++i) {
|
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];
|
j = hashdyn->bucket[i];
|
||||||
while (j) {
|
while (j) {
|
||||||
tommy_hashdyn_node* j_next = j->next;
|
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])
|
if (new_bucket[pos])
|
||||||
tommy_list_insert_tail_not_empty(new_bucket[pos], j);
|
tommy_list_insert_tail_not_empty(new_bucket[pos], j);
|
||||||
else
|
else
|
||||||
@ -95,7 +93,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucke
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tommy_count_t i;
|
tommy_size_t i;
|
||||||
|
|
||||||
/* shrink */
|
/* shrink */
|
||||||
for (i = 0; i < new_bucket_max; ++i) {
|
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_hashdyn_resize(hashdyn, hashdyn->bucket_bit - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash)
|
||||||
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);
|
tommy_list_insert_tail(&hashdyn->bucket[pos], node, data);
|
||||||
|
|
||||||
node->key = hash;
|
node->index = hash;
|
||||||
|
|
||||||
++hashdyn->count;
|
++hashdyn->count;
|
||||||
|
|
||||||
hashdyn_grow_step(hashdyn);
|
hashdyn_grow_step(hashdyn);
|
||||||
}
|
}
|
||||||
|
|
||||||
TOMMY_API //!!
|
TOMMY_API void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node)
|
||||||
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);
|
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;
|
return node->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
TOMMY_API //!!
|
TOMMY_API void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
|
||||||
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];
|
tommy_hashdyn_node* node = hashdyn->bucket[pos];
|
||||||
|
|
||||||
while (node) {
|
while (node) {
|
||||||
/* we first check if the hash matches, as in the same bucket we may have multiples hash values */
|
/* 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);
|
tommy_list_remove_existing(&hashdyn->bucket[pos], node);
|
||||||
|
|
||||||
--hashdyn->count;
|
--hashdyn->count;
|
||||||
@ -187,12 +182,11 @@ void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func)
|
||||||
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_hashdyn_node** bucket = hashdyn->bucket;
|
||||||
tommy_count_t pos;
|
tommy_size_t pos;
|
||||||
|
|
||||||
for (pos = 0; pos < bucket_max; ++pos) {
|
for (pos = 0; pos < bucket_max; ++pos) {
|
||||||
tommy_hashdyn_node* node = bucket[pos];
|
tommy_hashdyn_node* node = bucket[pos];
|
||||||
@ -205,12 +199,11 @@ void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* func, void* arg)
|
||||||
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_hashdyn_node** bucket = hashdyn->bucket;
|
||||||
tommy_count_t pos;
|
tommy_size_t pos;
|
||||||
|
|
||||||
for (pos = 0; pos < bucket_max; ++pos) {
|
for (pos = 0; pos < bucket_max; ++pos) {
|
||||||
tommy_hashdyn_node* node = bucket[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 //!!
|
TOMMY_API tommy_size_t tommy_hashdyn_memory_usage(tommy_hashdyn* hashdyn)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
return hashdyn->bucket_max * (tommy_size_t)sizeof(hashdyn->bucket[0])
|
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);
|
||||||
|
46
src/3rdparty/tommyds/tommyhashdyn.h
vendored
46
src/3rdparty/tommyds/tommyhashdyn.h
vendored
@ -160,17 +160,16 @@ typedef tommy_node tommy_hashdyn_node;
|
|||||||
*/
|
*/
|
||||||
typedef struct tommy_hashdyn_struct {
|
typedef struct tommy_hashdyn_struct {
|
||||||
tommy_hashdyn_node** bucket; /**< Hash buckets. One list for each hash modulus. */
|
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_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;
|
} tommy_hashdyn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the hashtable.
|
* Initializes the hashtable.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_hashdyn_init(tommy_hashdyn* hashdyn);
|
||||||
void tommy_hashdyn_init(tommy_hashdyn* hashdyn);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deinitializes the hashtable.
|
* Deinitializes the hashtable.
|
||||||
@ -178,14 +177,12 @@ void tommy_hashdyn_init(tommy_hashdyn* hashdyn);
|
|||||||
* You can call this function with elements still contained,
|
* You can call this function with elements still contained,
|
||||||
* but such elements are not going to be freed by this call.
|
* but such elements are not going to be freed by this call.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_hashdyn_done(tommy_hashdyn* hashdyn);
|
||||||
void tommy_hashdyn_done(tommy_hashdyn* hashdyn);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts an element in the hashtable.
|
* Inserts an element in the hashtable.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash);
|
||||||
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.
|
* 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.
|
* \param hash Hash of the element to find and remove.
|
||||||
* \return The removed element, or 0 if not found.
|
* \return The removed element, or 0 if not found.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash);
|
||||||
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.
|
* 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) {
|
while (i) {
|
||||||
/* we first check if the hash matches, as in the same bucket we may have multiples hash values */
|
/* 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;
|
return i->data;
|
||||||
i = i->next;
|
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.
|
* You must already have the address of the element to remove.
|
||||||
* \return The tommy_node::data field of the node removed.
|
* \return The tommy_node::data field of the node removed.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node);
|
||||||
void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls the specified function for each element in the hashtable.
|
* 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);
|
* tommy_hashdyn_done(&hashdyn);
|
||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func);
|
||||||
void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls the specified function with an argument for each element in the hashtable.
|
* Calls the specified function with an argument for each element in the hashtable.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* func, void* arg);
|
||||||
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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the number of elements.
|
* 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;
|
return hashdyn->count;
|
||||||
}
|
}
|
||||||
@ -309,8 +290,7 @@ tommy_inline tommy_count_t tommy_hashdyn_count(tommy_hashdyn* hashdyn)
|
|||||||
* Gets the size of allocated memory.
|
* Gets the size of allocated memory.
|
||||||
* It includes the size of the ::tommy_hashdyn_node of the stored elements.
|
* It includes the size of the ::tommy_hashdyn_node of the stored elements.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API tommy_size_t tommy_hashdyn_memory_usage(tommy_hashdyn* hashdyn);
|
||||||
tommy_size_t tommy_hashdyn_memory_usage(tommy_hashdyn* hashdyn);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
3
src/3rdparty/tommyds/tommylist.c
vendored
3
src/3rdparty/tommyds/tommylist.c
vendored
@ -38,8 +38,7 @@ tommy_inline void tommy_list_set(tommy_list* list, tommy_node* head, tommy_node*
|
|||||||
*list = head;
|
*list = head;
|
||||||
}
|
}
|
||||||
|
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp)
|
||||||
void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp)
|
|
||||||
{
|
{
|
||||||
tommy_chain chain;
|
tommy_chain chain;
|
||||||
tommy_node* head;
|
tommy_node* head;
|
||||||
|
25
src/3rdparty/tommyds/tommylist.h
vendored
25
src/3rdparty/tommyds/tommylist.h
vendored
@ -226,24 +226,6 @@ tommy_inline void tommy_list_insert_tail(tommy_list* list, tommy_node* node, voi
|
|||||||
node->data = data;
|
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.
|
* Removes an element from the list.
|
||||||
* You must already have the address of the element to remove.
|
* 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.
|
* \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.
|
* The function should return <0 if the first element is less than the second, ==0 if equal, and >0 if greather.
|
||||||
*/
|
*/
|
||||||
TOMMY_API //!!
|
TOMMY_API void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp);
|
||||||
void tommy_list_sort(tommy_list* list, tommy_compare_func* cmp);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if empty.
|
* Checks if empty.
|
||||||
@ -330,9 +311,9 @@ tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list)
|
|||||||
* Gets the number of elements.
|
* Gets the number of elements.
|
||||||
* \note This operation is O(n).
|
* \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);
|
tommy_node* i = tommy_list_head(list);
|
||||||
|
|
||||||
while (i) {
|
while (i) {
|
||||||
|
144
src/3rdparty/tommyds/tommytypes.h
vendored
144
src/3rdparty/tommyds/tommytypes.h
vendored
@ -24,7 +24,6 @@
|
|||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \file
|
/** \file
|
||||||
* Generic types.
|
* Generic types.
|
||||||
*/
|
*/
|
||||||
@ -37,17 +36,37 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#ifdef _MSC_VER
|
||||||
typedef unsigned tommy_uint32_t; /**< Generic uint32_t type. */
|
typedef unsigned tommy_uint32_t; /**< Generic uint32_t type. */
|
||||||
typedef unsigned _int64 tommy_uint64_t; /**< Generic uint64_t type. */
|
typedef unsigned _int64 tommy_uint64_t; /**< Generic uint64_t type. */
|
||||||
typedef size_t tommy_uintptr_t; /**< Generic uintptr_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
|
#else
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
typedef uint32_t tommy_uint32_t; /**< Generic uint32_t type. */
|
typedef uint32_t tommy_uint32_t; /**< Generic uint32_t type. */
|
||||||
typedef uint64_t tommy_uint64_t; /**< Generic uint64_t type. */
|
typedef uint64_t tommy_uint64_t; /**< Generic uint64_t type. */
|
||||||
typedef uintptr_t tommy_uintptr_t; /**< Generic uintptr_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
|
#endif
|
||||||
typedef size_t tommy_size_t; /**< Generic size_t type. */
|
#endif
|
||||||
|
|
||||||
typedef ptrdiff_t tommy_ptrdiff_t; /**< Generic ptrdiff_t type. */
|
typedef ptrdiff_t tommy_ptrdiff_t; /**< Generic ptrdiff_t type. */
|
||||||
typedef int tommy_bool_t; /**< Generic boolean 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;
|
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
|
/** \internal
|
||||||
* Type cast required for the C++ compilation.
|
* Type cast required for the C++ compilation.
|
||||||
* When compiling in C++ we cannot convert a void* pointer to another pointer.
|
* 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 */
|
/* modificators */
|
||||||
|
|
||||||
/** \internal
|
/** \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)
|
#if !defined(TOMMY_API)
|
||||||
#define TOMMY_API
|
#define TOMMY_API
|
||||||
@ -159,17 +172,17 @@ typedef tommy_uint32_t tommy_count_t;
|
|||||||
#endif
|
#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 */
|
/* node */
|
||||||
@ -207,11 +220,12 @@ typedef struct tommy_node_struct {
|
|||||||
void* data;
|
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 hashtables this field is used to store the hash value.
|
||||||
* With lists this field is not used.
|
* With lists this field is not used.
|
||||||
*/
|
*/
|
||||||
tommy_key_t key;
|
tommy_size_t index;
|
||||||
} tommy_node;
|
} tommy_node;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -302,19 +316,6 @@ typedef void tommy_foreach_func(void* obj);
|
|||||||
*/
|
*/
|
||||||
typedef void tommy_foreach_arg_func(void* arg, 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 */
|
/* bit hacks */
|
||||||
|
|
||||||
@ -322,6 +323,10 @@ typedef void tommy_foreach_node_arg_func(void* arg, void* node);
|
|||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#pragma intrinsic(_BitScanReverse)
|
#pragma intrinsic(_BitScanReverse)
|
||||||
#pragma intrinsic(_BitScanForward)
|
#pragma intrinsic(_BitScanForward)
|
||||||
|
#if TOMMY_SIZE_BIT == 64
|
||||||
|
#pragma intrinsic(_BitScanReverse64)
|
||||||
|
#pragma intrinsic(_BitScanForward64)
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
@ -383,6 +388,29 @@ tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value)
|
|||||||
#endif
|
#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.
|
* Bit scan forward or trailing zero count.
|
||||||
* Return the bit index of the least significant 1 bit.
|
* 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
|
#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.
|
* Rounds up to the next power of 2.
|
||||||
* For the value 0, the result is undefined.
|
* 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;
|
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.
|
* Check if the specified word has a byte at 0.
|
||||||
* \return 0 or 1.
|
* \return 0 or 1.
|
||||||
@ -440,5 +508,19 @@ tommy_inline int tommy_haszero_u32(tommy_uint32_t value)
|
|||||||
{
|
{
|
||||||
return ((value - 0x01010101) & ~value & 0x80808080) != 0;
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ fort_defer_packet_get (PFORT_DEFER defer)
|
|||||||
pkt = defer->packet_free;
|
pkt = defer->packet_free;
|
||||||
defer->packet_free = pkt->next;
|
defer->packet_free = pkt->next;
|
||||||
} else {
|
} 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 */
|
/* TODO: tommy_arrayof_grow(): check calloc()'s result for NULL */
|
||||||
tommy_arrayof_grow(&defer->packets, size + 1);
|
tommy_arrayof_grow(&defer->packets, size + 1);
|
||||||
|
@ -188,6 +188,13 @@ fort_stat_proc_free (PFORT_STAT stat, PFORT_STAT_PROC proc)
|
|||||||
stat->proc_free = 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
|
static PFORT_STAT_PROC
|
||||||
fort_stat_proc_add (PFORT_STAT stat, UINT32 process_id)
|
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;
|
proc = stat->proc_free;
|
||||||
stat->proc_free = proc->next;
|
stat->proc_free = proc->next;
|
||||||
} else {
|
} 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)
|
if (size + 1 >= FORT_PROC_COUNT_MAX)
|
||||||
return NULL;
|
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);
|
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
|
static void
|
||||||
fort_flow_close (PFORT_FLOW flow)
|
fort_flow_close (PFORT_FLOW flow)
|
||||||
{
|
{
|
||||||
flow->opt.proc_index = FORT_PROC_BAD_INDEX;
|
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
|
static PFORT_FLOW
|
||||||
fort_flow_get (PFORT_STAT stat, UINT64 flow_id, tommy_key_t flow_hash)
|
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;
|
flow = stat->flow_free;
|
||||||
stat->flow_free = flow->next;
|
stat->flow_free = flow->next;
|
||||||
} else {
|
} 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 */
|
/* TODO: tommy_arrayof_grow(): check calloc()'s result for NULL */
|
||||||
if (tommy_arrayof_grow(&stat->flows, size + 1), 0)
|
if (tommy_arrayof_grow(&stat->flows, size + 1), 0)
|
||||||
@ -370,7 +391,7 @@ fort_stat_close (PFORT_STAT stat)
|
|||||||
|
|
||||||
stat->closed = TRUE;
|
stat->closed = TRUE;
|
||||||
|
|
||||||
tommy_hashdyn_foreach_node_arg(&stat->flows_map,
|
tommy_hashdyn_foreach_arg(&stat->flows_map,
|
||||||
fort_flow_context_remove, stat);
|
fort_flow_context_remove, stat);
|
||||||
|
|
||||||
tommy_arrayof_done(&stat->procs);
|
tommy_arrayof_done(&stat->procs);
|
||||||
@ -387,8 +408,8 @@ fort_stat_clear (PFORT_STAT stat)
|
|||||||
{
|
{
|
||||||
fort_stat_proc_active_clear(stat);
|
fort_stat_proc_active_clear(stat);
|
||||||
|
|
||||||
tommy_hashdyn_foreach_node_arg(&stat->procs_map, fort_stat_proc_free, stat);
|
tommy_hashdyn_foreach_arg(&stat->procs_map, fort_stat_proc_free, stat);
|
||||||
tommy_hashdyn_foreach_node(&stat->flows_map, fort_flow_close);
|
tommy_hashdyn_foreach(&stat->flows_map, fort_flow_close);
|
||||||
|
|
||||||
RtlZeroMemory(stat->groups, sizeof(stat->groups));
|
RtlZeroMemory(stat->groups, sizeof(stat->groups));
|
||||||
}
|
}
|
||||||
|
@ -53,3 +53,6 @@ fort_tommy_realloc (PVOID p, SIZE_T new_size)
|
|||||||
#include "..\3rdparty\tommyds\tommylist.c"
|
#include "..\3rdparty\tommyds\tommylist.c"
|
||||||
#include "..\3rdparty\tommyds\tommyhash.c"
|
#include "..\3rdparty\tommyds\tommyhash.c"
|
||||||
#include "..\3rdparty\tommyds\tommyhashdyn.c"
|
#include "..\3rdparty\tommyds\tommyhashdyn.c"
|
||||||
|
|
||||||
|
#define fort_tommyhashdyn_node(datap) \
|
||||||
|
((tommy_hashdyn_node *) ((char *) (datap) - offsetof(tommy_hashdyn_node, data)))
|
||||||
|
Loading…
Reference in New Issue
Block a user