diff --git a/tommyds/tommyarray.c b/tommyds/tommyarray.c index 944a672d..a8d946bb 100644 --- a/tommyds/tommyarray.c +++ b/tommyds/tommyarray.c @@ -27,14 +27,12 @@ #include "tommyarray.h" -#include /* for ptrdiff_t */ - /******************************************************************************/ /* array */ void tommy_array_init(tommy_array* array) { - unsigned i; + tommy_uint_t i; /* fixed initial size */ array->bucket_bit = TOMMY_ARRAY_BIT; @@ -43,28 +41,27 @@ void tommy_array_init(tommy_array* array) for (i = 1; i < TOMMY_ARRAY_BIT; ++i) array->bucket[i] = array->bucket[0]; - array->bucket_mac = TOMMY_ARRAY_BIT; - array->size = 0; + array->count = 0; } void tommy_array_done(tommy_array* array) { - unsigned i; + tommy_uint_t i; tommy_free(array->bucket[0]); - for (i = TOMMY_ARRAY_BIT; i < array->bucket_mac; ++i) { + for (i = TOMMY_ARRAY_BIT; i < array->bucket_bit; ++i) { void** segment = array->bucket[i]; - tommy_free(&segment[1 << i]); + tommy_free(&segment[((tommy_ptrdiff_t)1) << i]); } } -void tommy_array_grow(tommy_array* array, unsigned size) +void tommy_array_grow(tommy_array* array, tommy_count_t count) { - if (array->size >= size) + if (array->count >= count) return; - array->size = size; + array->count = count; - while (size > array->bucket_max) { + while (count > array->bucket_max) { void** segment; /* allocate one more segment */ @@ -72,9 +69,8 @@ void tommy_array_grow(tommy_array* array, unsigned size) /* store it adjusting the offset */ /* cast to ptrdiff_t to ensure to get a negative value */ - array->bucket[array->bucket_mac] = &segment[-(ptrdiff_t)array->bucket_max]; + array->bucket[array->bucket_bit] = &segment[-(tommy_ptrdiff_t)array->bucket_max]; - ++array->bucket_mac; ++array->bucket_bit; array->bucket_max = 1 << array->bucket_bit; } diff --git a/tommyds/tommyarray.h b/tommyds/tommyarray.h index 86fd3a12..c04193f8 100644 --- a/tommyds/tommyarray.h +++ b/tommyds/tommyarray.h @@ -28,11 +28,11 @@ /** \file * Dynamic array based on segments of exponential growing size. * - * This array is able to grow dynamically upon request. + * This array is able to grow dynamically upon request, without any reallocation. * - * The resize involve an allocation of a new array segment, without reallocating - * the already allocated memory, and then not increasing the heap fragmentation. - * This means that the address of the allocated segments never change. + * The grow operation involves an allocation of a new array segment, without reallocating + * the already used memory, and then not increasing the heap fragmentation. + * This also implies that the address of the stored elements never change. * * Allocated segments grow in size exponentially. */ @@ -59,14 +59,14 @@ #define TOMMY_ARRAY_BIT_MAX 32 /** - * Array. + * Array container type. + * \note Don't use internal fields directly, but access the container only using functions. */ typedef struct tommy_array_struct { void** bucket[TOMMY_ARRAY_BIT_MAX]; /**< Dynamic array of buckets. */ - unsigned bucket_bit; /**< Bits used in the bit mask. */ - unsigned bucket_max; /**< Number of buckets. */ - unsigned bucket_mac; /**< Number of vectors allocated. */ - unsigned size; /**< Currently allocated and initialized size. */ + 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_array; /** @@ -80,21 +80,21 @@ void tommy_array_init(tommy_array* array); void tommy_array_done(tommy_array* array); /** - * Grow 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. */ -void tommy_array_grow(tommy_array* array, unsigned size); +void tommy_array_grow(tommy_array* array, tommy_count_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_array_grow(). */ -tommy_inline void** tommy_array_ref(tommy_array* array, unsigned pos) +tommy_inline void** tommy_array_ref(tommy_array* array, tommy_count_t pos) { - unsigned bsr; + tommy_uint_t bsr; - assert(pos < array->size); + assert(pos < array->count); /* get the highest bit set, in case of all 0, return 0 */ bsr = tommy_ilog2_u32(pos | 1); @@ -107,7 +107,7 @@ tommy_inline void** tommy_array_ref(tommy_array* array, unsigned pos) * You must be sure that space for this position is already * allocated calling tommy_array_grow(). */ -tommy_inline void tommy_array_set(tommy_array* array, unsigned pos, void* element) +tommy_inline void tommy_array_set(tommy_array* array, tommy_count_t pos, void* element) { *tommy_array_ref(array, pos) = element; } @@ -117,7 +117,7 @@ tommy_inline void tommy_array_set(tommy_array* array, unsigned pos, void* elemen * You must be sure that space for this position is already * allocated calling tommy_array_grow(). */ -tommy_inline void* tommy_array_get(tommy_array* array, unsigned pos) +tommy_inline void* tommy_array_get(tommy_array* array, tommy_count_t pos) { return *tommy_array_ref(array, pos); } @@ -127,7 +127,7 @@ tommy_inline void* tommy_array_get(tommy_array* array, unsigned pos) */ tommy_inline void tommy_array_insert(tommy_array* array, void* element) { - unsigned pos = array->size; + tommy_count_t pos = array->count; tommy_array_grow(array, pos + 1); @@ -137,9 +137,9 @@ tommy_inline void tommy_array_insert(tommy_array* array, void* element) /** * Gets the initialized size of the array. */ -tommy_inline unsigned tommy_array_size(tommy_array* array) +tommy_inline tommy_count_t tommy_array_size(tommy_array* array) { - return array->size; + return array->count; } /** diff --git a/tommyds/tommyarrayblk.c b/tommyds/tommyarrayblk.c index 82d29751..69b2d2ac 100644 --- a/tommyds/tommyarrayblk.c +++ b/tommyds/tommyarrayblk.c @@ -34,12 +34,12 @@ void tommy_arrayblk_init(tommy_arrayblk* array) { tommy_array_init(&array->block); - array->size = 0; + array->count = 0; } void tommy_arrayblk_done(tommy_arrayblk* array) { - unsigned i; + tommy_count_t i; for (i = 0; i < tommy_array_size(&array->block); ++i) tommy_free(tommy_array_get(&array->block, i)); @@ -47,16 +47,16 @@ void tommy_arrayblk_done(tommy_arrayblk* array) tommy_array_done(&array->block); } -void tommy_arrayblk_grow(tommy_arrayblk* array, unsigned size) +void tommy_arrayblk_grow(tommy_arrayblk* array, tommy_count_t count) { - unsigned block_max; - unsigned block_mac; + tommy_count_t block_max; + tommy_count_t block_mac; - if (array->size >= size) + if (array->count >= count) return; - array->size = size; + array->count = count; - block_max = (size + TOMMY_ARRAYBLK_SIZE - 1) / TOMMY_ARRAYBLK_SIZE; + block_max = (count + TOMMY_ARRAYBLK_SIZE - 1) / TOMMY_ARRAYBLK_SIZE; block_mac = tommy_array_size(&array->block); if (block_mac < block_max) { diff --git a/tommyds/tommyarrayblk.h b/tommyds/tommyarrayblk.h index beba5b32..20d05258 100644 --- a/tommyds/tommyarrayblk.h +++ b/tommyds/tommyarrayblk.h @@ -26,16 +26,16 @@ */ /** \file - * Dynamic array based on blocks of fixed sizes. + * Dynamic array based on blocks of fixed size. * - * This array is able to grow dynamically upon request. + * This array is able to grow dynamically upon request, without any reallocation. * - * The resize involve an allocation of a new array block, without reallocating - * the already allocated memory, and then not increasing the heap fragmentation, + * The grow operation involves an allocation of a new array block, without reallocating + * the already used memory, and then not increasing the heap fragmentation, * and minimize the space occupation. - * This means that the address of the allocated blocks never change. + * This also implies that the address of the stored elements never change. * - * Allocated blocks are always of the same fixed size of 64 Ki pointers. + * Allocated blocks are always of the same fixed size of 4 Ki pointers. */ #ifndef __TOMMYARRAYBLK_H @@ -55,11 +55,12 @@ #define TOMMY_ARRAYBLK_SIZE (4 * 1024) /** - * Array. + * Array container type. + * \note Don't use internal fields directly, but access the container only using functions. */ typedef struct tommy_arrayblk_struct { tommy_array block; /**< Array of blocks. */ - unsigned size; /**< Currently allocated and initialized size. */ + tommy_count_t count; /**< Number of initialized elements in the array. */ } tommy_arrayblk; /** @@ -73,21 +74,21 @@ void tommy_arrayblk_init(tommy_arrayblk* array); void tommy_arrayblk_done(tommy_arrayblk* array); /** - * Grow 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. */ -void tommy_arrayblk_grow(tommy_arrayblk* array, unsigned size); +void tommy_arrayblk_grow(tommy_arrayblk* array, tommy_count_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_arrayblk_grow(). */ -tommy_inline void** tommy_arrayblk_ref(tommy_arrayblk* array, unsigned pos) +tommy_inline void** tommy_arrayblk_ref(tommy_arrayblk* array, tommy_count_t pos) { void** ptr; - assert(pos < array->size); + assert(pos < array->count); ptr = tommy_cast(void**, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLK_SIZE)); @@ -99,7 +100,7 @@ tommy_inline void** tommy_arrayblk_ref(tommy_arrayblk* array, unsigned pos) * You must be sure that space for this position is already * allocated calling tommy_arrayblk_grow(). */ -tommy_inline void tommy_arrayblk_set(tommy_arrayblk* array, unsigned pos, void* element) +tommy_inline void tommy_arrayblk_set(tommy_arrayblk* array, tommy_count_t pos, void* element) { *tommy_arrayblk_ref(array, pos) = element; } @@ -109,7 +110,7 @@ tommy_inline void tommy_arrayblk_set(tommy_arrayblk* array, unsigned pos, void* * You must be sure that space for this position is already * allocated calling tommy_arrayblk_grow(). */ -tommy_inline void* tommy_arrayblk_get(tommy_arrayblk* array, unsigned pos) +tommy_inline void* tommy_arrayblk_get(tommy_arrayblk* array, tommy_count_t pos) { return *tommy_arrayblk_ref(array, pos); } @@ -119,7 +120,7 @@ tommy_inline void* tommy_arrayblk_get(tommy_arrayblk* array, unsigned pos) */ tommy_inline void tommy_arrayblk_insert(tommy_arrayblk* array, void* element) { - unsigned pos = array->size; + tommy_count_t pos = array->count; tommy_arrayblk_grow(array, pos + 1); @@ -129,9 +130,9 @@ tommy_inline void tommy_arrayblk_insert(tommy_arrayblk* array, void* element) /** * Gets the initialized size of the array. */ -tommy_inline unsigned tommy_arrayblk_size(tommy_arrayblk* array) +tommy_inline tommy_count_t tommy_arrayblk_size(tommy_arrayblk* array) { - return array->size; + return array->count; } /** diff --git a/tommyds/tommyarrayblkof.c b/tommyds/tommyarrayblkof.c index 1a7e0ba6..13f43ff2 100644 --- a/tommyds/tommyarrayblkof.c +++ b/tommyds/tommyarrayblkof.c @@ -30,16 +30,17 @@ /******************************************************************************/ /* array */ -void tommy_arrayblkof_init(tommy_arrayblkof* array, unsigned element_size) +void tommy_arrayblkof_init(tommy_arrayblkof* array, tommy_size_t element_size) { tommy_array_init(&array->block); + array->element_size = element_size; - array->size = 0; + array->count = 0; } void tommy_arrayblkof_done(tommy_arrayblkof* array) { - unsigned i; + tommy_count_t i; for (i = 0; i < tommy_array_size(&array->block); ++i) tommy_free(tommy_array_get(&array->block, i)); @@ -47,16 +48,16 @@ void tommy_arrayblkof_done(tommy_arrayblkof* array) tommy_array_done(&array->block); } -void tommy_arrayblkof_grow(tommy_arrayblkof* array, unsigned size) +void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_t count) { - unsigned block_max; - unsigned block_mac; + tommy_count_t block_max; + tommy_count_t block_mac; - if (array->size >= size) + if (array->count >= count) return; - array->size = size; + array->count = count; - block_max = (size + TOMMY_ARRAYBLK_SIZE - 1) / TOMMY_ARRAYBLK_SIZE; + block_max = (count + TOMMY_ARRAYBLK_SIZE - 1) / TOMMY_ARRAYBLK_SIZE; block_mac = tommy_array_size(&array->block); if (block_mac < block_max) { diff --git a/tommyds/tommyarrayblkof.h b/tommyds/tommyarrayblkof.h index 922604c1..f7ce93ab 100644 --- a/tommyds/tommyarrayblkof.h +++ b/tommyds/tommyarrayblkof.h @@ -26,15 +26,16 @@ */ /** \file - * Dynamic array based on blocks of fixed sizes. + * Dynamic array based on blocks of fixed size. * - * This array is able to grow dynamically upon request. + * This array is able to grow dynamically upon request, without any reallocation. * * This is very similar at ::tommy_arrayblk, but it allows to store elements of any * size and not just pointers. * * Note that in this case tommy_arrayblkof_ref() returns a pointer at the element, - * and it should be used for both get() and set() operation. + * that should be used for getting and setting elements in the array, + * as generic getter and setter are not available. */ #ifndef __TOMMYARRAYBLKOF_H @@ -54,19 +55,20 @@ #define TOMMY_ARRAYBLKOF_SIZE (4 * 1024) /** - * Array. + * Array container type. + * \note Don't use internal fields directly, but access the container only using functions. */ typedef struct tommy_arrayblkof_struct { tommy_array block; /**< Array of blocks. */ - unsigned element_size; /**< Size of the stored element in bytes. */ - unsigned size; /**< Currently allocated and initialized size. */ + tommy_size_t element_size; /**< Size of the stored element in bytes. */ + tommy_count_t count; /**< Number of initialized elements in the array. */ } tommy_arrayblkof; /** * Initializes the array. * \param element_size Size in byte of the element to store in the array. */ -void tommy_arrayblkof_init(tommy_arrayblkof* array, unsigned element_size); +void tommy_arrayblkof_init(tommy_arrayblkof* array, tommy_size_t element_size); /** * Deinitializes the array. @@ -74,21 +76,21 @@ void tommy_arrayblkof_init(tommy_arrayblkof* array, unsigned element_size); void tommy_arrayblkof_done(tommy_arrayblkof* array); /** - * Grow 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. */ -void tommy_arrayblkof_grow(tommy_arrayblkof* array, unsigned size); +void tommy_arrayblkof_grow(tommy_arrayblkof* array, tommy_count_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_arrayblkof_grow(). */ -tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, unsigned pos) +tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, tommy_count_t pos) { unsigned char* base; - assert(pos < array->size); + assert(pos < array->count); base = tommy_cast(unsigned char*, tommy_array_get(&array->block, pos / TOMMY_ARRAYBLKOF_SIZE)); @@ -98,9 +100,9 @@ tommy_inline void* tommy_arrayblkof_ref(tommy_arrayblkof* array, unsigned pos) /** * Gets the initialized size of the array. */ -tommy_inline unsigned tommy_arrayblkof_size(tommy_arrayblkof* array) +tommy_inline tommy_count_t tommy_arrayblkof_size(tommy_arrayblkof* array) { - return array->size; + return array->count; } /** diff --git a/tommyds/tommychain.h b/tommyds/tommychain.h index 1a2dc796..a9c05f85 100644 --- a/tommyds/tommychain.h +++ b/tommyds/tommychain.h @@ -167,11 +167,11 @@ tommy_inline void tommy_chain_mergesort(tommy_chain* chain, tommy_compare_func* * Value stored inside the bit bucket. * It's used to know which bucket is empty of full. */ - unsigned counter; + tommy_count_t counter; tommy_node* node = chain->head; tommy_node* tail = chain->tail; - unsigned mask; - unsigned i; + tommy_count_t mask; + tommy_count_t i; counter = 0; while (1) { diff --git a/tommyds/tommyhashdyn.c b/tommyds/tommyhashdyn.c index 5a3fc114..4da3fe63 100644 --- a/tommyds/tommyhashdyn.c +++ b/tommyds/tommyhashdyn.c @@ -50,12 +50,12 @@ void tommy_hashdyn_done(tommy_hashdyn* hashdyn) /** * Resize the bucket vector. */ -static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, unsigned new_bucket_bit) +static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, tommy_count_t new_bucket_bit) { - unsigned bucket_bit; - unsigned bucket_max; - unsigned new_bucket_max; - unsigned new_bucket_mask; + tommy_count_t bucket_bit; + tommy_count_t bucket_max; + tommy_count_t new_bucket_max; + tommy_count_t new_bucket_mask; tommy_hashdyn_node** new_bucket; bucket_bit = hashdyn->bucket_bit; @@ -70,7 +70,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, unsigned new_bucket_bit /* reinsert all the elements */ if (new_bucket_bit > bucket_bit) { - unsigned i; + tommy_count_t i; /* grow */ for (i = 0; i < bucket_max; ++i) { @@ -84,7 +84,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, unsigned new_bucket_bit j = hashdyn->bucket[i]; while (j) { tommy_hashdyn_node* j_next = j->next; - unsigned index = j->key & new_bucket_mask; + tommy_count_t index = j->key & new_bucket_mask; if (new_bucket[index]) tommy_list_insert_tail_not_empty(new_bucket[index], j); else @@ -93,7 +93,7 @@ static void tommy_hashdyn_resize(tommy_hashdyn* hashdyn, unsigned new_bucket_bit } } } else { - unsigned i; + tommy_count_t i; /* shrink */ for (i = 0; i < new_bucket_max; ++i) { @@ -138,7 +138,7 @@ tommy_inline void hashdyn_shrink_step(tommy_hashdyn* hashdyn) void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void* data, tommy_hash_t hash) { - unsigned pos = hash & hashdyn->bucket_mask; + tommy_count_t pos = hash & hashdyn->bucket_mask; tommy_list_insert_tail(&hashdyn->bucket[pos], node, data); @@ -151,7 +151,7 @@ void tommy_hashdyn_insert(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node, void void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node) { - unsigned pos = node->key & hashdyn->bucket_mask; + tommy_count_t pos = node->key & hashdyn->bucket_mask; tommy_list_remove_existing(&hashdyn->bucket[pos], node); @@ -164,7 +164,7 @@ void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash) { - unsigned pos = hash % hashdyn->bucket_max; + tommy_count_t pos = hash % hashdyn->bucket_max; tommy_hashdyn_node* node = hashdyn->bucket[pos]; while (node) { @@ -186,9 +186,9 @@ void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_search_func* cmp, const void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func) { - unsigned bucket_max = hashdyn->bucket_max; + tommy_count_t bucket_max = hashdyn->bucket_max; tommy_hashdyn_node** bucket = hashdyn->bucket; - unsigned pos; + tommy_count_t pos; for (pos = 0; pos < bucket_max; ++pos) { tommy_hashdyn_node* node = bucket[pos]; @@ -203,9 +203,9 @@ void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func) void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* func, void* arg) { - unsigned bucket_max = hashdyn->bucket_max; + tommy_count_t bucket_max = hashdyn->bucket_max; tommy_hashdyn_node** bucket = hashdyn->bucket; - unsigned pos; + tommy_count_t pos; for (pos = 0; pos < bucket_max; ++pos) { tommy_hashdyn_node* node = bucket[pos]; diff --git a/tommyds/tommyhashdyn.h b/tommyds/tommyhashdyn.h index b706df92..11f24473 100644 --- a/tommyds/tommyhashdyn.h +++ b/tommyds/tommyhashdyn.h @@ -114,7 +114,7 @@ * and remove. * * \code - * struct object* obj = tommy_trie_remove(&hashtable, compare, &value_to_remove, tommy_inthash_u32(value_to_remove)); + * struct object* obj = tommy_hashdyn_remove(&hashdyn, compare, &value_to_remove, tommy_inthash_u32(value_to_remove)); * if (obj) { * free(obj); // frees the object allocated memory * } @@ -127,9 +127,11 @@ * tommy_hashdyn_done(&hashdyn); * \endcode * - * Note that you cannot iterates over all the elements in the hashtable using the - * hashtable itself. You have to insert all the elements also in a ::tommy_list, - * and use the list to iterate. See the \ref multiindex example for more detail. + * If you need to iterate over all the elements in the hashtable, you can use + * tommy_hashdyn_foreach() or tommy_hashdyn_foreach_arg(). + * If you need a more precise control with a real iteration, you have to insert + * all the elements also in a ::tommy_list, and use the list to iterate. + * See the \ref multiindex example for more detail. */ #ifndef __TOMMYHASHDYN_H @@ -147,20 +149,21 @@ #define TOMMY_HASHDYN_BIT 4 /** - * Dynamic hashtable node. + * Hashtable node. * This is the node that you have to include inside your objects. */ typedef tommy_node tommy_hashdyn_node; /** - * Dynamic chained hashtable. + * Hashtable container type. + * \note Don't use internal fields directly, but access the container only using functions. */ typedef struct tommy_hashdyn_struct { tommy_hashdyn_node** bucket; /**< Hash buckets. One list for each hash modulus. */ - unsigned bucket_bit; /**< Bits used in the bit mask. */ - unsigned bucket_max; /**< Number of buckets. */ - unsigned bucket_mask; /**< Bit mask to access the buckets. */ - unsigned 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; /** @@ -240,6 +243,33 @@ void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* /** * Calls the specified function for each element in the hashtable. + * + * You can use this function to deallocate all the elements inserted. + * + * \code + * tommy_hashdyn hashdyn; + * + * // initializes the hashtable + * tommy_hashdyn_init(&hashdyn); + * + * ... + * + * // creates an object + * struct object* obj = malloc(sizeof(struct object)); + * + * ... + * + * // insert it in the hashtable + * tommy_hashdyn_insert(&hashdyn, &obj->node, obj, tommy_inthash_u32(obj->value)); + * + * ... + * + * // deallocates all the objects iterating the hashtable + * tommy_hashdyn_foreach(&hashdyn, free); + * + * // deallocates the hashtable + * tommy_hashdyn_done(&hashdyn); + * \endcode */ void tommy_hashdyn_foreach(tommy_hashdyn* hashdyn, tommy_foreach_func* func); @@ -251,7 +281,7 @@ void tommy_hashdyn_foreach_arg(tommy_hashdyn* hashdyn, tommy_foreach_arg_func* f /** * Gets the number of elements. */ -tommy_inline unsigned tommy_hashdyn_count(tommy_hashdyn* hashdyn) +tommy_inline tommy_count_t tommy_hashdyn_count(tommy_hashdyn* hashdyn) { return hashdyn->count; } diff --git a/tommyds/tommylist.h b/tommyds/tommylist.h index 1725923b..98e43035 100644 --- a/tommyds/tommylist.h +++ b/tommyds/tommylist.h @@ -108,7 +108,7 @@ /* list */ /** - * Double linked list for collisions into hashtables. + * Double linked list type. */ typedef tommy_node* tommy_list; @@ -309,6 +309,31 @@ tommy_inline tommy_bool_t tommy_list_empty(tommy_list* list) /** * Calls the specified function for each element in the list. + * + * You can use this function to deallocate all the elements + * inserted in a list. + * + * \code + * tommy_list list; + * + * // initializes the list + * tommy_list_init(&list); + * + * ... + * + * // creates an object + * struct object* obj = malloc(sizeof(struct object)); + * + * ... + * + * // insert it in the list + * tommy_list_insert_tail(&list, &obj->node, obj); + * + * ... + * + * // deallocates all the objects iterating the list + * tommy_list_foreach(&list, free); + * \endcode */ tommy_inline void tommy_list_foreach(tommy_list* list, tommy_foreach_func* func) { diff --git a/tommyds/tommytypes.h b/tommyds/tommytypes.h index fc58095c..5c81f3ca 100644 --- a/tommyds/tommytypes.h +++ b/tommyds/tommytypes.h @@ -35,21 +35,37 @@ /******************************************************************************/ /* types */ -#if defined(_MSC_VER) #include + +#if defined(_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_size_t; /**< Generic size_t type. */ typedef size_t tommy_uintptr_t; /**< Generic uintptr_t type. */ #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_size_t; /**< Generic size_t type. */ typedef uintptr_t tommy_uintptr_t; /**< Generic uintptr_t type. */ #endif +typedef size_t tommy_size_t; /**< Generic size_t type. */ +typedef ptrdiff_t tommy_ptrdiff_t; /**< Generic ptrdiff_t type. */ typedef int tommy_bool_t; /**< Generic boolean type. */ +/** + * Generic unsigned integer type. + * + * It has no specific size, as is used to store only small values. + * To make the code more efficient, a full 32 bit integer is used. + */ +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. @@ -307,7 +323,7 @@ typedef void tommy_foreach_arg_func(void* arg, void* obj); * \param value Value to scan. 0 is not allowed. * \return The index of the most significan bit set. */ -tommy_inline unsigned tommy_ilog2_u32(tommy_uint32_t value) +tommy_inline tommy_uint_t tommy_ilog2_u32(tommy_uint32_t value) { #if defined(_MSC_VER) unsigned long count; @@ -326,7 +342,7 @@ tommy_inline unsigned tommy_ilog2_u32(tommy_uint32_t value) #else /* Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup */ /* from http://graphics.stanford.edu/~seander/bithacks.html */ - static const int TOMMY_DE_BRUIJN_INDEX_ILOG2[32] = { + static unsigned char TOMMY_DE_BRUIJN_INDEX_ILOG2[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 }; @@ -349,7 +365,7 @@ tommy_inline unsigned tommy_ilog2_u32(tommy_uint32_t value) * \param value Value to scan. 0 is not allowed. * \return The index of the least significant bit set. */ -tommy_inline unsigned tommy_ctz_u32(tommy_uint32_t value) +tommy_inline tommy_uint_t tommy_ctz_u32(tommy_uint32_t value) { #if defined(_MSC_VER) unsigned long count; @@ -360,7 +376,7 @@ tommy_inline unsigned tommy_ctz_u32(tommy_uint32_t value) #else /* Count the consecutive zero bits (trailing) on the right with multiply and lookup */ /* from http://graphics.stanford.edu/~seander/bithacks.html */ - static const tommy_uint32_t TOMMY_DE_BRUIJN_INDEX_CTZ[32] = { + static const unsigned char TOMMY_DE_BRUIJN_INDEX_CTZ[32] = { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 };