Replaced unnecessary node struct from intervalheap to a buffer of array[2]
This commit is contained in:
1 parent
5af021ec0a
commit
fe78937150
4 files changed
+234
-260
No files matched your search
@@ -26,7 +26,6 @@ TODO
|
||||
|
||||
[ ] Use binary search to find optimum hashtable prime size inside impl_calculate_size
|
||||
[ ] Optimize certain loops that use iterators that can simply use a normal loop
|
||||
[ ] Replace IntervalHeap node by a simple buffer of two pointers (V (*buffer)[2])
|
||||
|
||||
#!! Done -------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -62,3 +61,4 @@ TODO
|
||||
[X] Merge bidirectional map key_buffer and val_buffer to a single buffer and make key_dist and val_dist into dist[2]
|
||||
[X] Callback utility
|
||||
on_create, on_read, on_update, on_delete, on_resize
|
||||
[X] Replace IntervalHeap node by a simple buffer of two pointers (V (*buffer)[2])
|
||||
+113
-133
@@ -59,13 +59,14 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
/* Heap Structure */ \
|
||||
struct SNAME \
|
||||
{ \
|
||||
/* Dynamic array of nodes */ \
|
||||
struct SNAME##_node *buffer; \
|
||||
/* Dynamic array of elements */ \
|
||||
/* buffer[n][0] is MinHeap and buffer[n][1] is MaxHeap */ \
|
||||
V (*buffer)[2]; \
|
||||
\
|
||||
/* Current array capacity (how many nodes can be stored) */ \
|
||||
/* Current array capacity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of nodes in the dynamic array */ \
|
||||
/* Current amount of pairs of values in the array */ \
|
||||
size_t size; \
|
||||
\
|
||||
/* Current amount of elements in the heap */ \
|
||||
@@ -90,14 +91,6 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
struct cmc_callbacks *callbacks; \
|
||||
}; \
|
||||
\
|
||||
/* Heap Node */ \
|
||||
struct SNAME##_node \
|
||||
{ \
|
||||
/* 0 - Value belonging to the MinHeap */ \
|
||||
/* 1 - Value belonging to the MaxHeap */ \
|
||||
V data[2]; \
|
||||
}; \
|
||||
\
|
||||
/* Value struct function table */ \
|
||||
struct SNAME##_fval \
|
||||
{ \
|
||||
@@ -220,12 +213,9 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
if (!_heap_) \
|
||||
return NULL; \
|
||||
\
|
||||
/* Since each node can store two elements, divide the actual */ \
|
||||
/* capacity by 2 */ \
|
||||
/* Round the capacity of nodes up */ \
|
||||
capacity = capacity % 2 == 0 ? capacity / 2 : (capacity + 1) / 2; \
|
||||
capacity = (capacity + capacity % 2) / 2; \
|
||||
\
|
||||
_heap_->buffer = alloc->calloc(capacity, sizeof(struct SNAME##_node)); \
|
||||
_heap_->buffer = alloc->calloc(capacity, sizeof(V[2])); \
|
||||
\
|
||||
if (!_heap_->buffer) \
|
||||
{ \
|
||||
@@ -264,12 +254,9 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
if (!_heap_) \
|
||||
return NULL; \
|
||||
\
|
||||
/* Since each node can store two elements, divide the actual */ \
|
||||
/* capacity by 2 */ \
|
||||
/* Round the capacity of nodes up */ \
|
||||
capacity = capacity % 2 == 0 ? capacity / 2 : (capacity + 1) / 2; \
|
||||
capacity = (capacity + capacity % 2) / 2; \
|
||||
\
|
||||
_heap_->buffer = alloc->calloc(capacity, sizeof(struct SNAME##_node)); \
|
||||
_heap_->buffer = alloc->calloc(capacity, sizeof(V[2])); \
|
||||
\
|
||||
if (!_heap_->buffer) \
|
||||
{ \
|
||||
@@ -296,11 +283,11 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
{ \
|
||||
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(V) * _heap_->capacity); \
|
||||
memset(_heap_->buffer, 0, sizeof(V[2]) * _heap_->capacity); \
|
||||
\
|
||||
_heap_->size = 0; \
|
||||
_heap_->count = 0; \
|
||||
@@ -313,7 +300,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
{ \
|
||||
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]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -346,26 +333,26 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
if (_heap_->count % 2 == 0) \
|
||||
{ \
|
||||
/* Occupying a new node */ \
|
||||
_heap_->buffer[_heap_->size].data[0] = value; \
|
||||
_heap_->buffer[_heap_->size].data[1] = (V){ 0 }; \
|
||||
_heap_->buffer[_heap_->size][0] = value; \
|
||||
_heap_->buffer[_heap_->size][1] = (V){ 0 }; \
|
||||
\
|
||||
_heap_->size++; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
struct SNAME##_node *node = &(_heap_->buffer[_heap_->size - 1]); \
|
||||
V(*node)[2] = &(_heap_->buffer[_heap_->size - 1]); \
|
||||
\
|
||||
/* Decide if the new element goes into the MinHeap or MaxHeap */ \
|
||||
if (_heap_->f_val->cmp(node->data[0], value) > 0) \
|
||||
if (_heap_->f_val->cmp((*node)[0], value) > 0) \
|
||||
{ \
|
||||
/* Swap current value and add new element to the MinHeap */ \
|
||||
node->data[1] = node->data[0]; \
|
||||
node->data[0] = value; \
|
||||
(*node)[1] = (*node)[0]; \
|
||||
(*node)[0] = value; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* No need to swap and add the new element to the MaxHeap */ \
|
||||
node->data[1] = value; \
|
||||
(*node)[1] = value; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -377,12 +364,11 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
/* 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 - 2) / 2]); \
|
||||
V(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]); \
|
||||
\
|
||||
if (_heap_->f_val->cmp(parent->data[0], value) > 0) \
|
||||
if (_heap_->f_val->cmp((*parent)[0], value) > 0) \
|
||||
PFX##_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) \
|
||||
PFX##_impl_float_up_max(_heap_); \
|
||||
/* else no float up required */ \
|
||||
} \
|
||||
@@ -403,7 +389,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
\
|
||||
if (_heap_->count == 1) \
|
||||
{ \
|
||||
_heap_->buffer[0].data[0] = (V){ 0 }; \
|
||||
_heap_->buffer[0][0] = (V){ 0 }; \
|
||||
\
|
||||
_heap_->count--; \
|
||||
_heap_->size--; \
|
||||
@@ -413,22 +399,22 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
\
|
||||
/* Swap the result with the last element in the MaxHeap and float */ \
|
||||
/* it down */ \
|
||||
struct SNAME##_node *last_node = &(_heap_->buffer[_heap_->size - 1]); \
|
||||
V(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); \
|
||||
\
|
||||
if (_heap_->count % 2 == 1) \
|
||||
{ \
|
||||
/* Grab from MinHeap and discard last node */ \
|
||||
_heap_->buffer[0].data[1] = last_node->data[0]; \
|
||||
_heap_->buffer[0][1] = (*last_node)[0]; \
|
||||
\
|
||||
last_node->data[0] = (V){ 0 }; \
|
||||
(*last_node)[0] = (V){ 0 }; \
|
||||
\
|
||||
_heap_->size--; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_heap_->buffer[0].data[1] = last_node->data[1]; \
|
||||
_heap_->buffer[0][1] = (*last_node)[1]; \
|
||||
\
|
||||
last_node->data[1] = (V){ 0 }; \
|
||||
(*last_node)[1] = (V){ 0 }; \
|
||||
} \
|
||||
\
|
||||
_heap_->count--; \
|
||||
@@ -456,7 +442,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
\
|
||||
if (_heap_->count == 1) \
|
||||
{ \
|
||||
_heap_->buffer[0].data[0] = (V){ 0 }; \
|
||||
_heap_->buffer[0][0] = (V){ 0 }; \
|
||||
\
|
||||
_heap_->count--; \
|
||||
_heap_->size--; \
|
||||
@@ -466,22 +452,22 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
\
|
||||
/* Swap the result with the last element in the MinHeap and float */ \
|
||||
/* it down */ \
|
||||
struct SNAME##_node *last_node = &(_heap_->buffer[_heap_->size - 1]); \
|
||||
V(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); \
|
||||
\
|
||||
_heap_->buffer[0].data[0] = last_node->data[0]; \
|
||||
_heap_->buffer[0][0] = (*last_node)[0]; \
|
||||
\
|
||||
if (_heap_->count % 2 == 1) \
|
||||
{ \
|
||||
/* Discard last node */ \
|
||||
last_node->data[0] = (V){ 0 }; \
|
||||
(*last_node)[0] = (V){ 0 }; \
|
||||
\
|
||||
_heap_->size--; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Place the MaxHeap value in the MinHeap value spot */ \
|
||||
last_node->data[0] = last_node->data[1]; \
|
||||
last_node->data[1] = (V){ 0 }; \
|
||||
(*last_node)[0] = (*last_node)[1]; \
|
||||
(*last_node)[1] = (V){ 0 }; \
|
||||
} \
|
||||
\
|
||||
_heap_->count--; \
|
||||
@@ -509,21 +495,21 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
\
|
||||
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) \
|
||||
{ \
|
||||
/* Corner case: we are updating the Max value but it is less */ \
|
||||
/* than the Min value */ \
|
||||
_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; \
|
||||
\
|
||||
PFX##_impl_float_down_max(_heap_); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Update Max element and float it down */ \
|
||||
_heap_->buffer[0].data[1] = value; \
|
||||
_heap_->buffer[0][1] = value; \
|
||||
\
|
||||
PFX##_impl_float_down_max(_heap_); \
|
||||
} \
|
||||
@@ -546,21 +532,21 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
\
|
||||
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) \
|
||||
{ \
|
||||
/* Corner case: we are updating the Min value but it is greater */ \
|
||||
/* than the Max value. */ \
|
||||
_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; \
|
||||
\
|
||||
PFX##_impl_float_down_min(_heap_); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Update Min element and float it down */ \
|
||||
_heap_->buffer[0].data[0] = value; \
|
||||
_heap_->buffer[0][0] = value; \
|
||||
\
|
||||
PFX##_impl_float_down_min(_heap_); \
|
||||
} \
|
||||
@@ -589,9 +575,9 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
/* If there is only one element, then the maximum element is the */ \
|
||||
/* same as the one in the MinHeap */ \
|
||||
if (_heap_->count == 1) \
|
||||
return _heap_->buffer[0].data[0]; \
|
||||
return _heap_->buffer[0][0]; \
|
||||
\
|
||||
return _heap_->buffer[0].data[1]; \
|
||||
return _heap_->buffer[0][1]; \
|
||||
} \
|
||||
\
|
||||
V PFX##_min(struct SNAME *_heap_) \
|
||||
@@ -607,7 +593,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
if (_heap_->callbacks && _heap_->callbacks->read) \
|
||||
_heap_->callbacks->read(); \
|
||||
\
|
||||
return _heap_->buffer[0].data[0]; \
|
||||
return _heap_->buffer[0][0]; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_contains(struct SNAME *_heap_, V value) \
|
||||
@@ -618,8 +604,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
\
|
||||
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 = true; \
|
||||
break; \
|
||||
@@ -676,10 +661,10 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
capacity = capacity % 2 == 0 ? capacity / 2 : (capacity + 1) / 2; \
|
||||
capacity += capacity % 2; \
|
||||
\
|
||||
struct SNAME##_node *new_buffer = _heap_->alloc->realloc( \
|
||||
_heap_->buffer, sizeof(struct SNAME##_node) * capacity); \
|
||||
V(*new_buffer) \
|
||||
[2] = _heap_->alloc->realloc(_heap_->buffer, sizeof(V[2]) * capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
{ \
|
||||
@@ -690,8 +675,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
if (capacity > _heap_->capacity) \
|
||||
{ \
|
||||
memset(new_buffer + _heap_->capacity, 0, \
|
||||
sizeof(struct SNAME##_node) * \
|
||||
(capacity - _heap_->capacity)); \
|
||||
sizeof(V[2]) * (capacity - _heap_->capacity)); \
|
||||
} \
|
||||
\
|
||||
_heap_->buffer = new_buffer; \
|
||||
@@ -719,8 +703,8 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
\
|
||||
memcpy(result, _heap_, sizeof(struct SNAME)); \
|
||||
\
|
||||
result->buffer = _heap_->alloc->malloc(sizeof(struct SNAME##_node) * \
|
||||
_heap_->capacity); \
|
||||
result->buffer = \
|
||||
_heap_->alloc->malloc(sizeof(V[2]) * _heap_->capacity); \
|
||||
\
|
||||
if (!result->buffer) \
|
||||
{ \
|
||||
@@ -732,12 +716,12 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
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 SNAME##_node) * _heap_->capacity); \
|
||||
sizeof(V[2]) * _heap_->capacity); \
|
||||
\
|
||||
result->capacity = _heap_->capacity; \
|
||||
result->size = _heap_->size; \
|
||||
@@ -764,8 +748,8 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
\
|
||||
for (size_t i = 0; i < _heap1_->count; i++) \
|
||||
{ \
|
||||
V value1 = _heap1_->buffer[i / 2].data[i % 2]; \
|
||||
V value2 = _heap2_->buffer[i / 2].data[i % 2]; \
|
||||
V value1 = _heap1_->buffer[i / 2][i % 2]; \
|
||||
V value2 = _heap2_->buffer[i / 2][i % 2]; \
|
||||
\
|
||||
if (_heap1_->f_val->cmp(value1, value2) != 0) \
|
||||
return false; \
|
||||
@@ -791,7 +775,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
{ \
|
||||
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 false; \
|
||||
} \
|
||||
\
|
||||
@@ -954,7 +938,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return (V){ 0 }; \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor / 2].data[iter->cursor % 2]; \
|
||||
return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_iter_index(struct SNAME##_iter *iter) \
|
||||
@@ -966,7 +950,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
{ \
|
||||
size_t index = _heap_->size - 1; \
|
||||
\
|
||||
struct SNAME##_node *curr_node = &(_heap_->buffer[index]); \
|
||||
V(*curr_node)[2] = &(_heap_->buffer[index]); \
|
||||
\
|
||||
/* FLoat Up on the MaxHeap */ \
|
||||
while (index > 0) \
|
||||
@@ -974,35 +958,33 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
/* Parent index */ \
|
||||
size_t P_index = (index - 1) / 2; \
|
||||
\
|
||||
struct SNAME##_node *parent = &(_heap_->buffer[P_index]); \
|
||||
V(*parent)[2] = &(_heap_->buffer[P_index]); \
|
||||
\
|
||||
if (index == _heap_->size - 1 && _heap_->count % 2 != 0) \
|
||||
{ \
|
||||
/* In this case, the current node has no MaxHeap value so */ \
|
||||
/* we instead compare with the MinHeap value */ \
|
||||
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; \
|
||||
\
|
||||
/* Since the comparison above passed now we need to swap */ \
|
||||
/* the current node with the parent but it will have to be */ \
|
||||
/* done with the node's MinHeap value since the MaxHeap */ \
|
||||
/* value doesn't exist */ \
|
||||
V tmp = curr_node->data[0]; \
|
||||
curr_node->data[0] = parent->data[1]; \
|
||||
parent->data[1] = tmp; \
|
||||
V tmp = (*curr_node)[0]; \
|
||||
(*curr_node)[0] = (*parent)[1]; \
|
||||
(*parent)[1] = tmp; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Usual case, just compare both MaxHeap values */ \
|
||||
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; \
|
||||
\
|
||||
/* Swap with parent and repeat */ \
|
||||
V tmp = curr_node->data[1]; \
|
||||
curr_node->data[1] = parent->data[1]; \
|
||||
parent->data[1] = tmp; \
|
||||
V tmp = (*curr_node)[1]; \
|
||||
(*curr_node)[1] = (*parent)[1]; \
|
||||
(*parent)[1] = tmp; \
|
||||
} \
|
||||
\
|
||||
/* Update indexe and node */ \
|
||||
@@ -1015,7 +997,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
{ \
|
||||
size_t index = _heap_->size - 1; \
|
||||
\
|
||||
struct SNAME##_node *curr_node = &(_heap_->buffer[index]); \
|
||||
V(*curr_node)[2] = &(_heap_->buffer[index]); \
|
||||
\
|
||||
/* FLoat Up on the MinHeap */ \
|
||||
while (index > 0) \
|
||||
@@ -1023,15 +1005,15 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
/* Parent index */ \
|
||||
size_t P_index = (index - 1) / 2; \
|
||||
\
|
||||
struct SNAME##_node *parent = &(_heap_->buffer[P_index]); \
|
||||
V(*parent)[2] = &(_heap_->buffer[P_index]); \
|
||||
\
|
||||
if (_heap_->f_val->cmp(curr_node->data[0], parent->data[0]) >= 0) \
|
||||
if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[0]) >= 0) \
|
||||
break; \
|
||||
\
|
||||
/* Swap with parent and repeat */ \
|
||||
V tmp = curr_node->data[0]; \
|
||||
curr_node->data[0] = parent->data[0]; \
|
||||
parent->data[0] = tmp; \
|
||||
V tmp = (*curr_node)[0]; \
|
||||
(*curr_node)[0] = (*parent)[0]; \
|
||||
(*parent)[0] = tmp; \
|
||||
\
|
||||
/* Update indexe and node */ \
|
||||
index = P_index; \
|
||||
@@ -1044,7 +1026,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
/* Floats Down from the MinHeap */ \
|
||||
size_t index = 0; \
|
||||
\
|
||||
struct SNAME##_node *curr_node = &(_heap_->buffer[index]); \
|
||||
V(*curr_node)[2] = &(_heap_->buffer[index]); \
|
||||
\
|
||||
while (true) \
|
||||
{ \
|
||||
@@ -1060,18 +1042,18 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
/* If there are two children, pick the smallest one */ \
|
||||
if (R_index < _heap_->size) \
|
||||
{ \
|
||||
struct SNAME##_node *L = &(_heap_->buffer[L_index]); \
|
||||
struct SNAME##_node *R = &(_heap_->buffer[R_index]); \
|
||||
V(*L)[2] = &(_heap_->buffer[L_index]); \
|
||||
V(*R)[2] = &(_heap_->buffer[R_index]); \
|
||||
\
|
||||
/* If the right child is the last node and there is no */ \
|
||||
/* MaxHeap value */ \
|
||||
/* then do the comparison with the MinHeap value */ \
|
||||
if (R_index == _heap_->size - 1 && _heap_->count % 2 != 0) \
|
||||
child = _heap_->f_val->cmp(L->data[1], R->data[0]) > 0 \
|
||||
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 \
|
||||
child = _heap_->f_val->cmp((*L)[1], (*R)[1]) > 0 \
|
||||
? L_index \
|
||||
: R_index; \
|
||||
} \
|
||||
@@ -1079,7 +1061,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
else \
|
||||
child = L_index; \
|
||||
\
|
||||
struct SNAME##_node *child_node = &(_heap_->buffer[child]); \
|
||||
V(*child_node)[2] = &(_heap_->buffer[child]); \
|
||||
\
|
||||
/* Again, check if the child node is the last one and has no */ \
|
||||
/* MaxHeap value */ \
|
||||
@@ -1088,38 +1070,38 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
/* Odd case, compare with MinHeap value */ \
|
||||
/* If current value is not less than the child node's */ \
|
||||
/* value it is done */ \
|
||||
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; \
|
||||
\
|
||||
/* Otherwise swap and continue */ \
|
||||
V tmp = child_node->data[0]; \
|
||||
child_node->data[0] = curr_node->data[1]; \
|
||||
curr_node->data[1] = tmp; \
|
||||
V tmp = (*child_node)[0]; \
|
||||
(*child_node)[0] = (*curr_node)[1]; \
|
||||
(*curr_node)[1] = tmp; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* If current value is not less than the child node's */ \
|
||||
/* value it is done */ \
|
||||
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; \
|
||||
\
|
||||
/* Otherwise swap and continue */ \
|
||||
V tmp = child_node->data[1]; \
|
||||
child_node->data[1] = curr_node->data[1]; \
|
||||
curr_node->data[1] = tmp; \
|
||||
V tmp = (*child_node)[1]; \
|
||||
(*child_node)[1] = (*curr_node)[1]; \
|
||||
(*curr_node)[1] = tmp; \
|
||||
\
|
||||
/* Check if the MinHeap and MaxHeap values need to be */ \
|
||||
/* swapped */ \
|
||||
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) \
|
||||
{ \
|
||||
/* Swap because the MinHeap value is greater than the */ \
|
||||
/* MaxHeap value */ \
|
||||
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; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -1134,7 +1116,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
/* Floats Down from the MinHeap */ \
|
||||
size_t index = 0; \
|
||||
\
|
||||
struct SNAME##_node *curr_node = &(_heap_->buffer[index]); \
|
||||
V(*curr_node)[2] = &(_heap_->buffer[index]); \
|
||||
\
|
||||
while (true) \
|
||||
{ \
|
||||
@@ -1150,42 +1132,40 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
|
||||
/* If there are two children, pick the smallest one */ \
|
||||
if (R_index < _heap_->size) \
|
||||
{ \
|
||||
struct SNAME##_node *L = &(_heap_->buffer[L_index]); \
|
||||
struct SNAME##_node *R = &(_heap_->buffer[R_index]); \
|
||||
V(*L)[2] = &(_heap_->buffer[L_index]); \
|
||||
V(*R)[2] = &(_heap_->buffer[R_index]); \
|
||||
\
|
||||
child = _heap_->f_val->cmp(L->data[0], R->data[0]) < 0 \
|
||||
? L_index \
|
||||
: R_index; \
|
||||
child = _heap_->f_val->cmp((*L)[0], (*R)[0]) < 0 ? L_index \
|
||||
: R_index; \
|
||||
} \
|
||||
/* Pick the only one available */ \
|
||||
else \
|
||||
child = L_index; \
|
||||
\
|
||||
struct SNAME##_node *child_node = &(_heap_->buffer[child]); \
|
||||
V(*child_node)[2] = &(_heap_->buffer[child]); \
|
||||
\
|
||||
/* If current value is smaller than the child node's value, it */ \
|
||||
/* is done */ \
|
||||
if (_heap_->f_val->cmp(curr_node->data[0], child_node->data[0]) < \
|
||||
0) \
|
||||
if (_heap_->f_val->cmp((*curr_node)[0], (*child_node)[0]) < 0) \
|
||||
break; \
|
||||
\
|
||||
/* Otherwise swap and continue */ \
|
||||
V tmp = child_node->data[0]; \
|
||||
child_node->data[0] = curr_node->data[0]; \
|
||||
curr_node->data[0] = tmp; \
|
||||
V tmp = (*child_node)[0]; \
|
||||
(*child_node)[0] = (*curr_node)[0]; \
|
||||
(*curr_node)[0] = tmp; \
|
||||
\
|
||||
/* If the child node is the last node check if the MinHeap and */ \
|
||||
/* MaxHeap values need to be swapped */ \
|
||||
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) \
|
||||
{ \
|
||||
/* Swap because the MinHeap value is greater than the */ \
|
||||
/* MaxHeap value */ \
|
||||
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; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
|
||||
+107
-119
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user