jshn: add functionality to read big JSON
[project/libubox.git] / avl.c
diff --git a/avl.c b/avl.c
index bde40b7..8d0bf65 100644 (file)
--- a/avl.c
+++ b/avl.c
 #include "avl.h"
 #include "list.h"
 
-#define list_merge(_head, _list) list_merge(_list, _head)
-#define list_is_last(_head, _list) list_is_last(_list, _head)
-#define list_is_first(_head, _list) list_is_first(_list, _head)
-
 /**
  * internal type save inline function to calculate the maximum of
  * to integers without macro implementation.
@@ -94,7 +90,7 @@ static void avl_remove(struct avl_tree *tree, struct avl_node *node);
 void
 avl_init(struct avl_tree *tree, avl_tree_comp comp, bool allow_dups, void *ptr)
 {
-  list_init_head(&tree->list_head);
+  INIT_LIST_HEAD(&tree->list_head);
   tree->root = NULL;
   tree->count = 0;
   tree->comp = comp;
@@ -102,30 +98,9 @@ avl_init(struct avl_tree *tree, avl_tree_comp comp, bool allow_dups, void *ptr)
   tree->cmp_ptr = ptr;
 }
 
-/**
- * Internal function to support returning the element from a avl tree query
- * @param tree pointer to avl tree
- * @param key pointer to key
- * @param offset offset of node inside the embedded struct
- * @param mode mode of lookup operation (less equal, equal or greater equal)
- * @param pointer to elemen, NULL if no fitting one was found
- */
-void *
-__avl_find_element(struct avl_tree *tree, const void *key, size_t offset, enum avl_find_mode mode) {
-  void *node = NULL;
-
-  switch (mode) {
-    case AVL_FIND_EQUAL:
-      node = avl_find(tree, key);
-      break;
-    case AVL_FIND_LESSEQUAL:
-      node = avl_find_lessequal(tree, key);
-      break;
-    case AVL_FIND_GREATEREQUAL:
-      node = avl_find_greaterequal(tree, key);
-      break;
-  }
-  return node == NULL ? NULL : (((char *)node) - offset);
+static inline struct avl_node *avl_next(struct avl_node *node)
+{
+    return list_entry(node->list.next, struct avl_node, list);
 }
 
 /**
@@ -136,7 +111,7 @@ __avl_find_element(struct avl_tree *tree, const void *key, size_t offset, enum a
  *    this key exists.
  */
 struct avl_node *
-avl_find(struct avl_tree *tree, const void *key)
+avl_find(const struct avl_tree *tree, const void *key)
 {
   struct avl_node *node;
   int diff;
@@ -158,7 +133,7 @@ avl_find(struct avl_tree *tree, const void *key)
  *    key less or equal specified key exists.
  */
 struct avl_node *
-avl_find_lessequal(struct avl_tree *tree, const void *key) {
+avl_find_lessequal(const struct avl_tree *tree, const void *key) {
   struct avl_node *node, *next;
   int diff;
 
@@ -169,7 +144,7 @@ avl_find_lessequal(struct avl_tree *tree, const void *key) {
 
   /* go left as long as key<node.key */
   while (diff < 0) {
-    if (list_is_first(&tree->list_head, &node->list)) {
+    if (list_is_first(&node->list, &tree->list_head)) {
       return NULL;
     }
 
@@ -181,7 +156,7 @@ avl_find_lessequal(struct avl_tree *tree, const void *key) {
   next = node;
   while (diff >= 0) {
     node = next;
-    if (list_is_last(&tree->list_head, &node->list)) {
+    if (list_is_last(&node->list, &tree->list_head)) {
       break;
     }
 
@@ -200,7 +175,7 @@ avl_find_lessequal(struct avl_tree *tree, const void *key) {
  *    key greater or equal specified key exists.
  */
 struct avl_node *
-avl_find_greaterequal(struct avl_tree *tree, const void *key) {
+avl_find_greaterequal(const struct avl_tree *tree, const void *key) {
   struct avl_node *node, *next;
   int diff;
 
@@ -211,7 +186,7 @@ avl_find_greaterequal(struct avl_tree *tree, const void *key) {
 
   /* go right as long as key>node.key */
   while (diff > 0) {
-    if (list_is_last(&tree->list_head, &node->list)) {
+    if (list_is_last(&node->list, &tree->list_head)) {
       return NULL;
     }
 
@@ -223,7 +198,7 @@ avl_find_greaterequal(struct avl_tree *tree, const void *key) {
   next = node;
   while (diff <= 0) {
     node = next;
-    if (list_is_first(&tree->list_head, &node->list)) {
+    if (list_is_first(&node->list, &tree->list_head)) {
       break;
     }
 
@@ -255,7 +230,7 @@ avl_insert(struct avl_tree *tree, struct avl_node *new)
   new->leader = true;
 
   if (tree->root == NULL) {
-    list_add_head(&tree->list_head, &new->list);
+    list_add(&new->list, &tree->list_head);
     tree->root = new;
     tree->count = 1;
     return 0;
@@ -265,8 +240,8 @@ avl_insert(struct avl_tree *tree, struct avl_node *new)
 
   last = node;
 
-  while (!list_is_last(&tree->list_head, &last->list)) {
-    next = list_next_element(last, list);
+  while (!list_is_last(&last->list, &tree->list_head)) {
+    next = avl_next(last);
     if (next->leader) {
       break;
     }
@@ -336,8 +311,8 @@ avl_delete(struct avl_tree *tree, struct avl_node *node)
   struct avl_node *right;
   if (node->leader) {
     if (tree->allow_dups
-        && !list_is_last(&tree->list_head, &node->list)
-        && !(next = list_next_element(node, list))->leader) {
+        && !list_is_last(&node->list, &tree->list_head)
+        && !(next = avl_next(node))->leader) {
       next->leader = true;
       next->balance = node->balance;
 
@@ -514,21 +489,21 @@ post_insert(struct avl_tree *tree, struct avl_node *node)
 static void
 avl_insert_before(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node)
 {
-  list_add_before(&pos_node->list, &node->list);
+  list_add_tail(&node->list, &pos_node->list);
   tree->count++;
 }
 
 static void
 avl_insert_after(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node)
 {
-  list_add_after(&pos_node->list, &node->list);
+  list_add(&node->list, &pos_node->list);
   tree->count++;
 }
 
 static void
 avl_remove(struct avl_tree *tree, struct avl_node *node)
 {
-  list_remove(&node->list);
+  list_del(&node->list);
   tree->count--;
 }