rsys

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

commit 3549e9d1e6d9cba04ed58e098ff2f733b03688a2
parent 25e61caedcce78bbbc1f0be6d52115f2d932b2c8
Author: vaplv <vaplv@free.fr>
Date:   Sat,  5 Apr 2014 23:19:10 +0200

Add support of specific init/copy/release hash table functors

Diffstat:
Msrc/dynamic_array.h | 4++--
Msrc/hash_table.h | 186++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
2 files changed, 144 insertions(+), 46 deletions(-)

diff --git a/src/dynamic_array.h b/src/dynamic_array.h @@ -73,9 +73,9 @@ DARRAY_FUNC__(functor_cp__)(DARRAY_DATA* dst, DARRAY_DATA const* src) static FINLINE int DARRAY_FUNC__(functor_cp_and_release__)(DARRAY_DATA* dst, DARRAY_DATA* src) { - DARRAY_FUNCTOR_COPY(dst, src); + const int res = DARRAY_FUNCTOR_COPY(dst, src); DARRAY_FUNCTOR_RELEASE(src); - return 0; + return res; } #define DARRAY_FUNCTOR_COPY_AND_RELEASE DARRAY_FUNC__(functor_cp_and_release__) #endif diff --git a/src/hash_table.h b/src/hash_table.h @@ -18,15 +18,15 @@ * - 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; - * TODO - * - HTABLE_FUNCTOR_INIT: init functor on HTABLE_DATA. If not defined, no - * specific treatment is performed on the created data; - * - HTABLE_FUNCTOR_COPY: copy functor on HTABLE_DATA. If not defined a - * bitwise copy is used instead; - * - HTABLE_FUNCTOR_RELEASE: release functor on HTABLE_DATA. If not defined - * nothing is done on the release of an element; - * - HTABLE_FUNCTOR_COPY_AND_RELEASE: Copy and release of a HTABLE_DATA. If - * not defined the copy and the release functors is used. + * - 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 + * defined a bitwise copy is used instead; + * - HTABLE_<DATA|KEY>_FUNCTOR_RELEASE: release functor on HTABLE_<DATA|KEY>. + * If not defined nothing is done on the release of an element; + * - HTABLE_<DATA|KEY>_FUNCTOR_COPY_AND_RELEASE: Copy and release of a + * HTABLE_<DATA|KEY>. If not defined the copy and the release functors is + * used. * * The name of the generated types are: * struct htable_<HTABLE_NAME>[_pair|_iterator] @@ -49,13 +49,12 @@ #define HTABLE__ CONCAT(htable_, HTABLE_NAME) #define HTABLE_PAIR__ CONCAT(CONCAT(HTABLE__, _), pair) -#define HTABLE_INTERATOR__ CONCAT(HTABLE, iterator) +#define HTABLE_ITERATOR__ CONCAT(HTABLE, iterator) #define HTABLE_FUNC__(Func) \ CONCAT(CONCAT(CONCAT(CONCAT(htable, _), HTABLE_NAME), _), Func) /* Internal data structure */ -struct HTABLE_PAIR__ -{ +struct HTABLE_PAIR__ { HTABLE_DATA data; HTABLE_KEY key; }; @@ -67,8 +66,7 @@ struct HTABLE_PAIR__ #define HTABLE_DATA__ CONCAT(CONCAT(darray_, HTABLE_NAME), __) #define HTABLE_DATA_FUNC__(Func) CONCAT(CONCAT(HTABLE_DATA__, _), Func) -struct HTABLE__ -{ +struct HTABLE__ { struct HTABLE_DATA__ table; struct darray_char table_slot_is_used; size_t table_size_in_use; @@ -79,14 +77,83 @@ struct HTABLE__ struct mem_allocator* allocator; }; -struct HTABLE_INTERATOR__ -{ +struct HTABLE_ITERATOR__ { struct HTABLE__* hash_table; size_t slot; size_t entries_scanned; }; /******************************************************************************* + * Internal default functions + ******************************************************************************/ +#ifndef HTABLE_DATA_FUNCTOR_INIT +static FINLINE void +HTABLE_FUNC__(data_functor_init__) + (struct mem_allocator* alloc, HTABLE_DATA* data) +{ ASSERT(data); (void)alloc, (void)data; } +#define HTABLE_DATA_FUNCTOR_INIT HTABLE_FUNC__(data_functor_init__) +#endif + +#ifndef HTABLE_KEY_FUNCTOR_INIT +static FINLINE void +HTABLE_FUNC__(key_functor_init__)(struct mem_allocator* alloc, HTABLE_KEY* key) +{ ASSERT(key); (void)alloc, (void)key; } +#define HTABLE_KEY_FUNCTOR_INIT HTABLE_FUNC__(key_functor_init__) +#endif + +#ifndef HTABLE_DATA_FUNCTOR_RELEASE +static FINLINE void +HTABLE_FUNC__(data_functor_release__)(HTABLE_DATA* data) +{ ASSERT(data); (void)data; } +#define HTABLE_DATA_FUNCTOR_RELEASE HTABLE_FUNC__(data_functor_release__) +#endif + +#ifndef HTABLE_KEY_FUNCTOR_RELEASE +static FINLINE void +HTABLE_FUNC__(key_functor_release__)(HTABLE_KEY* key) +{ ASSERT(key); (void)key; } +#define HTABLE_KEY_FUNCTOR_RELEASE HTABLE_FUNC__(key_functor_release__) +#endif + +#ifndef HTABLE_DATA_FUNCTOR_COPY +static FINLINE int +HTABLE_FUNC__(data_functor_cp__)(HTABLE_DATA* dst, HTABLE_DATA const* src) +{ ASSERT(dst && src); *dst = *src; return 0; } +#define HTABLE_DATA_FUNCTOR_COPY HTABLE_FUNC__(data_functor_cp__) +#endif + +#ifndef HTABLE_KEY_FUNCTOR_COPY +static FINLINE int +HTABLE_FUNC__(key_functor_cp__)(HTABLE_KEY* dst, HTABLE_KEY const* src) +{ ASSERT(dst && src); *dst = *src; return 0; } +#define HTABLE_KEY_FUNCTOR_COPY HTABLE_FUNC__(key_functor_cp__) +#endif + +#ifndef HTABLE_DATA_FUNCTOR_COPY_AND_RELEASE +static FINLINE int +HTABLE_FUNC__(data_functor_cp_and_release__)(HTABLE_DATA* dst, HTABLE_DATA* src) +{ + const int res = HTABLE_DATA_FUNCTOR_COPY(dst, src); + HTABLE_DATA_FUNCTOR_RELEASE(src); + return res; +} +#define HTABLE_DATA_FUNCTOR_COPY_AND_RELEASE \ + HTABLE_FUNC__(data_functor_cp_and_release__) +#endif + +#ifndef HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE +static FINLINE int +HTABLE_FUNC__(key_functor_cp_and_release__)(HTABLE_KEY* dst, HTABLE_KEY* src) +{ + const int res = HTABLE_KEY_FUNCTOR_COPY(dst, src); + HTABLE_KEY_FUNCTOR_RELEASE(src); + return res; +} +#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE \ + HTABLE_FUNC__(key_functor_cp_and_release__) +#endif + +/******************************************************************************* * Internal helper functions ******************************************************************************/ static INLINE size_t @@ -147,21 +214,33 @@ HTABLE_FUNC__(init) } static INLINE void -HTABLE_FUNC__(release)(struct HTABLE__* htbl) +HTABLE_FUNC__(clear)(struct HTABLE__* htbl) { + size_t islot = 0, in_use = 0; ASSERT(htbl); - HTABLE_DATA_FUNC__(release)(&htbl->table); - darray_char_release(&htbl->table_slot_is_used); + + FOR_EACH(islot, 0, HTABLE_DATA_FUNC__(size_get)(&htbl->table)) { + struct HTABLE_PAIR__* pair = NULL; + if(in_use == htbl->table_size_in_use) + break; /* Early stop the rehasing since there is no more slot in htbl */ + + if(!darray_char_cdata_get(&htbl->table_slot_is_used)[islot]) + continue; + + darray_char_data_get(&htbl->table_slot_is_used)[islot] = 0; + pair = HTABLE_DATA_FUNC__(data_get)(&htbl->table) + islot; + HTABLE_KEY_FUNCTOR_RELEASE(&pair->key); + HTABLE_DATA_FUNCTOR_RELEASE(&pair->data); + } } static INLINE void -HTABLE_FUNC__(clear)(struct HTABLE__* htbl) +HTABLE_FUNC__(release)(struct HTABLE__* htbl) { - ASSERT( htbl ); - htbl->table_size_in_use = 0; - memset - (darray_char_data_get(&htbl->table_slot_is_used), 0, - darray_char_size_get(&htbl->table_slot_is_used) * sizeof(char)); + ASSERT(htbl); + HTABLE_FUNC__(clear)(htbl); + HTABLE_DATA_FUNC__(release)(&htbl->table); + darray_char_release(&htbl->table_slot_is_used); } /* Return 0 on success and -1 otherwise */ @@ -170,7 +249,7 @@ HTABLE_FUNC__(reserve)(struct HTABLE__* htbl, const size_t size_submitted) { struct HTABLE_DATA__ tbl; struct darray_char tbl_slot_is_used; - const struct HTABLE_PAIR__* old_pairs = NULL; + struct HTABLE_PAIR__* old_pairs = NULL; struct HTABLE_PAIR__* new_pairs = NULL; const char* old_used_pairs = NULL; char* new_used_pairs = NULL; @@ -194,7 +273,7 @@ HTABLE_FUNC__(reserve)(struct HTABLE__* htbl, const size_t size_submitted) memset(darray_char_data_get(&tbl_slot_is_used), 0, size*sizeof(char)); /* Rehash the hash table */ - old_pairs = HTABLE_DATA_FUNC__(cdata_get)(&htbl->table); + old_pairs = HTABLE_DATA_FUNC__(data_get)(&htbl->table); new_pairs = HTABLE_DATA_FUNC__(data_get)(&tbl); old_used_pairs = darray_char_cdata_get(&htbl->table_slot_is_used); new_used_pairs = darray_char_data_get(&tbl_slot_is_used); @@ -213,7 +292,14 @@ HTABLE_FUNC__(reserve)(struct HTABLE__* htbl, const size_t size_submitted) (!htbl->eq_key(&new_pairs[islot_new].key, &old_pairs[islot].key )); islot_new = (islot_new + 1) & (size - 1); /* (islot_new + 1) % size */ } - new_pairs[islot_new] = old_pairs[islot]; + + HTABLE_KEY_FUNCTOR_INIT(htbl->allocator, &new_pairs[islot_new].key); + HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE + (&new_pairs[islot_new].key, &old_pairs[islot].key); + HTABLE_DATA_FUNCTOR_INIT(htbl->allocator, &new_pairs[islot_new].data); + HTABLE_DATA_FUNCTOR_COPY_AND_RELEASE + (&new_pairs[islot_new].data, &old_pairs[islot].data); + new_used_pairs[islot_new] = 1; ++in_use; } @@ -237,6 +323,7 @@ HTABLE_FUNC__(set) HTABLE_KEY const* key, HTABLE_DATA const* data ) { + struct HTABLE_PAIR__* pair = NULL; size_t tbl_size = 0; size_t i = 0; int res = 0; @@ -255,11 +342,15 @@ HTABLE_FUNC__(set) } i = HTABLE_FUNC__(find_slot__)(htbl, key); + pair = HTABLE_DATA_FUNC__(data_get)(&htbl->table) + i; if(darray_char_cdata_get(&htbl->table_slot_is_used)[i]) { - HTABLE_DATA_FUNC__(data_get)(&htbl->table)[i].data = *data; + HTABLE_DATA_FUNCTOR_COPY(&pair->data, data); } else { - HTABLE_DATA_FUNC__(data_get)(&htbl->table)[i].data = *data; - HTABLE_DATA_FUNC__(data_get)(&htbl->table)[i].key = *key; + HTABLE_KEY_FUNCTOR_INIT(htbl->allocator, &pair->key); + HTABLE_KEY_FUNCTOR_COPY(&pair->key, key); + HTABLE_DATA_FUNCTOR_INIT(htbl->allocator, &pair->data); + HTABLE_DATA_FUNCTOR_COPY(&pair->data, data); + darray_char_data_get(&htbl->table_slot_is_used)[i] = 1; ++htbl->table_size_in_use; } @@ -286,6 +377,8 @@ HTABLE_FUNC__(erase)(struct HTABLE__* htbl, HTABLE_KEY const* key) /* Remove the entry */ used_pairs[i] = 0; + HTABLE_KEY_FUNCTOR_RELEASE(&pairs[i].key); + HTABLE_DATA_FUNCTOR_RELEASE(&pairs[i].data); --htbl->table_size_in_use; for(j = (i + 1) & (tbl_size - 1); /* <=> j = (i+1) % size */ @@ -296,7 +389,8 @@ HTABLE_FUNC__(erase)(struct HTABLE__* htbl, HTABLE_KEY const* key) if(i <= j ? (i < k && k <= j) : (i < k || k <= j)) continue; - pairs[i] = pairs[j]; + HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE(&pairs[i].key, &pairs[j].key); + HTABLE_DATA_FUNCTOR_COPY_AND_RELEASE(&pairs[i].data, &pairs[j].data); used_pairs[i] = 1; used_pairs[j] = 0; i = j; @@ -337,7 +431,7 @@ HTABLE_FUNC__(size_get)(const struct HTABLE__* htbl) static INLINE void HTABLE_FUNC__(begin) (struct HTABLE__* htbl, - struct HTABLE_INTERATOR__* it) + struct HTABLE_ITERATOR__* it) { const char* used_pairs = NULL; size_t i = 0; @@ -348,7 +442,7 @@ HTABLE_FUNC__(begin) used_pairs = darray_char_cdata_get(&htbl->table_slot_is_used); it->slot = it->entries_scanned = 0; - for( i = 0; i < tbl_size && !used_pairs[i]; ++i) {} + for(i = 0; i < tbl_size && !used_pairs[i]; ++i) {} it->slot = i; it->entries_scanned = i < tbl_size; it->hash_table = htbl; @@ -357,7 +451,7 @@ HTABLE_FUNC__(begin) static INLINE void HTABLE_FUNC__(end) (struct HTABLE__* htbl, - struct HTABLE_INTERATOR__* it) + struct HTABLE_ITERATOR__* it) { ASSERT(htbl && it); it->slot = HTABLE_DATA_FUNC__(size_get)(&htbl->table); @@ -366,7 +460,7 @@ HTABLE_FUNC__(end) } static INLINE void -HTABLE_FUNC__(iterator_next)(struct HTABLE_INTERATOR__* it) +HTABLE_FUNC__(iterator_next)(struct HTABLE_ITERATOR__* it) { size_t tbl_size = 0; ASSERT(it); @@ -385,8 +479,8 @@ HTABLE_FUNC__(iterator_next)(struct HTABLE_INTERATOR__* it) static INLINE char HTABLE_FUNC__(iterator_eq) - (const struct HTABLE_INTERATOR__* it0, - const struct HTABLE_INTERATOR__* it1) + (const struct HTABLE_ITERATOR__* it0, + const struct HTABLE_ITERATOR__* it1) { ASSERT(it0 && it1); return @@ -396,26 +490,30 @@ HTABLE_FUNC__(iterator_eq) } static INLINE HTABLE_KEY* -HTABLE_FUNC__(iterator_key_get)(const struct HTABLE_INTERATOR__* it) +HTABLE_FUNC__(iterator_key_get)(const struct HTABLE_ITERATOR__* it) { ASSERT(it && it->slot < HTABLE_DATA_FUNC__(size_get)(&it->hash_table->table)); return &HTABLE_DATA_FUNC__(data_get)(&it->hash_table->table)[it->slot].key; } static INLINE HTABLE_DATA* -HTABLE_FUNC__(iterator_data_get)(const struct HTABLE_INTERATOR__* it) +HTABLE_FUNC__(iterator_data_get)(const struct HTABLE_ITERATOR__* it) { ASSERT(it && it->slot < HTABLE_DATA_FUNC__(size_get)(&it->hash_table->table)); return &HTABLE_DATA_FUNC__(data_get)(&it->hash_table->table)[it->slot].data; } -#undef HTABLE_KEY #undef HTABLE_DATA +#undef HTABLE_FUNCTOR_COPY +#undef HTABLE_FUNCTOR_COPY_AND_RELEASE +#undef HTABLE_FUNCTOR_INIT +#undef HTABLE_FUNCTOR_RELEASE +#undef HTABLE_KEY #undef HTABLE_NAME -#undef HTABLE +#undef HTABLE__ #undef HTABLE_PAIR__ -#undef HTABLE_INTERATOR__ +#undef HTABLE_ITERATOR__ #undef HTABLE_FUNC__ -#endif /* Pre inclusion */ +#endif /* !HTABLE_NAME || !HTABLE_KEY || !HTABLE_DATA */