int binheap_delete(binheap_t *bh, void *key, size_t klen, void **value) { binomial_tree_node_t *tree = NULL; int i; for (i = 0; i < list_count(bh->trees); i++) { binomial_tree_node_t *cur_tree = list_pick_value(bh->trees, i); if (HAS_PRECEDENCE(bh, cur_tree->key, cur_tree->klen, key, klen)) { if (tree) { if (HAS_PRECEDENCE(bh, tree->key, tree->klen, cur_tree->key, cur_tree->klen)) { tree = cur_tree; } } else { tree = cur_tree; } } } binomial_tree_node_t *to_delete = tree; while(to_delete && bh->cbs->cmp(to_delete->key, to_delete->klen, key, klen) != 0) { binomial_tree_node_t *next_tree = NULL; for (i = 0; i < to_delete->num_children; i++) { binomial_tree_node_t *child = to_delete->children[i]; if (HAS_PRECEDENCE(bh, child->key, child->klen, key, klen)) { if (next_tree) { if (HAS_PRECEDENCE(bh, next_tree->key, next_tree->klen, child->key, child->klen)) { next_tree = child; } } else { next_tree = child; } } } if (next_tree) { to_delete = next_tree; } else { to_delete = NULL; } } if (to_delete) { if (value) *value = to_delete->value; binomial_tree_node_destroy(to_delete, 0); return 0; } return -1; }
void binheap_destroy(binheap_t *bh) { binomial_tree_node_t *node = (bh->mode == BINHEAP_MODE_MIN) ? binheap_get_minimum(bh, NULL) : binheap_get_maximum(bh, NULL); while (node) { binomial_tree_node_destroy(node, 0); node = (bh->mode == BINHEAP_MODE_MIN) ? binheap_get_minimum(bh, NULL) : binheap_get_maximum(bh, NULL); } list_destroy(bh->trees); free(bh); }
int binheap_delete_maximum(binheap_t *bh, void **value) { uint32_t maxidx = 0; binomial_tree_node_t *maxitem = binheap_get_maximum(bh, &maxidx); if (!maxitem) return -1; if (value) *value = maxitem->value; binomial_tree_node_destroy(maxitem, maxidx); return 0; }
int binheap_delete_minimum(binheap_t *bh, void **value) { size_t minidx = 0; binomial_tree_node_t *minitem = binheap_get_minimum(bh, &minidx); if (!minitem) return -1; if (value) *value = minitem->value; binomial_tree_node_destroy(minitem, minidx); return 0; }
static int binomial_tree_walk(binomial_tree_node_t *node, int *count, binheap_walk_callback_t cb, void *priv) { int proceed = 0; int remove = 0; (*count)++; int rc = cb(node->bh, node->key, node->klen, node->value, priv); switch(rc) { case -2: proceed = 0; remove = 1; break; case -1: proceed = 1; remove = 1; break; case 0: proceed = 0; remove = 0; break; case 1: proceed = 1; remove = 0; break; default: // TODO - Warning messages? (the callback returned an invalid return code) break; } if (proceed) { int i; for (i = 0; i < node->num_children; i ++) { binomial_tree_node_t *child = node->children[i]; proceed = binomial_tree_walk(child, count, cb, priv); if (!proceed) break; } } if (remove) { binomial_tree_node_destroy(node, 0); } return proceed; }