Merge pull request #3339 from jkohen/patch-1
[collectd.git] / src / daemon / utils_avltree.c
diff --git a/src/daemon/utils_avltree.c b/src/daemon/utils_avltree.c
deleted file mode 100644 (file)
index 92259ae..0000000
+++ /dev/null
@@ -1,646 +0,0 @@
-/**
- * collectd - src/utils_avltree.c
- * Copyright (C) 2006,2007  Florian octo Forster
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *   Florian octo Forster <octo at collectd.org>
- **/
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include "utils_avltree.h"
-
-#define BALANCE(n)                                                             \
-  ((((n)->left == NULL) ? 0 : (n)->left->height) -                             \
-   (((n)->right == NULL) ? 0 : (n)->right->height))
-
-/*
- * private data types
- */
-struct c_avl_node_s {
-  void *key;
-  void *value;
-
-  int height;
-  struct c_avl_node_s *left;
-  struct c_avl_node_s *right;
-  struct c_avl_node_s *parent;
-};
-typedef struct c_avl_node_s c_avl_node_t;
-
-struct c_avl_tree_s {
-  c_avl_node_t *root;
-  int (*compare)(const void *, const void *);
-  int size;
-};
-
-struct c_avl_iterator_s {
-  c_avl_tree_t *tree;
-  c_avl_node_t *node;
-};
-
-/*
- * private functions
- */
-#if 0
-static void verify_tree (c_avl_node_t *n)
-{
-       if (n == NULL)
-               return;
-
-       verify_tree (n->left);
-       verify_tree (n->right);
-
-       assert ((BALANCE (n) >= -1) && (BALANCE (n) <= 1));
-       assert ((n->parent == NULL) || (n->parent->right == n) || (n->parent->left == n));
-} /* void verify_tree */
-#else
-#define verify_tree(n) /**/
-#endif
-
-static void free_node(c_avl_node_t *n) {
-  if (n == NULL)
-    return;
-
-  if (n->left != NULL)
-    free_node(n->left);
-  if (n->right != NULL)
-    free_node(n->right);
-
-  free(n);
-}
-
-static int calc_height(c_avl_node_t *n) {
-  int height_left;
-  int height_right;
-
-  if (n == NULL)
-    return (0);
-
-  height_left = (n->left == NULL) ? 0 : n->left->height;
-  height_right = (n->right == NULL) ? 0 : n->right->height;
-
-  return (((height_left > height_right) ? height_left : height_right) + 1);
-} /* int calc_height */
-
-static c_avl_node_t *search(c_avl_tree_t *t, const void *key) {
-  c_avl_node_t *n;
-  int cmp;
-
-  n = t->root;
-  while (n != NULL) {
-    cmp = t->compare(key, n->key);
-    if (cmp == 0)
-      return (n);
-    else if (cmp < 0)
-      n = n->left;
-    else
-      n = n->right;
-  }
-
-  return (NULL);
-}
-
-/*         (x)             (y)
- *        /   \           /   \
- *     (y)    /\         /\    (x)
- *    /   \  /_c\  ==>  / a\  /   \
- *   /\   /\           /____\/\   /\
- *  / a\ /_b\               /_b\ /_c\
- * /____\
- */
-static c_avl_node_t *rotate_right(c_avl_tree_t *t, c_avl_node_t *x) {
-  c_avl_node_t *p;
-  c_avl_node_t *y;
-  c_avl_node_t *b;
-
-  assert(x != NULL);
-  assert(x->left != NULL);
-
-  p = x->parent;
-  y = x->left;
-  b = y->right;
-
-  x->left = b;
-  if (b != NULL)
-    b->parent = x;
-
-  x->parent = y;
-  y->right = x;
-
-  y->parent = p;
-  assert((p == NULL) || (p->left == x) || (p->right == x));
-  if (p == NULL)
-    t->root = y;
-  else if (p->left == x)
-    p->left = y;
-  else
-    p->right = y;
-
-  x->height = calc_height(x);
-  y->height = calc_height(y);
-
-  return (y);
-} /* void rotate_right */
-
-/*
- *    (x)                   (y)
- *   /   \                 /   \
- *  /\    (y)           (x)    /\
- * /_a\  /   \   ==>   /   \  / c\
- *      /\   /\       /\   /\/____\
- *     /_b\ / c\     /_a\ /_b\
- *         /____\
- */
-static c_avl_node_t *rotate_left(c_avl_tree_t *t, c_avl_node_t *x) {
-  c_avl_node_t *p;
-  c_avl_node_t *y;
-  c_avl_node_t *b;
-
-  assert(x != NULL);
-  assert(x->right != NULL);
-
-  p = x->parent;
-  y = x->right;
-  b = y->left;
-
-  x->right = b;
-  if (b != NULL)
-    b->parent = x;
-
-  x->parent = y;
-  y->left = x;
-
-  y->parent = p;
-  assert((p == NULL) || (p->left == x) || (p->right == x));
-  if (p == NULL)
-    t->root = y;
-  else if (p->left == x)
-    p->left = y;
-  else
-    p->right = y;
-
-  x->height = calc_height(x);
-  y->height = calc_height(y);
-
-  return (y);
-} /* void rotate_left */
-
-static c_avl_node_t *rotate_left_right(c_avl_tree_t *t, c_avl_node_t *x) {
-  rotate_left(t, x->left);
-  return (rotate_right(t, x));
-} /* void rotate_left_right */
-
-static c_avl_node_t *rotate_right_left(c_avl_tree_t *t, c_avl_node_t *x) {
-  rotate_right(t, x->right);
-  return (rotate_left(t, x));
-} /* void rotate_right_left */
-
-static void rebalance(c_avl_tree_t *t, c_avl_node_t *n) {
-  int b_top;
-  int b_bottom;
-
-  while (n != NULL) {
-    b_top = BALANCE(n);
-    assert((b_top >= -2) && (b_top <= 2));
-
-    if (b_top == -2) {
-      assert(n->right != NULL);
-      b_bottom = BALANCE(n->right);
-      assert((b_bottom >= -1) && (b_bottom <= 1));
-      if (b_bottom == 1)
-        n = rotate_right_left(t, n);
-      else
-        n = rotate_left(t, n);
-    } else if (b_top == 2) {
-      assert(n->left != NULL);
-      b_bottom = BALANCE(n->left);
-      assert((b_bottom >= -1) && (b_bottom <= 1));
-      if (b_bottom == -1)
-        n = rotate_left_right(t, n);
-      else
-        n = rotate_right(t, n);
-    } else {
-      int height = calc_height(n);
-      if (height == n->height)
-        break;
-      n->height = height;
-    }
-
-    assert(n->height == calc_height(n));
-
-    n = n->parent;
-  } /* while (n != NULL) */
-} /* void rebalance */
-
-static c_avl_node_t *c_avl_node_next(c_avl_node_t *n) {
-  c_avl_node_t *r; /* return node */
-
-  if (n == NULL) {
-    return (NULL);
-  }
-
-  /* If we can't descent any further, we have to backtrack to the first
-   * parent that's bigger than we, i. e. who's _left_ child we are. */
-  if (n->right == NULL) {
-    r = n->parent;
-    while ((r != NULL) && (r->parent != NULL)) {
-      if (r->left == n)
-        break;
-      n = r;
-      r = n->parent;
-    }
-
-    /* n->right == NULL && r == NULL => t is root and has no next
-     * r->left != n => r->right = n => r->parent == NULL */
-    if ((r == NULL) || (r->left != n)) {
-      assert((r == NULL) || (r->parent == NULL));
-      return (NULL);
-    } else {
-      assert(r->left == n);
-      return (r);
-    }
-  } else {
-    r = n->right;
-    while (r->left != NULL)
-      r = r->left;
-  }
-
-  return (r);
-} /* c_avl_node_t *c_avl_node_next */
-
-static c_avl_node_t *c_avl_node_prev(c_avl_node_t *n) {
-  c_avl_node_t *r; /* return node */
-
-  if (n == NULL) {
-    return (NULL);
-  }
-
-  /* If we can't descent any further, we have to backtrack to the first
-   * parent that's smaller than we, i. e. who's _right_ child we are. */
-  if (n->left == NULL) {
-    r = n->parent;
-    while ((r != NULL) && (r->parent != NULL)) {
-      if (r->right == n)
-        break;
-      n = r;
-      r = n->parent;
-    }
-
-    /* n->left == NULL && r == NULL => t is root and has no next
-     * r->right != n => r->left = n => r->parent == NULL */
-    if ((r == NULL) || (r->right != n)) {
-      assert((r == NULL) || (r->parent == NULL));
-      return (NULL);
-    } else {
-      assert(r->right == n);
-      return (r);
-    }
-  } else {
-    r = n->left;
-    while (r->right != NULL)
-      r = r->right;
-  }
-
-  return (r);
-} /* c_avl_node_t *c_avl_node_prev */
-
-static int _remove(c_avl_tree_t *t, c_avl_node_t *n) {
-  assert((t != NULL) && (n != NULL));
-
-  if ((n->left != NULL) && (n->right != NULL)) {
-    c_avl_node_t *r;    /* replacement node */
-    if (BALANCE(n) > 0) /* left subtree is higher */
-    {
-      assert(n->left != NULL);
-      r = c_avl_node_prev(n);
-
-    } else /* right subtree is higher */
-    {
-      assert(n->right != NULL);
-      r = c_avl_node_next(n);
-    }
-
-    assert((r->left == NULL) || (r->right == NULL));
-
-    /* copy content */
-    n->key = r->key;
-    n->value = r->value;
-
-    n = r;
-  }
-
-  assert((n->left == NULL) || (n->right == NULL));
-
-  if ((n->left == NULL) && (n->right == NULL)) {
-    /* Deleting a leave is easy */
-    if (n->parent == NULL) {
-      assert(t->root == n);
-      t->root = NULL;
-    } else {
-      assert((n->parent->left == n) || (n->parent->right == n));
-      if (n->parent->left == n)
-        n->parent->left = NULL;
-      else
-        n->parent->right = NULL;
-
-      rebalance(t, n->parent);
-    }
-
-    free_node(n);
-  } else if (n->left == NULL) {
-    assert(BALANCE(n) == -1);
-    assert((n->parent == NULL) || (n->parent->left == n) ||
-           (n->parent->right == n));
-    if (n->parent == NULL) {
-      assert(t->root == n);
-      t->root = n->right;
-    } else if (n->parent->left == n) {
-      n->parent->left = n->right;
-    } else {
-      n->parent->right = n->right;
-    }
-    n->right->parent = n->parent;
-
-    if (n->parent != NULL)
-      rebalance(t, n->parent);
-
-    n->right = NULL;
-    free_node(n);
-  } else if (n->right == NULL) {
-    assert(BALANCE(n) == 1);
-    assert((n->parent == NULL) || (n->parent->left == n) ||
-           (n->parent->right == n));
-    if (n->parent == NULL) {
-      assert(t->root == n);
-      t->root = n->left;
-    } else if (n->parent->left == n) {
-      n->parent->left = n->left;
-    } else {
-      n->parent->right = n->left;
-    }
-    n->left->parent = n->parent;
-
-    if (n->parent != NULL)
-      rebalance(t, n->parent);
-
-    n->left = NULL;
-    free_node(n);
-  } else {
-    assert(0);
-  }
-
-  return (0);
-} /* void *_remove */
-
-/*
- * public functions
- */
-c_avl_tree_t *c_avl_create(int (*compare)(const void *, const void *)) {
-  c_avl_tree_t *t;
-
-  if (compare == NULL)
-    return (NULL);
-
-  if ((t = malloc(sizeof(*t))) == NULL)
-    return (NULL);
-
-  t->root = NULL;
-  t->compare = compare;
-  t->size = 0;
-
-  return (t);
-}
-
-void c_avl_destroy(c_avl_tree_t *t) {
-  if (t == NULL)
-    return;
-  free_node(t->root);
-  free(t);
-}
-
-int c_avl_insert(c_avl_tree_t *t, void *key, void *value) {
-  c_avl_node_t *new;
-  c_avl_node_t *nptr;
-  int cmp;
-
-  if ((new = malloc(sizeof(*new))) == NULL)
-    return (-1);
-
-  new->key = key;
-  new->value = value;
-  new->height = 1;
-  new->left = NULL;
-  new->right = NULL;
-
-  if (t->root == NULL) {
-    new->parent = NULL;
-    t->root = new;
-    t->size = 1;
-    return (0);
-  }
-
-  nptr = t->root;
-  while (42) {
-    cmp = t->compare(nptr->key, new->key);
-    if (cmp == 0) {
-      free_node(new);
-      return (1);
-    } else if (cmp < 0) {
-      /* nptr < new */
-      if (nptr->right == NULL) {
-        nptr->right = new;
-        new->parent = nptr;
-        rebalance(t, nptr);
-        break;
-      } else {
-        nptr = nptr->right;
-      }
-    } else /* if (cmp > 0) */
-    {
-      /* nptr > new */
-      if (nptr->left == NULL) {
-        nptr->left = new;
-        new->parent = nptr;
-        rebalance(t, nptr);
-        break;
-      } else {
-        nptr = nptr->left;
-      }
-    }
-  } /* while (42) */
-
-  verify_tree(t->root);
-  ++t->size;
-  return (0);
-} /* 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);
-
-  n = search(t, key);
-  if (n == NULL)
-    return (-1);
-
-  if (rkey != NULL)
-    *rkey = n->key;
-  if (rvalue != NULL)
-    *rvalue = n->value;
-
-  status = _remove(t, n);
-  verify_tree(t->root);
-  --t->size;
-  return (status);
-} /* void *c_avl_remove */
-
-int c_avl_get(c_avl_tree_t *t, const void *key, void **value) {
-  c_avl_node_t *n;
-
-  assert(t != NULL);
-
-  n = search(t, key);
-  if (n == NULL)
-    return (-1);
-
-  if (value != NULL)
-    *value = n->value;
-
-  return (0);
-}
-
-int c_avl_pick(c_avl_tree_t *t, void **key, void **value) {
-  c_avl_node_t *n;
-  c_avl_node_t *p;
-
-  if ((key == NULL) || (value == NULL))
-    return (-1);
-  if (t->root == NULL)
-    return (-1);
-
-  n = t->root;
-  while ((n->left != NULL) || (n->right != NULL)) {
-    if (n->left == NULL) {
-      n = n->right;
-      continue;
-    } else if (n->right == NULL) {
-      n = n->left;
-      continue;
-    }
-
-    if (n->left->height > n->right->height)
-      n = n->left;
-    else
-      n = n->right;
-  }
-
-  p = n->parent;
-  if (p == NULL)
-    t->root = NULL;
-  else if (p->left == n)
-    p->left = NULL;
-  else
-    p->right = NULL;
-
-  *key = n->key;
-  *value = n->value;
-
-  free_node(n);
-  --t->size;
-  rebalance(t, p);
-
-  return (0);
-} /* int c_avl_pick */
-
-c_avl_iterator_t *c_avl_get_iterator(c_avl_tree_t *t) {
-  c_avl_iterator_t *iter;
-
-  if (t == NULL)
-    return (NULL);
-
-  iter = calloc(1, sizeof(*iter));
-  if (iter == NULL)
-    return (NULL);
-  iter->tree = t;
-
-  return (iter);
-} /* 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->node == NULL) {
-    for (n = iter->tree->root; n != NULL; n = n->left)
-      if (n->left == NULL)
-        break;
-    iter->node = n;
-  } else {
-    n = c_avl_node_next(iter->node);
-  }
-
-  if (n == NULL)
-    return (-1);
-
-  iter->node = n;
-  *key = n->key;
-  *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->node == NULL) {
-    for (n = iter->tree->root; n != NULL; n = n->left)
-      if (n->right == NULL)
-        break;
-    iter->node = n;
-  } else {
-    n = c_avl_node_prev(iter->node);
-  }
-
-  if (n == NULL)
-    return (-1);
-
-  iter->node = n;
-  *key = n->key;
-  *value = n->value;
-
-  return (0);
-} /* int c_avl_iterator_prev */
-
-void c_avl_iterator_destroy(c_avl_iterator_t *iter) { free(iter); }
-
-int c_avl_size(c_avl_tree_t *t) {
-  if (t == NULL)
-    return (0);
-  return (t->size);
-}