rsys

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

commit c0a3c9c6f1e67d3f77da298454e52919767ff776
parent 3727b0670857d3e99af7b0d98a368416d67fbc7a
Author: vaplv <vaplv@free.fr>
Date:   Sun,  6 Apr 2014 15:04:52 +0200

Fix dynamic_array and hash_table issues

Push further the hash_table tests

Diffstat:
Msrc/dynamic_array.h | 4+++-
Msrc/hash_table.h | 15++++++++++-----
Msrc/test_hash_table.c | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 169 insertions(+), 6 deletions(-)

diff --git a/src/dynamic_array.h b/src/dynamic_array.h @@ -250,8 +250,10 @@ DARRAY_FUNC__(copy_and_clear) if(src->data != src->buf && src->allocator == dst->allocator) { /* Give the ownership of src->m_Data to dst */ - if(dst->data != dst->buf) + if(dst->data != dst->buf) { + DARRAY_FUNC__(clear)(dst); MEM_FREE(dst->allocator, dst->data); + } dst->data = src->data; dst->capacity = src->capacity; dst->size = src->size; diff --git a/src/hash_table.h b/src/hash_table.h @@ -276,7 +276,10 @@ HTABLE_FUNC__(clear)(struct HTABLE__* htbl) darray_char_data_get(&htbl->table_slot_is_used)[islot] = 0; pair = HTABLE_DATA_FUNC__(data_get)(&htbl->table) + islot; + /* Release the pair data and re-init it since it must keep valid for + * subsequent uses */ HTABLE_FUNC__(pair_release__)(pair); + HTABLE_FUNC__(pair_init__)(htbl->allocator, pair); } htbl->table_size_in_use = 0; } @@ -340,9 +343,11 @@ HTABLE_FUNC__(reserve)(struct HTABLE__* htbl, const size_t size_submitted) islot_new = (islot_new + 1) & (size - 1); /* (islot_new + 1) % size */ } - HTABLE_FUNC__(pair_init__)(htbl->allocator, &new_pairs[islot_new]); + /* Transfer ownership of old_pairs[islot] data to new_pairs[islot_new]. + * Re-init the old_pairs[islot] structure since it must keep valid */ HTABLE_FUNC__(pair_copy_and_release__) (&new_pairs[islot_new], &old_pairs[islot]); + HTABLE_FUNC__(pair_init__)(htbl->allocator, &old_pairs[islot]); new_used_pairs[islot_new] = 1; ++in_use; @@ -390,7 +395,6 @@ HTABLE_FUNC__(set) if(darray_char_cdata_get(&htbl->table_slot_is_used)[i]) { HTABLE_DATA_FUNCTOR_COPY(&pair->data, data); } else { - HTABLE_FUNC__(pair_init__)(htbl->allocator, pair); HTABLE_KEY_FUNCTOR_COPY(&pair->key, key); HTABLE_DATA_FUNCTOR_COPY(&pair->data, data); @@ -418,8 +422,7 @@ HTABLE_FUNC__(erase)(struct HTABLE__* htbl, HTABLE_KEY const* key) if(!used_pairs[i]) return 0; /* No entry */ - /* Remove the entry */ - HTABLE_FUNC__(pair_release__)(&pairs[i]); + /* Remove the entry but does not release it */ used_pairs[i] = 0; --htbl->table_size_in_use; @@ -431,8 +434,10 @@ HTABLE_FUNC__(erase)(struct HTABLE__* htbl, HTABLE_KEY const* key) if(i <= j ? (i < k && k <= j) : (i < k || k <= j)) continue; - HTABLE_FUNC__(pair_init__)(htbl->allocator, &pairs[i]); + /* Transfer ownership of pairs[j] data to pairs[i]. Re-init pairs[j] since + * it must keep valid for subsequent uses */ HTABLE_FUNC__(pair_copy_and_release__)(&pairs[i], &pairs[j]); + HTABLE_FUNC__(pair_init__)(htbl->allocator, &pairs[j]); used_pairs[i] = 1; used_pairs[j] = 0; i = j; diff --git a/src/test_hash_table.c b/src/test_hash_table.c @@ -1,3 +1,4 @@ +#include "dynamic_array_char.h" #include "hash.h" #include "hash_table.h" #include "str.h" @@ -263,12 +264,167 @@ test_htbl_str_int(void) mem_shutdown_proxy_allocator(&allocator_proxy); } +#define HTABLE_KEY struct str +#define HTABLE_DATA struct darray_char +#define HTABLE_NAME str_darray +#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_DATA_FUNCTOR_INIT darray_char_init +#define HTABLE_DATA_FUNCTOR_RELEASE darray_char_release +#define HTABLE_DATA_FUNCTOR_COPY darray_char_copy +#define HTABLE_DATA_FUNCTOR_COPY_AND_RELEASE darray_char_copy_and_release +#include "hash_table.h" + +static void +test_htbl_str_darray(void) +{ + struct mem_allocator allocator_proxy; + struct htable_str_darray htbl; + struct htable_str_darray_iterator it0; + struct htable_str_darray_iterator it1; + struct darray_char darray; + struct darray_char* data = NULL; + struct str* key = NULL; + struct str tmp; + const char* str[] = { +"Rcvfbqr 1, XARR-QRRC VA GUR QRNQ:\n\ +---------------------------------", + +"BAPR LBH ORNG GUR OVT ONQNFFRF NAQ PYRNA BHG GUR ZBBA ONFR LBH'ER FHCCBFRQ GB\n\ +JVA, NERA'G LBH? NERA'G LBH? JURER'F LBHE SNG ERJNEQ NAQ GVPXRG UBZR? JUNG\n\ +GUR URYY VF GUVF? VG'F ABG FHCCBFRQ GB RAQ GUVF JNL!", + +"VG FGVAXF YVXR EBGGRA ZRNG, OHG YBBXF YVXR GUR YBFG QRVZBF ONFR. YBBXF YVXR\n\ +LBH'ER FGHPX BA GUR FUBERF BS URYY. GUR BAYL JNL BHG VF GUEBHTU.", + +"GB PBAGVAHR GUR QBBZ RKCREVRAPR, CYNL GUR FUBERF BS URYY NAQ VGF NZNMVAT\n\ +FRDHRY, VASREAB!", + +"Rcvfbqr 2, GUR FUBERF BS URYY:\n\ +------------------------------", + +"LBH'IR QBAR VG! GUR UVQRBHF PLORE- QRZBA YBEQ GUNG EHYRQ GUR YBFG QRVZBF ZBBA\n\ +ONFR UNF ORRA FYNVA NAQ LBH NER GEVHZCUNAG! OHG ... JURER NER LBH? LBH\n\ +PYNZORE GB GUR RQTR BS GUR ZBBA NAQ YBBX QBJA GB FRR GUR NJSHY GEHGU.", + +"QRVZBF SYBNGF NOBIR URYY VGFRYS! LBH'IR ARIRE URNEQ BS NALBAR RFPNCVAT SEBZ\n\ +URYY, OHG LBH'YY ZNXR GUR ONFGNEQF FBEEL GURL RIRE URNEQ BS LBH! DHVPXYL, LBH\n\ +ENCCRY QBJA GB GUR FHESNPR BS URYY.", + +"ABJ, VG'F BA GB GUR SVANY PUNCGRE BS QBBZ! -- VASREAB.", + +"Rcvfbqr 3, VASREAB:\n\ +-------------------", + +"GUR YBNGUFBZR FCVQREQRZBA GUNG ZNFGREZVAQRQ GUR VAINFVBA BS GUR ZBBA ONFRF\n\ +NAQ PNHFRQ FB ZHPU QRNGU UNF UNQ VGF NFF XVPXRQ SBE NYY GVZR.", + +"N UVQQRA QBBEJNL BCRAF NAQ LBH RAGRE. LBH'IR CEBIRA GBB GBHTU SBE URYY GB\n\ +PBAGNVA, NAQ ABJ URYY NG YNFG CYNLF SNVE -- SBE LBH RZRETR SEBZ GUR QBBE GB\n\ +FRR GUR TERRA SVRYQF BS RNEGU! UBZR NG YNFG.", + +"LBH JBAQRE JUNG'F ORRA UNCCRAVAT BA RNEGU JUVYR LBH JRER ONGGYVAT RIVY\n\ +HAYRNFURQ. VG'F TBBQ GUNG AB URYY- FCNJA PBHYQ UNIR PBZR GUEBHTU GUNG QBBE\n\ +JVGU LBH ...", + +"Rcvfbqr 4, GUL SYRFU PBAFHZRQ:\n\ +------------------------------", + +"GUR FCVQRE ZNFGREZVAQ ZHFG UNIR FRAG SBEGU VGF YRTVBAF BS URYYFCNJA ORSBER\n\ +LBHE SVANY PBASEBAGNGVBA JVGU GUNG GREEVOYR ORNFG SEBZ URYY. OHG LBH FGRCCRQ\n\ +SBEJNEQ NAQ OEBHTUG SBEGU RGREANY QNZANGVBA NAQ FHSSREVAT HCBA GUR UBEQR NF N\n\ +GEHR UREB JBHYQ VA GUR SNPR BS FBZRGUVAT FB RIVY.", + +"ORFVQRF, FBZRBAR JNF TBAAN CNL SBE JUNG UNCCRARQ GB QNVFL, LBHE CRG ENOOVG.", + +"OHG ABJ, LBH FRR FCERNQ ORSBER LBH ZBER CBGRAGVNY CNVA NAQ TVOOVGHQR NF N\n\ +ANGVBA BS QRZBAF EHA NZBX VA BHE PVGVRF.", + +"ARKG FGBC, URYY BA RNEGU!" + }; + size_t nstrs = sizeof(str)/sizeof(const char*); + size_t i = 0, j = 0, k = 0; + size_t buf[16]; + 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); + darray_char_init(&allocator_proxy, &darray); + str_init(&allocator_proxy, &tmp); + + FOR_EACH(i, 0, nstrs) { + darray_char_clear(&darray); + FOR_EACH(j, 0, strlen(str[i]) + 1) { + CHECK(darray_char_push_back(&darray, str[i] + j), 0); + } + str_set(&tmp, str[i]); + CHECK(htable_str_darray_set(&htbl, &tmp, &darray), 0); + } + + FOR_EACH(j, 0, nerase) { + for(;;) { + i = (size_t)rand() % nstrs; + FOR_EACH(k, 0, j) + if(buf[k] == i) break; + if(k >= j) break; + } + + buf[j] = i; + + str_set(&tmp, str[i]); + data = htable_str_darray_find(&htbl, &tmp); + NCHECK(data, NULL); + CHECK(strcmp(darray_char_cdata_get(data), str_cget(&tmp)), 0); + CHECK(htable_str_darray_erase(&htbl, &tmp), 1); + CHECK(htable_str_darray_erase(&htbl, &tmp), 0); + } + CHECK(htable_str_darray_size_get(&htbl), nstrs - 3); + + htable_str_darray_begin(&htbl, &it0); + htable_str_darray_end(&htbl, &it1); + while(!htable_str_darray_iterator_eq(&it0, &it1)) { + key = htable_str_darray_iterator_key_get(&it0); + data = htable_str_darray_iterator_data_get(&it0); + CHECK(strcmp(str_cget(key), darray_char_cdata_get(data)), 0); + htable_str_darray_iterator_next(&it0); + } + + CHECK(htable_str_darray_reserve(&htbl, 2891), 0); + + FOR_EACH(j, 0, 5) { + for(;;) { + i = (size_t)rand() % nstrs; + FOR_EACH(k, 0, nerase) + if(buf[k] == i) break; + if(k >= nerase) break; + } + str_set(&tmp, str[i]); + data = htable_str_darray_find(&htbl, &tmp); + NCHECK(data, NULL); + CHECK(strcmp(darray_char_cdata_get(data), str_cget(&tmp)), 0); + } + + str_release(&tmp); + darray_char_release(&darray); + htable_str_darray_release(&htbl); + if(MEM_ALLOCATED_SIZE(&allocator_proxy) ) { + char dump[512]; + MEM_DUMP(&allocator_proxy, dump, sizeof(dump) / sizeof(char)); + fprintf(stderr, "error: %s\n", dump); + FATAL("Memory leaks\n"); + } + mem_shutdown_proxy_allocator(&allocator_proxy); +} + int main(int argc, char** argv) { (void)argc, (void)argv; test_htbl_int_float(); test_htbl_str_int(); + test_htbl_str_darray(); return 0; }