]> git.kaiwu.me - nginx.git/commitdiff
remove parent from radix tree node to add skip field
authorIgor Sysoev <igor@sysoev.ru>
Wed, 3 Dec 2008 13:23:07 +0000 (13:23 +0000)
committerIgor Sysoev <igor@sysoev.ru>
Wed, 3 Dec 2008 13:23:07 +0000 (13:23 +0000)
src/core/ngx_radix_tree.c
src/core/ngx_radix_tree.h

index f339e6fab7687334befd35dac9271cf5c39dd59a..9a368ca1a01a1b191bb5219d149d8bfa2409fc19 100644 (file)
@@ -8,6 +8,8 @@
 #include <ngx_core.h>
 
 
+static ngx_int_t ngx_radix32tree_delete_node(ngx_radix_tree_t *tree,
+    uint32_t key, uint32_t mask, ngx_radix_node_t **pnode, uint32_t bit);
 static void *ngx_radix_alloc(ngx_radix_tree_t *tree);
 
 
@@ -34,7 +36,7 @@ ngx_radix_tree_create(ngx_pool_t *pool, ngx_int_t preallocate)
 
     tree->root->right = NULL;
     tree->root->left = NULL;
-    tree->root->parent = NULL;
+    tree->root->skip = 0;
     tree->root->value = NGX_RADIX_NO_VALUE;
 
     if (preallocate == 0) {
@@ -149,7 +151,7 @@ ngx_radix32tree_insert(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask,
 
         next->right = NULL;
         next->left = NULL;
-        next->parent = node;
+        next->skip = 0;
         next->value = NGX_RADIX_NO_VALUE;
 
         if (key & bit) {
@@ -172,62 +174,65 @@ ngx_radix32tree_insert(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask,
 ngx_int_t
 ngx_radix32tree_delete(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask)
 {
-    uint32_t           bit;
-    ngx_radix_node_t  *node;
+    return ngx_radix32tree_delete_node(tree, key, mask, &tree->root,
+                                       0x80000000);
+}
 
-    bit = 0x80000000;
-    node = tree->root;
 
-    while (node && (bit & mask)) {
-        if (key & bit) {
-            node = node->right;
-
-        } else {
-            node = node->left;
-        }
+static ngx_int_t
+ngx_radix32tree_delete_node(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask,
+    ngx_radix_node_t **pnode, uint32_t bit)
+{
+    ngx_radix_node_t  *node;
 
-        bit >>= 1;
-    }
+    node = *pnode;
 
     if (node == NULL) {
         return NGX_ERROR;
     }
 
-    if (node->right || node->left) {
-        if (node->value != NGX_RADIX_NO_VALUE) {
-            node->value = NGX_RADIX_NO_VALUE;
-            return NGX_OK;
-        }
+    if ((bit & mask) == 0) {
 
-        return NGX_ERROR;
-    }
+        if (node->right || node->left) {
+
+            if (node->value != NGX_RADIX_NO_VALUE) {
+                node->value = NGX_RADIX_NO_VALUE;
+                return NGX_OK;
+            }
 
-    for ( ;; ) {
-        if (node->parent->right == node) {
-            node->parent->right = NULL;
+            return NGX_ERROR;
 
         } else {
-            node->parent->left = NULL;
-        }
+            node->right = tree->free;
+            tree->free = node;
 
-        node->right = tree->free;
-        tree->free = node;
+            *pnode = NULL;
+        }
 
-        node = node->parent;
+        return NGX_OK;
+    }
 
-        if (node->right || node->left) {
-            break;
-        }
+    if (ngx_radix32tree_delete_node(tree, key, mask,
+                                    (key & bit) ? &node->right : &node->left,
+                                    bit >> 1)
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
 
-        if (node->value != NGX_RADIX_NO_VALUE) {
-            break;
-        }
+    if (node->right || node->left) {
+        return NGX_OK;
+    }
 
-        if (node->parent == NULL) {
-            break;
-        }
+    if (node->value != NGX_RADIX_NO_VALUE) {
+        return NGX_OK;
     }
 
+    node->right = tree->free;
+    tree->free = node;
+
+    *pnode = NULL;
+
     return NGX_OK;
 }
 
index 02a9f383b7e83f1b21e41c20869ac2ce1d96a5ac..c5bdd9875c49af4786c506cc4c92d87a5e98ac7a 100644 (file)
@@ -19,7 +19,7 @@ typedef struct ngx_radix_node_s  ngx_radix_node_t;
 struct ngx_radix_node_s {
     ngx_radix_node_t  *right;
     ngx_radix_node_t  *left;
-    ngx_radix_node_t  *parent;
+    ngx_uint_t         skip;
     uintptr_t          value;
 };