Added intervalheap resize

This commit is contained in:
Leonardo committed 2019-10-15 23:52:09 -03:00
1 parent 1f11b6d2da
commit 99cd01ba1e
2 files changed
+91 -21

No files matched your search

+25 -19
View File
@@ -118,6 +118,7 @@ static const char *cmc_string_fmt_intervalheap = "%s at %p { buffer:%p, capacity
size_t PFX##_count(SNAME *_heap_); \
size_t PFX##_capacity(SNAME *_heap_); \
/* Collection Utility */ \
bool PFX##_resize(SNAME *_heap_, size_t capacity); \
SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)); \
bool PFX##_equals(SNAME *_heap1_, SNAME *_heap2_); \
cmc_string PFX##_to_string(SNAME *_heap_); \
@@ -157,7 +158,6 @@ static const char *cmc_string_fmt_intervalheap = "%s at %p { buffer:%p, capacity
#define CMC_GENERATE_INTERVALHEAP_SOURCE(PFX, SNAME, V) \
\
/* Implementation Detail Functions */ \
static bool PFX##_impl_grow(SNAME *_heap_); \
static void PFX##_impl_float_up_max(SNAME *_heap_); \
static void PFX##_impl_float_up_min(SNAME *_heap_); \
static void PFX##_impl_float_down_max(SNAME *_heap_); \
@@ -235,7 +235,7 @@ static const char *cmc_string_fmt_intervalheap = "%s at %p { buffer:%p, capacity
{ \
if (PFX##_full(_heap_)) \
{ \
if (!PFX##_impl_grow(_heap_)) \
if (!PFX##_resize(_heap_, PFX##_capacity(_heap_) * 4)) \
return false; \
} \
\
@@ -485,6 +485,29 @@ static const char *cmc_string_fmt_intervalheap = "%s at %p { buffer:%p, capacity
return _heap_->capacity; \
} \
\
bool PFX##_resize(SNAME *_heap_, size_t capacity) \
{ \
if (PFX##_capacity(_heap_) == capacity) \
return true; \
\
if (capacity < PFX##_count(_heap_)) \
return false; \
\
capacity = capacity % 2 == 0 ? capacity / 2 : (capacity + 1) / 2; \
\
SNAME##_node *new_buffer = realloc(_heap_->buffer, sizeof(SNAME##_node) * capacity); \
\
if (!new_buffer) \
return false; \
\
memset(new_buffer + _heap_->capacity, 0, sizeof(SNAME##_node) * _heap_->capacity); \
\
_heap_->buffer = new_buffer; \
_heap_->capacity = capacity; \
\
return true; \
} \
\
SNAME *PFX##_copy_of(SNAME *_heap_, V (*copy_func)(V)) \
{ \
SNAME *result = malloc(sizeof(SNAME)); \
@@ -704,23 +727,6 @@ static const char *cmc_string_fmt_intervalheap = "%s at %p { buffer:%p, capacity
return iter->cursor; \
} \
\
static bool PFX##_impl_grow(SNAME *_heap_) \
{ \
size_t new_cap = _heap_->capacity * 2; \
\
SNAME##_node *new_buffer = realloc(_heap_->buffer, sizeof(SNAME##_node) * new_cap); \
\
if (!new_buffer) \
return false; \
\
memset(new_buffer + _heap_->capacity, 0, sizeof(SNAME##_node) * _heap_->capacity); \
\
_heap_->buffer = new_buffer; \
_heap_->capacity = new_cap; \
\
return true; \
} \
\
static void PFX##_impl_float_up_max(SNAME *_heap_) \
{ \
size_t index = _heap_->size - 1; \
+66 -2
View File
@@ -28,6 +28,36 @@ CMC_CREATE_UNIT(intervalheap_test, true, {
ih_free(ih, NULL);
});
CMC_CREATE_TEST(new[capacity], {
intervalheap *ih = ih_new(1, cmp);
cmc_assert_not_equals(ptr, NULL, ih);
cmc_assert_equals(size_t, 1, ih_capacity(ih));
ih_free(ih, NULL);
ih = ih_new(2, cmp);
cmc_assert_not_equals(ptr, NULL, ih);
cmc_assert_equals(size_t, 1, ih_capacity(ih));
ih_free(ih, NULL);
ih = ih_new(3, cmp);
cmc_assert_not_equals(ptr, NULL, ih);
cmc_assert_equals(size_t, 2, ih_capacity(ih));
ih_free(ih, NULL);
ih = ih_new(4, cmp);
cmc_assert_not_equals(ptr, NULL, ih);
cmc_assert_equals(size_t, 2, ih_capacity(ih));
ih_free(ih, NULL);
});
CMC_CREATE_TEST(new[capacity = UINT64_MAX], {
intervalheap *ih = ih_new(UINT64_MAX, cmp);
@@ -43,7 +73,7 @@ CMC_CREATE_UNIT(intervalheap_test, true, {
cmc_assert_not_equals(ptr, NULL, ih);
for (size_t i = 0; i < 50; i++)
ih_insert(ih, i);
cmc_assert(ih_insert(ih, i));
cmc_assert_equals(size_t, 50, ih_count(ih));
@@ -61,9 +91,43 @@ CMC_CREATE_UNIT(intervalheap_test, true, {
cmc_assert_not_equals(ptr, NULL, ih);
for (size_t i = 0; i < 50; i++)
ih_insert(ih, 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, NULL);
});
CMC_CREATE_TEST(insert[count], {
intervalheap *ih = ih_new(100, cmp);
cmc_assert_not_equals(ptr, NULL, 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, NULL);
});
CMC_CREATE_TEST(insert[max min], {
intervalheap *ih = ih_new(1, cmp);
cmc_assert_not_equals(ptr, NULL, ih);
cmc_assert(ih_insert(ih, 1));
cmc_assert(ih_insert(ih, 0));
size_t min;
size_t max;
cmc_assert(ih_min(ih, &min));
cmc_assert(ih_max(ih, &max));
cmc_assert_equals(size_t, 0, min);
cmc_assert_equals(size_t, 1, max);
ih_free(ih, NULL);
});