Skip to content

Commit

Permalink
just some extra checks
Browse files Browse the repository at this point in the history
  • Loading branch information
xant committed Sep 18, 2015
1 parent 7e6de1a commit e157bb1
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 22 deletions.
56 changes: 41 additions & 15 deletions src/bh.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ static int
binomial_tree_node_add(binomial_tree_node_t *node,
binomial_tree_node_t *child)
{
node->children = realloc(node->children, sizeof(binomial_tree_node_t *) * (node->num_children + 1));
binomial_tree_node_t **children = realloc(node->children, sizeof(binomial_tree_node_t *) * (node->num_children + 1));
if (!children)
return -1;

node->children = children;

node->children[node->num_children++] = child;
if (child->parent) {
// TODO - remove the node
Expand Down Expand Up @@ -159,10 +164,13 @@ binomial_tree_node_destroy(binomial_tree_node_t *node, bh_free_value_callback_t
}

for (i = 0; i < node->num_children; i++) {
if (new_parent)
binomial_tree_node_add(new_parent, node->children[i]);
else
if (new_parent) {
if (binomial_tree_node_add(new_parent, node->children[i]) != 0) {
// TODO - Error Messages, the tree is corrupted (OOM occurred)
}
} else {
node->children[i]->parent = NULL;
}
}

node->bh->count--;
Expand All @@ -180,6 +188,8 @@ bh_t *
bh_create(bh_free_value_callback_t free_value_cb)
{
bh_t *bh = calloc(1, sizeof(bh_t));
if (!bh)
return NULL;
bh->free_value_cb = free_value_cb;
TAILQ_INIT(&bh->trees);
return bh;
Expand All @@ -200,7 +210,10 @@ bh_destroy(bh_t *bh)

static int binomial_tree_merge(binomial_tree_node_t *node1, binomial_tree_node_t *node2)
{
node1->children = realloc(node1->children, sizeof(binomial_tree_node_t *) * (node1->num_children + 1));
binomial_tree_node_t **children = realloc(node1->children, sizeof(binomial_tree_node_t *) * (node1->num_children + 1));
if (!children)
return -1;
node1->children = children;
node1->children[node1->num_children++] = node2;
node2->parent = node1;
return 0;
Expand Down Expand Up @@ -266,6 +279,9 @@ int
bh_insert(bh_t *bh, uint64_t key, void *value, size_t vlen)
{
binomial_tree_node_t *node = calloc(1, sizeof(binomial_tree_node_t));
if (!node)
return -1;

node->bh = bh;
node->key = key;
node->value = value;
Expand All @@ -276,9 +292,11 @@ bh_insert(bh_t *bh, uint64_t key, void *value, size_t vlen)
TAILQ_REMOVE(&bh->trees, tree, next);
while (tree && tree->num_children == order) {
if (node->key <= tree->key) {
binomial_tree_merge(node, tree);
if (binomial_tree_merge(node, tree) != 0)
return -1;
} else {
binomial_tree_merge(tree, node);
if (binomial_tree_merge(tree, node) != 0)
return -1;
node = tree;
}
order++;
Expand Down Expand Up @@ -492,9 +510,11 @@ bh_t *bh_merge(bh_t *bh1, bh_t *bh2)

if (node) {
if (node->key <= carry->key) {
binomial_tree_merge(node, carry);
if (binomial_tree_merge(node, carry) != 0)
return NULL;
} else {
binomial_tree_merge(carry, node);
if (binomial_tree_merge(carry, node) != 0)
return NULL;
if (node == node1)
node1 = carry;
else
Expand Down Expand Up @@ -550,25 +570,31 @@ bh_t *bh_merge(bh_t *bh1, bh_t *bh2)
// if we are here node1 and node2 have the same order so they
// need to be merged
if (node1->key <= node2->key) {
binomial_tree_merge(node1, node2);
if (binomial_tree_merge(node1, node2) != 0)
return NULL;
if (carry) {
if (node1->key >= carry->key) {
binomial_tree_merge(node1, carry);
if (binomial_tree_merge(node1, carry) != 0)
return NULL;
carry = node1;
} else {
binomial_tree_merge(carry, node1);
if (binomial_tree_merge(carry, node1) != 0)
return NULL;
}
} else {
carry = node1;
}
} else {
binomial_tree_merge(node2, node1);
if (binomial_tree_merge(node2, node1) != 0)
return NULL;
if (carry) {
if (node2->key <= carry->key) {
binomial_tree_merge(node2, carry);
if (binomial_tree_merge(node2, carry) != 0)
return NULL;
carry = node2;
} else {
binomial_tree_merge(carry, node2);
if (binomial_tree_merge(carry, node2) != 0)
return NULL;
}
} else {
carry = node2;
Expand Down
8 changes: 7 additions & 1 deletion src/bh.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ void bh_destroy(bh_t *bh);
* @param vlen The size of the value
* @return 0 if a new node has been inserted successfully;
* -1 otherwise
* @note if -1 is returned it means that no more memory is available
* and the heap has to be considered irremediably corrupted
*/
int bh_insert(bh_t *bh, uint64_t key, void *value, size_t vlen);

Expand Down Expand Up @@ -149,14 +151,18 @@ void bh_decrease_key(bh_t *bh, uint64_t key, int decr);
* @param bh2 A valid pointer to an initialized bh_t structure
* @return A newly created heap which will contain the union of the items
* stored in both the heaps (bh1 and bh2) provided as argument.
* The caller is responsible of disposing the new heap.
* The caller is responsible of disposing the new heap.\n
* NULL is returned in case of error.
* @note if NULL is returned it means there is no more available memory
* and the heap has to be considered irremediably corrupted
* @note Both bh1 and bh2 will be empty once merged in the new returned heap.
* The caller is responsible of disposing both of them if not necessary
* anymore (otherwise further operations on the original heaps are still
* possible)
* @note The two heaps MUST be configured to use the same operational mode
* for them to be merged. If the operational modes differ no merge
* will be attempted and NULL will be returned
*
*/
bh_t *bh_merge(bh_t *bh1, bh_t *bh2);

Expand Down
21 changes: 15 additions & 6 deletions src/iomux.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,12 @@ iomux_schedule(iomux_t *iomux,
timeout->id = (uint64_t)((expire << 8) | (uint8_t)(++iomux->last_timeout_id % 256));

// keep the list sorted in ascending order
bh_insert(iomux->timeouts, timeout->id, timeout, sizeof(iomux_timeout_t));
if (bh_insert(iomux->timeouts, timeout->id, timeout, sizeof(iomux_timeout_t)) != 0) {
fprintf(stderr, "Can't insert a new node in the binomial heap\n");
MUTEX_UNLOCK(iomux);
free(timeout);
return 0;
}
MUTEX_UNLOCK(iomux);
return timeout->id;
}
Expand Down Expand Up @@ -801,10 +806,13 @@ iomux_run_timeouts(iomux_t *iomux)
while (bh_delete_minimum(iomux->timeouts, &timeout_ptr, NULL) == 0) {
timeout = (iomux_timeout_t *)timeout_ptr;
if (timercmp(&now, &timeout->expire_time, <)) {
bh_insert(iomux->timeouts,
timeout->id,
timeout,
sizeof(iomux_timeout_t));
if (bh_insert(iomux->timeouts,
timeout->id,
timeout,
sizeof(iomux_timeout_t)) != 0)
{
fprintf(stderr, "%s: Can't insert a new node in the binomial heap\n", __FUNCTION__);
}
break;
}
// run expired timeouts
Expand Down Expand Up @@ -1514,7 +1522,8 @@ iomux_binheap_iterator_move_callback(bh_t *bh, uint64_t key, void *value, size_t
iomux_t *dst = (iomux_t *)priv;
iomux_timeout_t *timeout = (iomux_timeout_t *)value;
// XXX - ids might overlap ... they should be recomputed
bh_insert(dst->timeouts, timeout->id, timeout, sizeof(iomux_timeout_t));
if (bh_insert(dst->timeouts, timeout->id, timeout, sizeof(iomux_timeout_t)) != 0)
fprintf(stderr, "%s: Can't insert a new node in the destination binomial heap\n", __FUNCTION__);
return -1;
}

Expand Down

0 comments on commit e157bb1

Please sign in to comment.