**/
#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
#include <stdlib.h>
#include "utils/avltree/avltree.h"
return r;
} /* c_avl_node_t *c_avl_node_prev */
-static int _remove(c_avl_tree_t *t, c_avl_node_t *n) {
+static void _remove(c_avl_tree_t *t, c_avl_node_t *n) {
assert((t != NULL) && (n != NULL));
if ((n->left != NULL) && (n->right != NULL)) {
} else {
assert(0);
}
-
- return 0;
} /* void *_remove */
/*
int cmp;
if ((new = malloc(sizeof(*new))) == NULL)
- return -1;
+ return ENOMEM;
new->key = key;
new->value = value;
cmp = t->compare(nptr->key, new->key);
if (cmp == 0) {
free_node(new);
- return 1;
+ return EEXIST;
} else if (cmp < 0) {
/* nptr < new */
if (nptr->right == NULL) {
} /* int c_avl_insert */
int c_avl_remove(c_avl_tree_t *t, const void *key, void **rkey, void **rvalue) {
- c_avl_node_t *n;
- int status;
-
- assert(t != NULL);
+ if ((t == NULL) || (key == NULL)) {
+ return EINVAL;
+ }
- n = search(t, key);
+ c_avl_node_t *n = search(t, key);
if (n == NULL)
- return -1;
+ return ENOENT;
if (rkey != NULL)
*rkey = n->key;
if (rvalue != NULL)
*rvalue = n->value;
- status = _remove(t, n);
+ _remove(t, n);
verify_tree(t->root);
--t->size;
- return status;
+ return 0;
} /* void *c_avl_remove */
int c_avl_get(c_avl_tree_t *t, const void *key, void **value) {
n = search(t, key);
if (n == NULL)
- return -1;
+ return ENOENT;
if (value != NULL)
*value = n->value;
}
int c_avl_pick(c_avl_tree_t *t, void **key, void **value) {
- c_avl_node_t *n;
- c_avl_node_t *p;
-
- assert(t != NULL);
+ if ((t == NULL) || ((key == NULL) && (value == NULL))) {
+ return EINVAL;
+ }
- if ((key == NULL) || (value == NULL))
- return -1;
- if (t->root == NULL)
- return -1;
+ if (t->root == NULL) {
+ return EOF;
+ }
- n = t->root;
+ c_avl_node_t *n = t->root;
while ((n->left != NULL) || (n->right != NULL)) {
if (n->left == NULL) {
n = n->right;
n = n->right;
}
- p = n->parent;
+ c_avl_node_t *p = n->parent;
if (p == NULL)
t->root = NULL;
else if (p->left == n)
else
p->right = NULL;
- *key = n->key;
- *value = n->value;
+ if (key != NULL) {
+ *key = n->key;
+ }
+ if (value != NULL) {
+ *value = n->value;
+ }
free_node(n);
--t->size;
c_avl_iterator_t *c_avl_get_iterator(c_avl_tree_t *t) {
c_avl_iterator_t *iter;
- if (t == NULL)
+ if (t == NULL) {
+ errno = EINVAL;
return NULL;
+ }
iter = calloc(1, sizeof(*iter));
if (iter == NULL)
} /* c_avl_iterator_t *c_avl_get_iterator */
int c_avl_iterator_next(c_avl_iterator_t *iter, void **key, void **value) {
- c_avl_node_t *n;
-
- if ((iter == NULL) || (key == NULL) || (value == NULL))
- return -1;
+ if ((iter == NULL) || ((key == NULL) && (value == NULL))) {
+ return EINVAL;
+ }
+ c_avl_node_t *n = NULL;
if (iter->node == NULL) {
for (n = iter->tree->root; n != NULL; n = n->left)
if (n->left == NULL)
n = c_avl_node_next(iter->node);
}
- if (n == NULL)
- return -1;
+ if (n == NULL) {
+ return EOF;
+ }
iter->node = n;
- *key = n->key;
- *value = n->value;
+ if (key != NULL) {
+ *key = n->key;
+ }
+ if (value != NULL) {
+ *value = n->value;
+ }
return 0;
} /* int c_avl_iterator_next */
int c_avl_iterator_prev(c_avl_iterator_t *iter, void **key, void **value) {
- c_avl_node_t *n;
-
- if ((iter == NULL) || (key == NULL) || (value == NULL))
- return -1;
+ if ((iter == NULL) || ((key == NULL) && (value == NULL))) {
+ return EINVAL;
+ }
+ c_avl_node_t *n = NULL;
if (iter->node == NULL) {
for (n = iter->tree->root; n != NULL; n = n->right)
if (n->right == NULL)
n = c_avl_node_prev(iter->node);
}
- if (n == NULL)
- return -1;
+ if (n == NULL) {
+ return EOF;
+ }
iter->node = n;
- *key = n->key;
- *value = n->value;
+ if (key != NULL) {
+ *key = n->key;
+ }
+ if (value != NULL) {
+ *value = n->value;
+ }
return 0;
} /* int c_avl_iterator_prev */
*
* PARAMETERS
* `t' AVL-tree to get the value from.
- * `key' Pointer to a pointer in which to store the key.
- * `value' Pointer to a pointer in which to store the value.
+ * `key' Pointer to a pointer in which to store the key. Either key or
+ * value, but not both, may be NULL.
+ * `value' Pointer to a pointer in which to store the value. Either key or
+ * value, but not both, may be NULL.
*
* RETURN VALUE
- * Zero upon success or non-zero if the tree is empty or key or value is
- * NULL.
+ * Zero upon success. EOF if the tree is empty. EINVAL if t or key are NULL.
*/
int c_avl_pick(c_avl_tree_t *t, void **key, void **value);
c_avl_iterator_t *c_avl_get_iterator(c_avl_tree_t *t);
+
+/* c_avl_iterator_next returns the next key/value in the tree. Either key or
+ * value, but not both, may be NULL. Returns zero on success or EOF if there are
+ * no more nodes in the tree. */
int c_avl_iterator_next(c_avl_iterator_t *iter, void **key, void **value);
+
+/* c_avl_iterator_prev returns the previous key/value in the tree. Either key or
+ * value, but not both, may be NULL. Returns zero on success or EOF if there are
+ * no more nodes in the tree. */
int c_avl_iterator_prev(c_avl_iterator_t *iter, void **key, void **value);
void c_avl_iterator_destroy(c_avl_iterator_t *iter);