rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

commit 5f5bc133f3d6f2cd3bcab9b859bfc3e2459afdf0
parent c0a3c9c6f1e67d3f77da298454e52919767ff776
Author: vaplv <vaplv@free.fr>
Date:   Sun,  6 Apr 2014 15:43:16 +0200

Change the hash table API

Diffstat:
Mcmake/CMakeLists.txt | 2++
Asrc/dynamic_array_u64.h | 11+++++++++++
Msrc/hash_table.h | 77++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/test_hash_table.c | 38++++++++++++++++++--------------------
4 files changed, 75 insertions(+), 53 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -61,6 +61,8 @@ set(RSYS_FILES_INC_COMMON binary_heap.h clock_time.h dynamic_array.h + dynamic_array_char.h + dynamic_array_u64.h free_list.h hash.h hash_table.h diff --git a/src/dynamic_array_u64.h b/src/dynamic_array_u64.h @@ -0,0 +1,11 @@ +#ifndef DYNAMIC_ARRRAY_U64_H +#define DYNAMIC_ARRRAY_U64_H + +#include "dynamic_array.h" + +#define DARRAY_NAME u64 +#define DARRAY_DATA uint64_t +#include "dynamic_array.h" + +#endif /* DYNAMIC_ARRRAY_U64_H */ + diff --git a/src/hash_table.h b/src/hash_table.h @@ -18,6 +18,9 @@ * - HTABLE_NAME: prefix of the hash table functions & types; * - HTABLE_DATA: type of the data registered into the hash table; * - HTABLE_KEY: type of the key indexing the hash table data; + * - HTABLE_KEY_FUNCTOR_HASH: hash functor on HTABLE_KEY. If not defined, use + * the default function that hashes the bytes of HTABLE_KEY; + * - HTABLE_KEY_FUNCTOR_EQ: equality functor on 2 HTABLE_KEY; * - HTABLE_<DATA|KEY>_FUNCTOR_INIT: init functor on HTABLE_<DATA|KEY>. If not * defined, no specific treatment is performed on the created data; * - HTABLE_<DATA|KEY>_FUNCTOR_COPY: copy functor on HTABLE_<DATA|KEY>. If not @@ -129,6 +132,31 @@ HTABLE_FUNC__(key_functor_cp_and_release__)(HTABLE_KEY* dst, HTABLE_KEY* src) HTABLE_FUNC__(key_functor_cp_and_release__) #endif +#ifndef HTABLE_KEY_FUNCTOR_HASH +static INLINE size_t +HTABLE_FUNC__(key_functor_hash__)(HTABLE_KEY const* key) +{ +#ifdef ARCH_32BITS + return (size_t)hash_fnv32(key, sizeof(HTABLE_KEY)); +#elif defined(ARCH_64BITS) + return (size_t)hash_fnv64(key, sizeof(HTABLE_KEY)); +#else + #error "Unexpected architecture" +#endif +} +#define HTABLE_KEY_FUNCTOR_HASH HTABLE_FUNC__(key_functor_hash__) +#endif + +#ifndef HTABLE_KEY_FUNCTOR_EQ +static INLINE char +HTABLE_FUNC__(key_functor_eq__)(HTABLE_KEY const* a, HTABLE_KEY const* b) +{ + ASSERT(a && b); + return *a == *b; +} +#define HTABLE_KEY_FUNCTOR_EQ HTABLE_FUNC__(key_functor_eq__) +#endif + /******************************************************************************* * Pair functor ******************************************************************************/ @@ -187,10 +215,6 @@ struct HTABLE__ { struct HTABLE_DATA__ table; struct darray_char table_slot_is_used; size_t table_size_in_use; - - size_t (*hash)(HTABLE_KEY const*); - char (*eq_key)(HTABLE_KEY const*, HTABLE_KEY const*); - struct mem_allocator* allocator; }; @@ -217,46 +241,30 @@ HTABLE_FUNC__(find_slot__)(const struct HTABLE__* htbl, HTABLE_KEY const* key) pairs = HTABLE_DATA_FUNC__(cdata_get)(&htbl->table); used_pairs = darray_char_cdata_get(&htbl->table_slot_is_used); - /* slot = hash % size */ - slot = htbl->hash(key) & (HTABLE_DATA_FUNC__(size_get)(&htbl->table) - 1); + slot = /* slot = hash % size */ + HTABLE_KEY_FUNCTOR_HASH(key) + & (HTABLE_DATA_FUNC__(size_get)(&htbl->table) - 1); - while(used_pairs[slot] && !htbl->eq_key(key, &pairs[slot].key)) { + while(used_pairs[slot] && !HTABLE_KEY_FUNCTOR_EQ(key, &pairs[slot].key)) { /* slot = (slot + 1) % size */ slot = (slot + 1) & (HTABLE_DATA_FUNC__(size_get)(&htbl->table) - 1); } return slot; } -static INLINE size_t -HTABLE_FUNC__(hash__)(HTABLE_KEY const* key) -{ -#ifdef ARCH_32BITS - return (size_t)hash_fnv32(key, sizeof(HTABLE_KEY)); -#elif defined(ARCH_64BITS) - return (size_t)hash_fnv64(key, sizeof(HTABLE_KEY)); -#else - #error "Unexpected architecture" -#endif -} - /******************************************************************************* * Hash table API ******************************************************************************/ static INLINE void HTABLE_FUNC__(init) - (struct HTABLE__* htbl, - /* May be NULL <=> use default allocator */ + ( /* May be NULL <=> use default allocator */ struct mem_allocator* allocator, - /* May be NULL <=> use default hash function */ - size_t (*hash)(HTABLE_KEY const*), - char (*eq_key)(HTABLE_KEY const*, HTABLE_KEY const*)) + struct HTABLE__* htbl) { - ASSERT( htbl && eq_key ); + ASSERT(htbl); HTABLE_DATA_FUNC__(init)(allocator, &htbl->table); darray_char_init(allocator, &htbl->table_slot_is_used); htbl->table_size_in_use = 0; - htbl->hash = hash ? hash : HTABLE_FUNC__(hash__); - htbl->eq_key = eq_key; htbl->allocator = allocator ? allocator : &mem_default_allocator; } @@ -336,10 +344,11 @@ HTABLE_FUNC__(reserve)(struct HTABLE__* htbl, const size_t size_submitted) if(!old_used_pairs[islot]) continue; - islot_new = htbl->hash(&old_pairs[islot].key) & (size - 1); + islot_new = HTABLE_KEY_FUNCTOR_HASH(&old_pairs[islot].key) & (size - 1); while(new_used_pairs[islot_new]) { - ASSERT /* There is at most 1 entry for a given key */ - (!htbl->eq_key(&new_pairs[islot_new].key, &old_pairs[islot].key )); + /* There is at most 1 entry for a given key */ + ASSERT(!HTABLE_KEY_FUNCTOR_EQ + (&new_pairs[islot_new].key, &old_pairs[islot].key )); islot_new = (islot_new + 1) & (size - 1); /* (islot_new + 1) % size */ } @@ -429,7 +438,7 @@ HTABLE_FUNC__(erase)(struct HTABLE__* htbl, HTABLE_KEY const* key) for(j = (i + 1) & (tbl_size - 1); /* <=> j = (i+1) % size */ used_pairs[j]; j = (j + 1) & (tbl_size - 1) ) { /* <=> j = (j+1) % size */ - const size_t k = htbl->hash(&pairs[j].key) & (tbl_size- 1); + const size_t k = HTABLE_KEY_FUNCTOR_HASH(&pairs[j].key) & (tbl_size- 1); if(i <= j ? (i < k && k <= j) : (i < k || k <= j)) continue; @@ -550,16 +559,18 @@ HTABLE_FUNC__(iterator_data_get)(const struct HTABLE_ITERATOR__* it) return &HTABLE_DATA_FUNC__(data_get)(&it->hash_table->table)[it->slot].data; } -#undef HTABLE_DATA +#undef HTABLE_KEY #undef HTABLE_KEY_FUNCTOR_COPY #undef HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE +#undef HTABLE_KEY_FUNCTOR_EQ +#undef HTABLE_KEY_FUNCTOR_HASH #undef HTABLE_KEY_FUNCTOR_INIT #undef HTABLE_KEY_FUNCTOR_RELEASE +#undef HTABLE_DATA #undef HTABLE_DATA_FUNCTOR_COPY #undef HTABLE_DATA_FUNCTOR_COPY_AND_RELEASE #undef HTABLE_DATA_FUNCTOR_INIT #undef HTABLE_DATA_FUNCTOR_RELEASE -#undef HTABLE_KEY #undef HTABLE_NAME #undef HTABLE__ #undef HTABLE_PAIR__ diff --git a/src/test_hash_table.c b/src/test_hash_table.c @@ -9,12 +9,6 @@ #define HTABLE_NAME int_float #include "hash_table.h" -static INLINE char -eq_int(const int* a, const int* b) -{ - return *a == *b; -} - static void test_htbl_int_float(void) { @@ -23,12 +17,12 @@ test_htbl_int_float(void) int i; const int n = 678; - htable_int_float_init(&htbl, NULL, NULL, eq_int); + htable_int_float_init(NULL, &htbl); htable_int_float_release(&htbl); mem_init_proxy_allocator(&allocator_proxy, &mem_default_allocator); - htable_int_float_init(&htbl, &allocator_proxy, NULL, eq_int); + htable_int_float_init(&allocator_proxy, &htbl); htable_int_float_reserve(&htbl, 30); FOR_EACH(i, 0, n) { @@ -66,15 +60,6 @@ test_htbl_int_float(void) mem_shutdown_proxy_allocator(&allocator_proxy); } -#define HTABLE_KEY struct str -#define HTABLE_DATA int -#define HTABLE_NAME str_int -#define HTABLE_KEY_FUNCTOR_INIT str_init -#define HTABLE_KEY_FUNCTOR_RELEASE str_release -#define HTABLE_KEY_FUNCTOR_COPY str_copy -#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release -#include "hash_table.h" - static INLINE char eq_str(const struct str* a, const struct str* b) { @@ -87,6 +72,17 @@ hash_str(const struct str* a) return hash_fnv32(str_cget(a), str_len(a)); } +#define HTABLE_KEY struct str +#define HTABLE_DATA int +#define HTABLE_NAME str_int +#define HTABLE_KEY_FUNCTOR_INIT str_init +#define HTABLE_KEY_FUNCTOR_RELEASE str_release +#define HTABLE_KEY_FUNCTOR_COPY str_copy +#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release +#define HTABLE_KEY_FUNCTOR_EQ eq_str +#define HTABLE_KEY_FUNCTOR_HASH hash_str +#include "hash_table.h" + static void test_htbl_str_int(void) { @@ -145,7 +141,7 @@ test_htbl_str_int(void) str_init(&allocator_proxy, &tmp); - htable_str_int_init(&htbl, &allocator_proxy, hash_str, eq_str); + htable_str_int_init(&allocator_proxy, &htbl); CHECK(htable_str_int_is_empty(&htbl), 1); str_set(&tmp, "empty"); CHECK(htable_str_int_find(&htbl, &tmp), NULL); @@ -231,7 +227,7 @@ test_htbl_str_int(void) CHECK(htable_str_int_size_get(&htbl), 0); htable_str_int_release(&htbl); - htable_str_int_init(&htbl, &allocator_proxy, hash_str, eq_str); + htable_str_int_init(&allocator_proxy, &htbl); htable_str_int_reserve(&htbl, 3); str_set(&tmp, "Zero"), i = 0; CHECK(htable_str_int_set(&htbl, &tmp, &i), 0); @@ -271,6 +267,8 @@ test_htbl_str_int(void) #define HTABLE_KEY_FUNCTOR_RELEASE str_release #define HTABLE_KEY_FUNCTOR_COPY str_copy #define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release +#define HTABLE_KEY_FUNCTOR_EQ eq_str +#define HTABLE_KEY_FUNCTOR_HASH hash_str #define HTABLE_DATA_FUNCTOR_INIT darray_char_init #define HTABLE_DATA_FUNCTOR_RELEASE darray_char_release #define HTABLE_DATA_FUNCTOR_COPY darray_char_copy @@ -350,7 +348,7 @@ ANGVBA BS QRZBAF EHA NZBX VA BHE PVGVRF.", const size_t nerase = 3; mem_init_proxy_allocator(&allocator_proxy, &mem_default_allocator); - htable_str_darray_init(&htbl, &allocator_proxy, hash_str, eq_str); + htable_str_darray_init(&allocator_proxy, &htbl); darray_char_init(&allocator_proxy, &darray); str_init(&allocator_proxy, &tmp);