Replaced unnecessary node struct from intervalheap to a buffer of array[2]

This commit is contained in:
Leonardo committed 2020-04-22 11:51:05 -03:00
1 parent 5af021ec0a
commit fe78937150
4 files changed
+234 -260

No files matched your search

+107 -119
View File
@@ -2,7 +2,7 @@
struct intervalheap
{
struct intervalheap_node *buffer;
size_t (*buffer)[2];
size_t capacity;
size_t size;
size_t count;
@@ -13,10 +13,6 @@ struct intervalheap
struct cmc_alloc_node *alloc;
struct cmc_callbacks *callbacks;
};
struct intervalheap_node
{
size_t data[2];
};
struct intervalheap_fval
{
int (*cmp)(size_t, size_t);
@@ -90,8 +86,8 @@ struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val)
struct intervalheap *_heap_ = alloc->malloc(sizeof(struct intervalheap));
if (!_heap_)
return ((void *)0);
capacity = capacity % 2 == 0 ? capacity / 2 : (capacity + 1) / 2;
_heap_->buffer = alloc->calloc(capacity, sizeof(struct intervalheap_node));
capacity = (capacity + capacity % 2) / 2;
_heap_->buffer = alloc->calloc(capacity, sizeof(size_t[2]));
if (!_heap_->buffer)
{
alloc->free(_heap_);
@@ -122,8 +118,8 @@ struct intervalheap *ih_new_custom(size_t capacity,
struct intervalheap *_heap_ = alloc->malloc(sizeof(struct intervalheap));
if (!_heap_)
return ((void *)0);
capacity = capacity % 2 == 0 ? capacity / 2 : (capacity + 1) / 2;
_heap_->buffer = alloc->calloc(capacity, sizeof(struct intervalheap_node));
capacity = (capacity + capacity % 2) / 2;
_heap_->buffer = alloc->calloc(capacity, sizeof(size_t[2]));
if (!_heap_->buffer)
{
alloc->free(_heap_);
@@ -146,10 +142,10 @@ void ih_clear(struct intervalheap *_heap_)
{
for (size_t i = 0; i < _heap_->count; i++)
{
_heap_->f_val->free(_heap_->buffer[i / 2].data[i % 2]);
_heap_->f_val->free(_heap_->buffer[i / 2][i % 2]);
}
}
memset(_heap_->buffer, 0, sizeof(size_t) * _heap_->capacity);
memset(_heap_->buffer, 0, sizeof(size_t[2]) * _heap_->capacity);
_heap_->size = 0;
_heap_->count = 0;
_heap_->flag = cmc_flags.OK;
@@ -160,7 +156,7 @@ void ih_free(struct intervalheap *_heap_)
{
for (size_t i = 0; i < _heap_->count; i++)
{
_heap_->f_val->free(_heap_->buffer[i / 2].data[i % 2]);
_heap_->f_val->free(_heap_->buffer[i / 2][i % 2]);
}
}
_heap_->alloc->free(_heap_->buffer);
@@ -185,32 +181,31 @@ _Bool ih_insert(struct intervalheap *_heap_, size_t value)
}
if (_heap_->count % 2 == 0)
{
_heap_->buffer[_heap_->size].data[0] = value;
_heap_->buffer[_heap_->size].data[1] = (size_t){ 0 };
_heap_->buffer[_heap_->size][0] = value;
_heap_->buffer[_heap_->size][1] = (size_t){ 0 };
_heap_->size++;
}
else
{
struct intervalheap_node *node = &(_heap_->buffer[_heap_->size - 1]);
if (_heap_->f_val->cmp(node->data[0], value) > 0)
size_t(*node)[2] = &(_heap_->buffer[_heap_->size - 1]);
if (_heap_->f_val->cmp((*node)[0], value) > 0)
{
node->data[1] = node->data[0];
node->data[0] = value;
(*node)[1] = (*node)[0];
(*node)[0] = value;
}
else
{
node->data[1] = value;
(*node)[1] = value;
}
}
_heap_->count++;
_heap_->flag = cmc_flags.OK;
if (_heap_->count > 2)
{
struct intervalheap_node *parent =
&(_heap_->buffer[(_heap_->size - 2) / 2]);
if (_heap_->f_val->cmp(parent->data[0], value) > 0)
size_t(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]);
if (_heap_->f_val->cmp((*parent)[0], value) > 0)
ih_impl_float_up_min(_heap_);
else if (_heap_->f_val->cmp(parent->data[1], value) < 0)
else if (_heap_->f_val->cmp((*parent)[1], value) < 0)
ih_impl_float_up_max(_heap_);
}
if (_heap_->callbacks && _heap_->callbacks->create)
@@ -226,22 +221,22 @@ _Bool ih_remove_max(struct intervalheap *_heap_)
}
if (_heap_->count == 1)
{
_heap_->buffer[0].data[0] = (size_t){ 0 };
_heap_->buffer[0][0] = (size_t){ 0 };
_heap_->count--;
_heap_->size--;
goto success;
}
struct intervalheap_node *last_node = &(_heap_->buffer[_heap_->size - 1]);
size_t(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]);
if (_heap_->count % 2 == 1)
{
_heap_->buffer[0].data[1] = last_node->data[0];
last_node->data[0] = (size_t){ 0 };
_heap_->buffer[0][1] = (*last_node)[0];
(*last_node)[0] = (size_t){ 0 };
_heap_->size--;
}
else
{
_heap_->buffer[0].data[1] = last_node->data[1];
last_node->data[1] = (size_t){ 0 };
_heap_->buffer[0][1] = (*last_node)[1];
(*last_node)[1] = (size_t){ 0 };
}
_heap_->count--;
ih_impl_float_down_max(_heap_);
@@ -260,22 +255,22 @@ _Bool ih_remove_min(struct intervalheap *_heap_)
}
if (_heap_->count == 1)
{
_heap_->buffer[0].data[0] = (size_t){ 0 };
_heap_->buffer[0][0] = (size_t){ 0 };
_heap_->count--;
_heap_->size--;
goto success;
}
struct intervalheap_node *last_node = &(_heap_->buffer[_heap_->size - 1]);
_heap_->buffer[0].data[0] = last_node->data[0];
size_t(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]);
_heap_->buffer[0][0] = (*last_node)[0];
if (_heap_->count % 2 == 1)
{
last_node->data[0] = (size_t){ 0 };
(*last_node)[0] = (size_t){ 0 };
_heap_->size--;
}
else
{
last_node->data[0] = last_node->data[1];
last_node->data[1] = (size_t){ 0 };
(*last_node)[0] = (*last_node)[1];
(*last_node)[1] = (size_t){ 0 };
}
_heap_->count--;
ih_impl_float_down_min(_heap_);
@@ -294,17 +289,17 @@ _Bool ih_update_max(struct intervalheap *_heap_, size_t value)
}
if (_heap_->count == 1)
{
_heap_->buffer[0].data[0] = value;
_heap_->buffer[0][0] = value;
}
else if (_heap_->f_val->cmp(value, _heap_->buffer[0].data[0]) < 0)
else if (_heap_->f_val->cmp(value, _heap_->buffer[0][0]) < 0)
{
_heap_->buffer[0].data[1] = _heap_->buffer[0].data[0];
_heap_->buffer[0].data[0] = value;
_heap_->buffer[0][1] = _heap_->buffer[0][0];
_heap_->buffer[0][0] = value;
ih_impl_float_down_max(_heap_);
}
else
{
_heap_->buffer[0].data[1] = value;
_heap_->buffer[0][1] = value;
ih_impl_float_down_max(_heap_);
}
_heap_->flag = cmc_flags.OK;
@@ -321,17 +316,17 @@ _Bool ih_update_min(struct intervalheap *_heap_, size_t value)
}
if (_heap_->count == 1)
{
_heap_->buffer[0].data[0] = value;
_heap_->buffer[0][0] = value;
}
else if (_heap_->f_val->cmp(value, _heap_->buffer[0].data[1]) > 0)
else if (_heap_->f_val->cmp(value, _heap_->buffer[0][1]) > 0)
{
_heap_->buffer[0].data[0] = _heap_->buffer[0].data[1];
_heap_->buffer[0].data[1] = value;
_heap_->buffer[0][0] = _heap_->buffer[0][1];
_heap_->buffer[0][1] = value;
ih_impl_float_down_min(_heap_);
}
else
{
_heap_->buffer[0].data[0] = value;
_heap_->buffer[0][0] = value;
ih_impl_float_down_min(_heap_);
}
_heap_->flag = cmc_flags.OK;
@@ -350,8 +345,8 @@ size_t ih_max(struct intervalheap *_heap_)
if (_heap_->callbacks && _heap_->callbacks->read)
_heap_->callbacks->read();
if (_heap_->count == 1)
return _heap_->buffer[0].data[0];
return _heap_->buffer[0].data[1];
return _heap_->buffer[0][0];
return _heap_->buffer[0][1];
}
size_t ih_min(struct intervalheap *_heap_)
{
@@ -363,7 +358,7 @@ size_t ih_min(struct intervalheap *_heap_)
_heap_->flag = cmc_flags.OK;
if (_heap_->callbacks && _heap_->callbacks->read)
_heap_->callbacks->read();
return _heap_->buffer[0].data[0];
return _heap_->buffer[0][0];
}
_Bool ih_contains(struct intervalheap *_heap_, size_t value)
{
@@ -371,7 +366,7 @@ _Bool ih_contains(struct intervalheap *_heap_, size_t value)
_Bool result = 0;
for (size_t i = 0; i < _heap_->count; i++)
{
if (_heap_->f_val->cmp(_heap_->buffer[i / 2].data[i % 2], value) == 0)
if (_heap_->f_val->cmp(_heap_->buffer[i / 2][i % 2], value) == 0)
{
result = 1;
break;
@@ -415,9 +410,9 @@ _Bool ih_resize(struct intervalheap *_heap_, size_t capacity)
_heap_->flag = cmc_flags.ERROR;
return 0;
}
capacity = capacity % 2 == 0 ? capacity / 2 : (capacity + 1) / 2;
struct intervalheap_node *new_buffer = _heap_->alloc->realloc(
_heap_->buffer, sizeof(struct intervalheap_node) * capacity);
capacity += capacity % 2;
size_t(*new_buffer)[2] =
_heap_->alloc->realloc(_heap_->buffer, sizeof(size_t[2]) * capacity);
if (!new_buffer)
{
_heap_->flag = cmc_flags.ALLOC;
@@ -426,8 +421,7 @@ _Bool ih_resize(struct intervalheap *_heap_, size_t capacity)
if (capacity > _heap_->capacity)
{
memset(new_buffer + _heap_->capacity, 0,
sizeof(struct intervalheap_node) *
(capacity - _heap_->capacity));
sizeof(size_t[2]) * (capacity - _heap_->capacity));
}
_heap_->buffer = new_buffer;
_heap_->capacity = capacity;
@@ -447,8 +441,8 @@ struct intervalheap *ih_copy_of(struct intervalheap *_heap_)
return ((void *)0);
}
memcpy(result, _heap_, sizeof(struct intervalheap));
result->buffer = _heap_->alloc->malloc(sizeof(struct intervalheap_node) *
_heap_->capacity);
result->buffer =
_heap_->alloc->malloc(sizeof(size_t[2]) * _heap_->capacity);
if (!result->buffer)
{
_heap_->alloc->free(result);
@@ -458,12 +452,12 @@ struct intervalheap *ih_copy_of(struct intervalheap *_heap_)
if (_heap_->f_val->cpy)
{
for (size_t i = 0; i < _heap_->count; i++)
result->buffer[i / 2].data[i % 2] =
_heap_->f_val->cpy(_heap_->buffer[i / 2].data[i % 2]);
result->buffer[i / 2][i % 2] =
_heap_->f_val->cpy(_heap_->buffer[i / 2][i % 2]);
}
else
memcpy(result->buffer, _heap_->buffer,
sizeof(struct intervalheap_node) * _heap_->capacity);
sizeof(size_t[2]) * _heap_->capacity);
result->capacity = _heap_->capacity;
result->size = _heap_->size;
result->count = _heap_->count;
@@ -484,8 +478,8 @@ _Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_)
return 0;
for (size_t i = 0; i < _heap1_->count; i++)
{
size_t value1 = _heap1_->buffer[i / 2].data[i % 2];
size_t value2 = _heap2_->buffer[i / 2].data[i % 2];
size_t value1 = _heap1_->buffer[i / 2][i % 2];
size_t value2 = _heap2_->buffer[i / 2][i % 2];
if (_heap1_->f_val->cmp(value1, value2) != 0)
return 0;
}
@@ -505,7 +499,7 @@ _Bool ih_print(struct intervalheap *_heap_, FILE *fptr)
{
for (size_t i = 0; i < _heap_->count; i++)
{
if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2].data[i % 2]))
if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2]))
return 0;
}
return 1;
@@ -626,7 +620,7 @@ size_t ih_iter_value(struct intervalheap_iter *iter)
{
if (ih_empty(iter->target))
return (size_t){ 0 };
return iter->target->buffer[iter->cursor / 2].data[iter->cursor % 2];
return iter->target->buffer[iter->cursor / 2][iter->cursor % 2];
}
size_t ih_iter_index(struct intervalheap_iter *iter)
{
@@ -635,26 +629,26 @@ size_t ih_iter_index(struct intervalheap_iter *iter)
static void ih_impl_float_up_max(struct intervalheap *_heap_)
{
size_t index = _heap_->size - 1;
struct intervalheap_node *curr_node = &(_heap_->buffer[index]);
size_t(*curr_node)[2] = &(_heap_->buffer[index]);
while (index > 0)
{
size_t P_index = (index - 1) / 2;
struct intervalheap_node *parent = &(_heap_->buffer[P_index]);
size_t(*parent)[2] = &(_heap_->buffer[P_index]);
if (index == _heap_->size - 1 && _heap_->count % 2 != 0)
{
if (_heap_->f_val->cmp(curr_node->data[0], parent->data[1]) < 0)
if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[1]) < 0)
break;
size_t tmp = curr_node->data[0];
curr_node->data[0] = parent->data[1];
parent->data[1] = tmp;
size_t tmp = (*curr_node)[0];
(*curr_node)[0] = (*parent)[1];
(*parent)[1] = tmp;
}
else
{
if (_heap_->f_val->cmp(curr_node->data[1], parent->data[1]) < 0)
if (_heap_->f_val->cmp((*curr_node)[1], (*parent)[1]) < 0)
break;
size_t tmp = curr_node->data[1];
curr_node->data[1] = parent->data[1];
parent->data[1] = tmp;
size_t tmp = (*curr_node)[1];
(*curr_node)[1] = (*parent)[1];
(*parent)[1] = tmp;
}
index = P_index;
curr_node = parent;
@@ -663,16 +657,16 @@ static void ih_impl_float_up_max(struct intervalheap *_heap_)
static void ih_impl_float_up_min(struct intervalheap *_heap_)
{
size_t index = _heap_->size - 1;
struct intervalheap_node *curr_node = &(_heap_->buffer[index]);
size_t(*curr_node)[2] = &(_heap_->buffer[index]);
while (index > 0)
{
size_t P_index = (index - 1) / 2;
struct intervalheap_node *parent = &(_heap_->buffer[P_index]);
if (_heap_->f_val->cmp(curr_node->data[0], parent->data[0]) >= 0)
size_t(*parent)[2] = &(_heap_->buffer[P_index]);
if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[0]) >= 0)
break;
size_t tmp = curr_node->data[0];
curr_node->data[0] = parent->data[0];
parent->data[0] = tmp;
size_t tmp = (*curr_node)[0];
(*curr_node)[0] = (*parent)[0];
(*parent)[0] = tmp;
index = P_index;
curr_node = parent;
}
@@ -680,7 +674,7 @@ static void ih_impl_float_up_min(struct intervalheap *_heap_)
static void ih_impl_float_down_max(struct intervalheap *_heap_)
{
size_t index = 0;
struct intervalheap_node *curr_node = &(_heap_->buffer[index]);
size_t(*curr_node)[2] = &(_heap_->buffer[index]);
while (1)
{
if (2 * index + 1 >= _heap_->size)
@@ -690,43 +684,38 @@ static void ih_impl_float_down_max(struct intervalheap *_heap_)
size_t R_index = index * 2 + 2;
if (R_index < _heap_->size)
{
struct intervalheap_node *L = &(_heap_->buffer[L_index]);
struct intervalheap_node *R = &(_heap_->buffer[R_index]);
size_t(*L)[2] = &(_heap_->buffer[L_index]);
size_t(*R)[2] = &(_heap_->buffer[R_index]);
if (R_index == _heap_->size - 1 && _heap_->count % 2 != 0)
child = _heap_->f_val->cmp(L->data[1], R->data[0]) > 0
? L_index
: R_index;
child = _heap_->f_val->cmp((*L)[1], (*R)[0]) > 0 ? L_index
: R_index;
else
child = _heap_->f_val->cmp(L->data[1], R->data[1]) > 0
? L_index
: R_index;
child = _heap_->f_val->cmp((*L)[1], (*R)[1]) > 0 ? L_index
: R_index;
}
else
child = L_index;
struct intervalheap_node *child_node = &(_heap_->buffer[child]);
size_t(*child_node)[2] = &(_heap_->buffer[child]);
if (child == _heap_->size - 1 && _heap_->count % 2 != 0)
{
if (_heap_->f_val->cmp(curr_node->data[1], child_node->data[0]) >=
0)
if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[0]) >= 0)
break;
size_t tmp = child_node->data[0];
child_node->data[0] = curr_node->data[1];
curr_node->data[1] = tmp;
size_t tmp = (*child_node)[0];
(*child_node)[0] = (*curr_node)[1];
(*curr_node)[1] = tmp;
}
else
{
if (_heap_->f_val->cmp(curr_node->data[1], child_node->data[1]) >=
0)
if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[1]) >= 0)
break;
size_t tmp = child_node->data[1];
child_node->data[1] = curr_node->data[1];
curr_node->data[1] = tmp;
if (_heap_->f_val->cmp(child_node->data[0], child_node->data[1]) >
0)
size_t tmp = (*child_node)[1];
(*child_node)[1] = (*curr_node)[1];
(*curr_node)[1] = tmp;
if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0)
{
tmp = child_node->data[0];
child_node->data[0] = child_node->data[1];
child_node->data[1] = tmp;
tmp = (*child_node)[0];
(*child_node)[0] = (*child_node)[1];
(*child_node)[1] = tmp;
}
}
index = child;
@@ -736,7 +725,7 @@ static void ih_impl_float_down_max(struct intervalheap *_heap_)
static void ih_impl_float_down_min(struct intervalheap *_heap_)
{
size_t index = 0;
struct intervalheap_node *curr_node = &(_heap_->buffer[index]);
size_t(*curr_node)[2] = &(_heap_->buffer[index]);
while (1)
{
if (2 * index + 1 >= _heap_->size)
@@ -746,27 +735,26 @@ static void ih_impl_float_down_min(struct intervalheap *_heap_)
size_t R_index = index * 2 + 2;
if (R_index < _heap_->size)
{
struct intervalheap_node *L = &(_heap_->buffer[L_index]);
struct intervalheap_node *R = &(_heap_->buffer[R_index]);
child = _heap_->f_val->cmp(L->data[0], R->data[0]) < 0 ? L_index
: R_index;
size_t(*L)[2] = &(_heap_->buffer[L_index]);
size_t(*R)[2] = &(_heap_->buffer[R_index]);
child =
_heap_->f_val->cmp((*L)[0], (*R)[0]) < 0 ? L_index : R_index;
}
else
child = L_index;
struct intervalheap_node *child_node = &(_heap_->buffer[child]);
if (_heap_->f_val->cmp(curr_node->data[0], child_node->data[0]) < 0)
size_t(*child_node)[2] = &(_heap_->buffer[child]);
if (_heap_->f_val->cmp((*curr_node)[0], (*child_node)[0]) < 0)
break;
size_t tmp = child_node->data[0];
child_node->data[0] = curr_node->data[0];
curr_node->data[0] = tmp;
size_t tmp = (*child_node)[0];
(*child_node)[0] = (*curr_node)[0];
(*curr_node)[0] = tmp;
if (child != _heap_->size - 1 || _heap_->count % 2 == 0)
{
if (_heap_->f_val->cmp(child_node->data[0], child_node->data[1]) >
0)
if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0)
{
tmp = child_node->data[0];
child_node->data[0] = child_node->data[1];
child_node->data[1] = tmp;
tmp = (*child_node)[0];
(*child_node)[0] = (*child_node)[1];
(*child_node)[1] = tmp;
}
}
index = child;
+13 -7
View File
@@ -157,6 +157,12 @@ CMC_CREATE_UNIT(IntervalHeap, true, {
cmc_assert_equals(int32_t, 10001, v_total_free);
size_t sum = 0;
for (size_t i = 0; i < ih->capacity; i++)
sum += ih->buffer[i / 2][i % 2];
cmc_assert_equals(size_t, 0, sum);
ih_free(ih);
cmc_assert_equals(int32_t, 10001, v_total_free);
@@ -264,21 +270,21 @@ CMC_CREATE_UNIT(IntervalHeap, true, {
cmc_assert_not_equals(ptr, NULL, ih);
cmc_assert(ih_insert(ih, 2));
cmc_assert_equals(size_t, 2, ih->buffer[0].data[0]);
cmc_assert_equals(size_t, 2, ih->buffer[0][0]);
cmc_assert(ih_insert(ih, 1));
cmc_assert_equals(size_t, 1, ih->buffer[0].data[0]);
cmc_assert_equals(size_t, 2, ih->buffer[0].data[1]);
cmc_assert_equals(size_t, 1, ih->buffer[0][0]);
cmc_assert_equals(size_t, 2, ih->buffer[0][1]);
cmc_assert(ih_remove_min(ih));
cmc_assert_equals(size_t, 2, ih->buffer[0].data[0]);
cmc_assert_equals(size_t, 2, ih->buffer[0][0]);
cmc_assert(ih_insert(ih, 1));
cmc_assert_equals(size_t, 1, ih->buffer[0].data[0]);
cmc_assert_equals(size_t, 2, ih->buffer[0].data[1]);
cmc_assert_equals(size_t, 1, ih->buffer[0][0]);
cmc_assert_equals(size_t, 2, ih->buffer[0][1]);
cmc_assert(ih_remove_max(ih));
cmc_assert_equals(size_t, 1, ih->buffer[0].data[0]);
cmc_assert_equals(size_t, 1, ih->buffer[0][0]);
ih_free(ih);
total_create = 0;