]> git.ipfire.org Git - thirdparty/collectd.git/commitdiff
avltree: Return errno values; unify argument handling. 3509/head
authorFlorian Forster <octo@google.com>
Thu, 2 Jul 2020 18:52:05 +0000 (20:52 +0200)
committerFlorian Forster <octo@google.com>
Fri, 17 Jul 2020 09:42:15 +0000 (11:42 +0200)
src/utils/avltree/avltree.c
src/utils/avltree/avltree.h
src/utils/avltree/avltree_test.c

index af6efed95ac32bc89f61ea04ad1f745f2088d59c..728a1309d38632ffdfd96df66f4874b0f8c0caae 100644 (file)
@@ -25,6 +25,8 @@
  **/
 
 #include <assert.h>
+#include <errno.h>
+#include <stdio.h>
 #include <stdlib.h>
 
 #include "utils/avltree/avltree.h"
@@ -324,7 +326,7 @@ static c_avl_node_t *c_avl_node_prev(c_avl_node_t *n) {
   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)) {
@@ -408,8 +410,6 @@ static int _remove(c_avl_tree_t *t, c_avl_node_t *n) {
   } else {
     assert(0);
   }
-
-  return 0;
 } /* void *_remove */
 
 /*
@@ -444,7 +444,7 @@ int c_avl_insert(c_avl_tree_t *t, void *key, void *value) {
   int cmp;
 
   if ((new = malloc(sizeof(*new))) == NULL)
-    return -1;
+    return ENOMEM;
 
   new->key = key;
   new->value = value;
@@ -464,7 +464,7 @@ int c_avl_insert(c_avl_tree_t *t, void *key, void *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) {
@@ -495,24 +495,23 @@ int c_avl_insert(c_avl_tree_t *t, void *key, void *value) {
 } /* 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) {
@@ -522,7 +521,7 @@ 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;
@@ -531,17 +530,15 @@ int c_avl_get(c_avl_tree_t *t, const void *key, void **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;
@@ -557,7 +554,7 @@ int c_avl_pick(c_avl_tree_t *t, void **key, void **value) {
       n = n->right;
   }
 
-  p = n->parent;
+  c_avl_node_t *p = n->parent;
   if (p == NULL)
     t->root = NULL;
   else if (p->left == n)
@@ -565,8 +562,12 @@ int c_avl_pick(c_avl_tree_t *t, void **key, void **value) {
   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;
@@ -578,8 +579,10 @@ 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_t *iter;
 
-  if (t == NULL)
+  if (t == NULL) {
+    errno = EINVAL;
     return NULL;
+  }
 
   iter = calloc(1, sizeof(*iter));
   if (iter == NULL)
@@ -590,11 +593,11 @@ c_avl_iterator_t *c_avl_get_iterator(c_avl_tree_t *t) {
 } /* 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)
@@ -604,22 +607,27 @@ int c_avl_iterator_next(c_avl_iterator_t *iter, void **key, void **value) {
     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)
@@ -629,12 +637,17 @@ int c_avl_iterator_prev(c_avl_iterator_t *iter, void **key, void **value) {
     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 */
index 3f52b9314b70de781ccc787c3da4ebc70dd1ac16..6d49ff7ed6f5de2dd7dde574bab2c907ed51f00e 100644 (file)
@@ -137,17 +137,26 @@ int c_avl_get(c_avl_tree_t *t, const void *key, void **value);
  *
  * 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);
 
index 8cbcb13ce4f2435e33b1ecc59ec039599a59c230..2221dbacc67ab1457d363fd39472a5aaf5446ca3 100644 (file)
@@ -92,7 +92,7 @@ DEF_TEST(success) {
 
   /* Key already exists. */
   for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++)
-    EXPECT_EQ_INT(1, c_avl_insert(t, cases[i].key, cases[i].value));
+    EXPECT_EQ_INT(EEXIST, c_avl_insert(t, cases[i].key, cases[i].value));
 
   /* get */
   for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {