diff --git a/c/Makefile.no-autoconfig b/c/Makefile.no-autoconfig index 6d3591d21..24dcf357b 100644 --- a/c/Makefile.no-autoconfig +++ b/c/Makefile.no-autoconfig @@ -124,13 +124,14 @@ TEST_MULTIPLE_CONTAINERS_SRCS = \ containers/rslls.c \ lib/string_array.c \ containers/hss.c \ + containers/mlrval.c \ containers/lhmsi.c \ containers/lhmss.c \ containers/lhmsv.c \ containers/lhms2v.c \ containers/lhmslv.c \ containers/lhmsmv.c \ - containers/mlrval.c \ + containers/bind_stack.c \ containers/percentile_keeper.c \ containers/top_keeper.c \ containers/dheap.c \ diff --git a/c/containers/bind_stack.c b/c/containers/bind_stack.c index b28a7072c..60be93c22 100644 --- a/c/containers/bind_stack.c +++ b/c/containers/bind_stack.c @@ -5,6 +5,7 @@ #define INITIAL_SIZE 32 +// ---------------------------------------------------------------- bind_stack_t* bind_stack_alloc() { bind_stack_t* pstack = mlr_malloc_or_die(sizeof(bind_stack_t)); @@ -17,6 +18,7 @@ bind_stack_t* bind_stack_alloc() { return pstack; } +// ---------------------------------------------------------------- void bind_stack_free(bind_stack_t* pstack) { if (pstack == NULL) return; @@ -25,6 +27,7 @@ void bind_stack_free(bind_stack_t* pstack) { free(pstack); } +// ---------------------------------------------------------------- void bind_stack_push(bind_stack_t* pstack, lhmsmv_t* pframe) { if (pstack->num_used > pstack->num_allocated) { pstack->num_allocated += INITIAL_SIZE; @@ -34,14 +37,17 @@ void bind_stack_push(bind_stack_t* pstack, lhmsmv_t* pframe) { pstack->num_used++; } +// ---------------------------------------------------------------- void bind_stack_pop(bind_stack_t* pstack) { if (pstack->num_used <= 0) { fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", MLR_GLOBALS.argv0, __FILE__, __LINE__); exit(1); } + pstack->num_used--; } +// ---------------------------------------------------------------- mv_t* bind_stack_resolve(bind_stack_t* pstack, char* key) { for(int i = pstack->num_used - 1; i >= 0; i--) { mv_t* pval = lhmsmv_get(pstack->pframes[i], key); @@ -51,6 +57,7 @@ mv_t* bind_stack_resolve(bind_stack_t* pstack, char* key) { return NULL; } +// ---------------------------------------------------------------- void bind_stack_print(bind_stack_t* pstack) { printf("BIND STACK BEGIN (#frames %d):\n", pstack->num_used); for (int i = pstack->num_used - 1; i >= 0; i--) { diff --git a/c/containers/lhmsmv.c b/c/containers/lhmsmv.c index 745267a0d..9bc334a98 100644 --- a/c/containers/lhmsmv.c +++ b/c/containers/lhmsmv.c @@ -44,7 +44,7 @@ #define EMPTY 0xce // ---------------------------------------------------------------- -static void lhmsmv_put_no_enlarge(lhmsmv_t* pmap, char* key, mv_t value, char free_flags); +static void lhmsmv_put_no_enlarge(lhmsmv_t* pmap, char* key, mv_t* pvalue, char free_flags); static void lhmsmv_enlarge(lhmsmv_t* pmap); static void lhmsmv_init(lhmsmv_t *pmap, int length) { @@ -130,13 +130,13 @@ static int lhmsmv_find_index_for_key(lhmsmv_t* pmap, char* key, int* pideal_inde } // ---------------------------------------------------------------- -void lhmsmv_put(lhmsmv_t* pmap, char* key, mv_t value, char free_flags) { +void lhmsmv_put(lhmsmv_t* pmap, char* key, mv_t* pvalue, char free_flags) { if ((pmap->num_occupied + pmap->num_freed) >= (pmap->array_length*LOAD_FACTOR)) lhmsmv_enlarge(pmap); - lhmsmv_put_no_enlarge(pmap, key, value, free_flags); + lhmsmv_put_no_enlarge(pmap, key, pvalue, free_flags); } -static void lhmsmv_put_no_enlarge(lhmsmv_t* pmap, char* key, mv_t value, char free_flags) { +static void lhmsmv_put_no_enlarge(lhmsmv_t* pmap, char* key, mv_t* pvalue, char free_flags) { int ideal_index = 0; int index = lhmsmv_find_index_for_key(pmap, key, &ideal_index); lhmsmve_t* pe = &pmap->entries[index]; @@ -145,7 +145,7 @@ static void lhmsmv_put_no_enlarge(lhmsmv_t* pmap, char* key, mv_t value, char fr // Existing key found in chain; put value. if (pe->free_flags & FREE_ENTRY_VALUE) mv_free(&pe->value); - pe->value = value; + pe->value = *pvalue; if (free_flags & FREE_ENTRY_VALUE) pe->free_flags |= FREE_ENTRY_VALUE; else @@ -155,7 +155,7 @@ static void lhmsmv_put_no_enlarge(lhmsmv_t* pmap, char* key, mv_t value, char fr // End of chain. pe->ideal_index = ideal_index; pe->key = key; - pe->value = value; + pe->value = *pvalue; pe->free_flags = free_flags; pmap->states[index] = OCCUPIED; @@ -218,7 +218,7 @@ static void lhmsmv_enlarge(lhmsmv_t* pmap) { lhmsmv_init(pmap, pmap->array_length*ENLARGEMENT_FACTOR); for (lhmsmve_t* pe = old_head; pe != NULL; pe = pe->pnext) { - lhmsmv_put_no_enlarge(pmap, pe->key, pe->value, pe->free_flags); + lhmsmv_put_no_enlarge(pmap, pe->key, &pe->value, pe->free_flags); } free(old_entries); free(old_states); diff --git a/c/containers/lhmsmv.h b/c/containers/lhmsmv.h index a7d0c47fb..29aeaa9df 100644 --- a/c/containers/lhmsmv.h +++ b/c/containers/lhmsmv.h @@ -44,7 +44,7 @@ typedef struct _lhmsmv_t { // ---------------------------------------------------------------- lhmsmv_t* lhmsmv_alloc(); void lhmsmv_free(lhmsmv_t* pmap); -void lhmsmv_put(lhmsmv_t* pmap, char* key, mv_t value, char free_flags); +void lhmsmv_put(lhmsmv_t* pmap, char* key, mv_t* pvalue, char free_flags); mv_t* lhmsmv_get(lhmsmv_t* pmap, char* key); int lhmsmv_has_key(lhmsmv_t* pmap, char* key); diff --git a/c/unit_test/test_multiple_containers.c b/c/unit_test/test_multiple_containers.c index 0ea7829a0..9815902a7 100644 --- a/c/unit_test/test_multiple_containers.c +++ b/c/unit_test/test_multiple_containers.c @@ -13,6 +13,7 @@ #include "containers/lhms2v.h" #include "containers/lhmslv.h" #include "containers/lhmsmv.h" +#include "containers/bind_stack.h" #include "containers/percentile_keeper.h" #include "containers/top_keeper.h" #include "containers/dheap.h" @@ -523,7 +524,7 @@ static char* test_lhmsmv() { mu_assert_lf(!lhmsmv_has_key(pmap, "z")); mu_assert_lf(lhmsmv_get(pmap, "z") == NULL); mu_assert_lf(lhmsmv_check_counts(pmap)); - lhmsmv_put(pmap, "x", mv_from_int(3), NO_FREE); + lhmsmv_put(pmap, "x", imv(3), NO_FREE); lhmsmv_dump(pmap); printf("\n"); mu_assert_lf(pmap->num_occupied == 1); @@ -534,7 +535,7 @@ static char* test_lhmsmv() { mu_assert_lf(!lhmsmv_has_key(pmap, "z")); mu_assert_lf(lhmsmv_get(pmap, "z") == NULL); mu_assert_lf(lhmsmv_check_counts(pmap)); - lhmsmv_put(pmap, "y", mv_from_string_no_free("5"), NO_FREE); + lhmsmv_put(pmap, "y", smv("5"), NO_FREE); lhmsmv_dump(pmap); printf("\n"); mu_assert_lf(pmap->num_occupied == 2); @@ -545,7 +546,7 @@ static char* test_lhmsmv() { mu_assert_lf(!lhmsmv_has_key(pmap, "z")); mu_assert_lf(lhmsmv_get(pmap, "z") == NULL); mu_assert_lf(lhmsmv_check_counts(pmap)); - lhmsmv_put(pmap, "x", mv_from_string_no_free("f"), NO_FREE); + lhmsmv_put(pmap, "x", smv("f"), NO_FREE); lhmsmv_dump(pmap); printf("\n"); mu_assert_lf(pmap->num_occupied == 2); @@ -555,7 +556,7 @@ static char* test_lhmsmv() { mu_assert_lf(!lhmsmv_has_key(pmap, "z")); mu_assert_lf(lhmsmv_get(pmap, "z") == NULL); mu_assert_lf(lhmsmv_check_counts(pmap)); - lhmsmv_put(pmap, "z", mv_from_int(7), NO_FREE); + lhmsmv_put(pmap, "z", imv(7), NO_FREE); lhmsmv_dump(pmap); printf("\n"); mu_assert_lf(pmap->num_occupied == 3); @@ -572,6 +573,81 @@ static char* test_lhmsmv() { return NULL; } +// ---------------------------------------------------------------- +static char* test_bind_stack() { + printf("\n"); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + bind_stack_t* pstack = bind_stack_alloc(); + bind_stack_print(pstack); + + mu_assert_lf(bind_stack_resolve(pstack, "x") == NULL); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + lhmsmv_t* pframe0 = lhmsmv_alloc(); + bind_stack_push(pstack, pframe0); + bind_stack_print(pstack); + + lhmsmv_put(pframe0, "x", smv("1"), NO_FREE); + lhmsmv_put(pframe0, "y", smv("2"), NO_FREE); + bind_stack_print(pstack); + + mu_assert_lf(bind_stack_resolve(pstack, "x") != NULL); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "x"), smv("1"))); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "x"), imv(1))); + mu_assert_lf(bind_stack_resolve(pstack, "y") != NULL); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "y"), smv("2"))); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "y"), imv(2))); + mu_assert_lf(bind_stack_resolve(pstack, "z") == NULL); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + lhmsmv_t* pframe1 = lhmsmv_alloc(); + bind_stack_push(pstack, pframe1); + bind_stack_print(pstack); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + lhmsmv_t* pframe2 = lhmsmv_alloc(); + bind_stack_push(pstack, pframe2); + bind_stack_print(pstack); + + mu_assert_lf(bind_stack_resolve(pstack, "x") != NULL); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "x"), smv("1"))); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "x"), imv(1))); + mu_assert_lf(bind_stack_resolve(pstack, "y") != NULL); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "y"), smv("2"))); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "y"), imv(2))); + mu_assert_lf(bind_stack_resolve(pstack, "z") == NULL); + + lhmsmv_put(pframe2, "x", smv("three"), NO_FREE); + bind_stack_print(pstack); + + mu_assert_lf(bind_stack_resolve(pstack, "x") != NULL); + mu_assert_lf(!mveq(bind_stack_resolve(pstack, "x"), smv("1"))); + mu_assert_lf(!mveq(bind_stack_resolve(pstack, "x"), imv(1))); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "x"), smv("three"))); + mu_assert_lf(bind_stack_resolve(pstack, "y") != NULL); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "y"), smv("2"))); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "y"), imv(2))); + mu_assert_lf(bind_stack_resolve(pstack, "z") == NULL); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + bind_stack_pop(pstack); + bind_stack_print(pstack); + + mu_assert_lf(bind_stack_resolve(pstack, "x") != NULL); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "x"), smv("1"))); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "x"), imv(1))); + mu_assert_lf(bind_stack_resolve(pstack, "y") != NULL); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "y"), smv("2"))); + mu_assert_lf(mveq(bind_stack_resolve(pstack, "y"), imv(2))); + mu_assert_lf(bind_stack_resolve(pstack, "z") == NULL); + + bind_stack_free(pstack); + + printf("\n"); + return NULL; +} + // ---------------------------------------------------------------- static char* test_percentile_keeper() { @@ -758,6 +834,7 @@ static char * run_all_tests() { mu_run_test(test_lhms2v); mu_run_test(test_lhmslv); mu_run_test(test_lhmsmv); + mu_run_test(test_bind_stack); mu_run_test(test_percentile_keeper); mu_run_test(test_top_keeper); mu_run_test(test_dheap);