From 5af021ec0a32da078d61e8543cc0a61305c24d06 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Wed, 22 Apr 2020 10:08:06 -0300 Subject: [PATCH] Fixing some things with intervalheap and added more tests --- src/cmc/intervalheap.h | 7 +- tests/main/src/intervalheap.c | 2 +- tests/main/unt/intervalheap.c | 327 ++++++++++++++++++++++++++++++---- 3 files changed, 296 insertions(+), 40 deletions(-) diff --git a/src/cmc/intervalheap.h b/src/cmc/intervalheap.h index 0be111e..860d660 100644 --- a/src/cmc/intervalheap.h +++ b/src/cmc/intervalheap.h @@ -374,10 +374,11 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " \ if (_heap_->count > 2) \ { \ - /* Determine wheather to do a MaxHeap insert or a MinHeap insert \ - */ \ + /* Determine wheather to do a MaxHeap insert or a MinHeap */ \ + /* insert. For any integer this index calculation results in */ \ + /* an even number representing the parent of the last value */ \ struct SNAME##_node *parent = \ - &(_heap_->buffer[(_heap_->size - 1) / 2]); \ + &(_heap_->buffer[(_heap_->size - 2) / 2]); \ \ if (_heap_->f_val->cmp(parent->data[0], value) > 0) \ PFX##_impl_float_up_min(_heap_); \ diff --git a/tests/main/src/intervalheap.c b/tests/main/src/intervalheap.c index 3edc392..5b730c4 100644 --- a/tests/main/src/intervalheap.c +++ b/tests/main/src/intervalheap.c @@ -207,7 +207,7 @@ _Bool ih_insert(struct intervalheap *_heap_, size_t value) if (_heap_->count > 2) { struct intervalheap_node *parent = - &(_heap_->buffer[(_heap_->size - 1) / 2]); + &(_heap_->buffer[(_heap_->size - 2) / 2]); if (_heap_->f_val->cmp(parent->data[0], value) > 0) ih_impl_float_up_min(_heap_); else if (_heap_->f_val->cmp(parent->data[1], value) < 0) diff --git a/tests/main/unt/intervalheap.c b/tests/main/unt/intervalheap.c index 81e63c3..3f5eada 100644 --- a/tests/main/unt/intervalheap.c +++ b/tests/main/unt/intervalheap.c @@ -13,8 +13,20 @@ struct intervalheap_fval *ih_fval = .hash = cmc_size_hash, .pri = cmc_size_cmp }; +struct intervalheap_fval *ih_fval_counter = + &(struct intervalheap_fval){ .cmp = v_c_cmp, + .cpy = v_c_cpy, + .str = v_c_str, + .free = v_c_free, + .hash = v_c_hash, + .pri = v_c_pri }; + +struct cmc_alloc_node *ih_alloc_node = &(struct cmc_alloc_node){ + .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +}; + CMC_CREATE_UNIT(IntervalHeap, true, { - CMC_CREATE_TEST(new, { + CMC_CREATE_TEST(PFX##_new(), { struct intervalheap *ih = ih_new(1000000, ih_fval); cmc_assert_not_equals(ptr, NULL, ih); @@ -23,19 +35,16 @@ CMC_CREATE_UNIT(IntervalHeap, true, { cmc_assert_equals(size_t, 0, ih_count(ih)); ih_free(ih); - }); - CMC_CREATE_TEST(new[capacity = 0], { - struct intervalheap *ih = ih_new(0, ih_fval); + ih = ih_new(0, ih_fval); cmc_assert_equals(ptr, NULL, ih); - if (ih) - ih_free(ih); - }); + ih = ih_new(UINT64_MAX, ih_fval); - CMC_CREATE_TEST(new[capacity], { - struct intervalheap *ih = ih_new(1, ih_fval); + cmc_assert_equals(ptr, NULL, ih); + + ih = ih_new(1, ih_fval); cmc_assert_not_equals(ptr, NULL, ih); cmc_assert_equals(size_t, 1, ih_capacity(ih)); @@ -57,6 +66,56 @@ CMC_CREATE_UNIT(IntervalHeap, true, { ih_free(ih); ih = ih_new(4, ih_fval); + cmc_assert_not_equals(ptr, NULL, ih); + cmc_assert_equals(size_t, 2, ih_capacity(ih)); + + ih_free(ih); + }); + + CMC_CREATE_TEST(PFX##_new_custom(), { + struct intervalheap *ih = ih_new_custom(1000000, ih_fval, ih_alloc_node, callbacks); + + cmc_assert_not_equals(ptr, NULL, ih); + cmc_assert_not_equals(ptr, NULL, ih->buffer); + cmc_assert_equals(size_t, 500000, ih_capacity(ih)); + cmc_assert_equals(size_t, 0, ih_count(ih)); + cmc_assert_equals(ptr, ih_alloc_node, ih->alloc); + cmc_assert_equals(ptr, callbacks, ih->callbacks); + + ih_free(ih); + + ih = ih_new_custom(0, ih_fval, NULL, NULL); + + cmc_assert_equals(ptr, NULL, ih); + + ih = ih_new_custom(UINT64_MAX, ih_fval, NULL, NULL); + + cmc_assert_equals(ptr, NULL, ih); + + ih = ih_new_custom(1, ih_fval, NULL, NULL); + + cmc_assert_not_equals(ptr, NULL, ih); + cmc_assert_equals(size_t, 1, ih_capacity(ih)); + cmc_assert_equals(ptr, &cmc_alloc_node_default, ih->alloc); + cmc_assert_equals(ptr, NULL, ih->callbacks); + + ih_free(ih); + + ih = ih_new_custom(2, ih_fval, NULL, NULL); + + cmc_assert_not_equals(ptr, NULL, ih); + cmc_assert_equals(size_t, 1, ih_capacity(ih)); + + ih_free(ih); + + ih = ih_new_custom(3, ih_fval, NULL, NULL); + + cmc_assert_not_equals(ptr, NULL, ih); + cmc_assert_equals(size_t, 2, ih_capacity(ih)); + + ih_free(ih); + + ih = ih_new_custom(4, ih_fval, NULL, NULL); cmc_assert_not_equals(ptr, NULL, ih); cmc_assert_equals(size_t, 2, ih_capacity(ih)); @@ -64,22 +123,14 @@ CMC_CREATE_UNIT(IntervalHeap, true, { ih_free(ih); }); - CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct intervalheap *ih = ih_new(UINT64_MAX, ih_fval); - - cmc_assert_equals(ptr, NULL, ih); - - if (ih) - ih_free(ih); - }); - - CMC_CREATE_TEST(clear[count capacity], { + CMC_CREATE_TEST(PFX##_clear(), { + v_total_free = 0; struct intervalheap *ih = ih_new(100, ih_fval); cmc_assert_not_equals(ptr, NULL, ih); for (size_t i = 0; i < 50; i++) - cmc_assert(ih_insert(ih, i)); + ih_insert(ih, i); cmc_assert_equals(size_t, 50, ih_count(ih)); @@ -89,37 +140,104 @@ CMC_CREATE_UNIT(IntervalHeap, true, { cmc_assert_equals(size_t, 50, ih_capacity(ih)); ih_free(ih); + + ih = ih_new(100, ih_fval_counter); + + ih_insert(ih, 10); + ih_clear(ih); + + cmc_assert_equals(int32_t, 1, v_total_free); + + for (size_t i = 0; i < 10000; i++) + ih_insert(ih, i); + + cmc_assert_equals(size_t, 10000, ih_count(ih)); + + ih_clear(ih); + + cmc_assert_equals(int32_t, 10001, v_total_free); + + ih_free(ih); + + cmc_assert_equals(int32_t, 10001, v_total_free); + + v_total_free = 0; }); - CMC_CREATE_TEST(buffer_growth[capacity = 1], { - struct intervalheap *ih = ih_new(1, ih_fval); + CMC_CREATE_TEST(PFX##_free(), { + v_total_free = 0; + struct intervalheap *ih = ih_new(100, ih_fval_counter); cmc_assert_not_equals(ptr, NULL, ih); - for (size_t i = 0; i < 50; i++) - cmc_assert(ih_insert(ih, i)); + ih_insert(ih, 10); + ih_free(ih); - cmc_assert_equals(size_t, 50, ih_count(ih)); - cmc_assert_greater(size_t, 50, ih_capacity(ih) * 2); + cmc_assert_equals(int32_t, 1, v_total_free); + + ih = ih_new(100, ih_fval_counter); + + for (size_t i = 0; i < 10000; i++) + ih_insert(ih, i); + + ih_free(ih); + + cmc_assert_equals(int32_t, 10001, v_total_free); + + v_total_free = 0; + }); + + CMC_CREATE_TEST(PFX##_customize(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + ih->flag = cmc_flags.ERROR; + ih_customize(ih, ih_alloc_node, callbacks); + + cmc_assert_equals(ptr, ih_alloc_node, ih->alloc); + cmc_assert_equals(ptr, callbacks, ih->callbacks); + cmc_assert_equals(int32_t, cmc_flags.OK, ih->flag); + + ih->flag = cmc_flags.ERROR; + ih_customize(ih, NULL, NULL); + + cmc_assert_equals(ptr, &cmc_alloc_node_default, ih->alloc); + cmc_assert_equals(ptr, NULL, ih->callbacks); + cmc_assert_equals(int32_t, cmc_flags.OK, ih->flag); ih_free(ih); }); - CMC_CREATE_TEST(insert[count], { + CMC_CREATE_TEST(PFX##_insert(), { + total_create = 0; struct intervalheap *ih = ih_new(100, ih_fval); cmc_assert_not_equals(ptr, NULL, ih); + for (size_t i = 0; i < 100; i++) + ih_insert(ih, 10); + + cmc_assert_equals(size_t, 100, ih_count(ih)); + + ih_clear(ih); + cmc_assert(ih_insert(ih, 1)); cmc_assert(ih_insert(ih, 0)); cmc_assert_equals(size_t, 2, ih_count(ih)); ih_free(ih); - }); - CMC_CREATE_TEST(insert[max], { - struct intervalheap *ih = ih_new(1, ih_fval); + // callbacks + ih = ih_new_custom(100, ih_fval, NULL, callbacks); + + for (size_t i = 0; i < 10000; i++) + ih_insert(ih, i); + + cmc_assert_equals(size_t, 10000, ih_count(ih)); + cmc_assert_equals(int32_t, 10000, total_create); + + // max + ih = ih_new(1, ih_fval); cmc_assert(ih_insert(ih, 0)); cmc_assert(ih_insert(ih, 1)); @@ -128,10 +246,9 @@ CMC_CREATE_UNIT(IntervalHeap, true, { cmc_assert_equals(size_t, 2, ih_max(ih)); ih_free(ih); - }); - CMC_CREATE_TEST(insert[min], { - struct intervalheap *ih = ih_new(1, ih_fval); + // min + ih = ih_new(1, ih_fval); cmc_assert(ih_insert(ih, 0)); cmc_assert(ih_insert(ih, 1)); @@ -140,10 +257,9 @@ CMC_CREATE_UNIT(IntervalHeap, true, { cmc_assert_equals(size_t, 0, ih_min(ih)); ih_free(ih); - }); - CMC_CREATE_TEST(insert[remove_max remove_min], { - struct intervalheap *ih = ih_new(100, ih_fval); + // remove_max, remove_min + ih = ih_new(100, ih_fval); cmc_assert_not_equals(ptr, NULL, ih); @@ -164,6 +280,145 @@ CMC_CREATE_UNIT(IntervalHeap, true, { cmc_assert(ih_remove_max(ih)); cmc_assert_equals(size_t, 1, ih->buffer[0].data[0]); + ih_free(ih); + total_create = 0; + }); + + CMC_CREATE_TEST(PFX##_remove_max(), { + total_delete = 0; + struct intervalheap *ih = ih_new_custom(100, ih_fval, NULL, callbacks); + + // count == 0 + cmc_assert(!ih_remove_max(ih)); + + cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih->flag); + + // count == 1 + cmc_assert(ih_insert(ih, 10)); + ih->flag = cmc_flags.ERROR; + cmc_assert(ih_remove_max(ih)); + + cmc_assert_equals(int32_t, 1, total_delete); + cmc_assert_equals(int32_t, cmc_flags.OK, ih->flag); + + for (size_t i = 1; i <= 1000; i++) + ih_insert(ih, i); + + for (size_t i = 1000; i > 0; i--) + { + cmc_assert_equals(size_t, i, ih_max(ih)); + cmc_assert(ih_remove_max(ih)); + } + + cmc_assert_equals(size_t, 0, ih_count(ih)); + + for (size_t i = 1; i <= 1000; i++) + { + ih_insert(ih, i % 50); + } + + cmc_assert_equals(size_t, 1000, ih_count(ih)); + + for (int i = 49; i >= 0; i--) + { + for (size_t j = 0; j < 20; j++) + { + cmc_assert_equals(size_t, (size_t)i, ih_max(ih)); + cmc_assert(ih_remove_max(ih)); + } + } + + ih_free(ih); + total_delete = 0; + }); + + CMC_CREATE_TEST(PFX##_remove_min(), { + total_delete = 0; + struct intervalheap *ih = ih_new_custom(100, ih_fval, NULL, callbacks); + + // count == 0 + cmc_assert(!ih_remove_min(ih)); + + cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih->flag); + + // count == 1 + cmc_assert(ih_insert(ih, 10)); + ih->flag = cmc_flags.ERROR; + cmc_assert(ih_remove_min(ih)); + + cmc_assert_equals(int32_t, 1, total_delete); + cmc_assert_equals(int32_t, cmc_flags.OK, ih->flag); + + for (size_t i = 1000; i >= 1; i--) + ih_insert(ih, i); + + for (size_t i = 1; i <= 1000; i++) + { + cmc_assert_equals(size_t, i, ih_min(ih)); + cmc_assert(ih_remove_min(ih)); + } + + cmc_assert_equals(size_t, 0, ih_count(ih)); + + for (size_t i = 1000; i >= 1; i--) + { + ih_insert(ih, i % 50); + } + + cmc_assert_equals(size_t, 1000, ih_count(ih)); + + for (int i = 0; i <= 49; i++) + { + for (size_t j = 0; j < 20; j++) + { + cmc_assert_equals(size_t, (size_t)i, ih_min(ih)); + cmc_assert(ih_remove_min(ih)); + } + } + + ih_free(ih); + total_delete = 0; + }); + + CMC_CREATE_TEST(PFX##_remove_max() + PFX##_remove_min(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + for (size_t i = 1; i <= 10000; i++) + { + ih_insert(ih, i % 50); + } + + cmc_assert_equals(size_t, 10000, ih_count(ih)); + + // i = min + // j = max + for (size_t i = 0, j = 49; i < j; i++, j--) + { + for (size_t k = 0; k < 200; k++) + { + cmc_assert_equals(size_t, i, ih_min(ih)); + cmc_assert_equals(size_t, j, ih_max(ih)); + cmc_assert(ih_remove_min(ih)); + cmc_assert(ih_remove_max(ih)); + } + } + + cmc_assert_equals(size_t, 0, ih_count(ih)); + + ih_free(ih); + }); + + CMC_CREATE_TEST(buffer_growth[capacity = 1], { + struct intervalheap *ih = ih_new(1, ih_fval); + + cmc_assert_not_equals(ptr, NULL, ih); + + for (size_t i = 0; i < 50; i++) + cmc_assert(ih_insert(ih, i)); + + cmc_assert_equals(size_t, 50, ih_count(ih)); + cmc_assert_greater(size_t, 50, ih_capacity(ih) * 2); + ih_free(ih); });