Added intervalheap resize
This commit is contained in:
1 parent
1f11b6d2da
commit
99cd01ba1e
2 files changed
+91
-21
No files matched your search
+25
-19
@@ -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; \
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user