changeset 853:a7c8cbb4c55f

rbtree insert procedure
author Igor Sysoev <igor@sysoev.ru>
date Thu, 16 Nov 2006 15:34:52 +0000
parents 629b5e4f8931
children 1673f197bc62
files src/core/ngx_rbtree.c src/core/ngx_rbtree.h src/event/ngx_event_timer.c
diffstat 3 files changed, 52 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/ngx_rbtree.c
+++ b/src/core/ngx_rbtree.c
@@ -47,53 +47,10 @@ ngx_rbtree_insert(ngx_thread_volatile ng
         return;
     }
 
-    /*
-     * The rbtree is currently used by event timers only.  Timer values
-     * 1) are spread in small range, usually several minutes,
-     * 2) and overflow each 49 days, if milliseconds are stored in 32 bits.
-     * The below comparison takes into account that overflow.
-     *
-     * If there will be a necessity to use the rbtree for values with
-     * other comparison rules, then a whole "for ( ;; )" loop should
-     * be made as tree->insert() function.
-     */
-
-    temp = *root;
-
-    for ( ;; ) {
-
-        /*  node->key < temp->key */
-
-        if ((ngx_rbtree_key_int_t) node->key - (ngx_rbtree_key_int_t) temp->key
-            < 0)
-        {
-            if (temp->left == sentinel) {
-                temp->left = node;
-                break;
-            }
-
-            temp = temp->left;
-            continue;
-        }
-
-        if (temp->right == sentinel) {
-            temp->right = node;
-            break;
-        }
-
-        temp = temp->right;
-        continue;
-    }
-
-    node->parent = temp;
-    node->left = sentinel;
-    node->right = sentinel;
-
+    tree->insert(*root, node, sentinel);
 
     /* re-balance tree */
 
-    ngx_rbt_red(node);
-
     while (node != *root && ngx_rbt_is_red(node->parent)) {
 
         if (node->parent == node->parent->parent->left) {
@@ -136,7 +93,6 @@ ngx_rbtree_insert(ngx_thread_volatile ng
                 ngx_rbtree_left_rotate(root, sentinel, node->parent->parent);
             }
         }
-
     }
 
     ngx_rbt_black(*root);
@@ -144,10 +100,53 @@ ngx_rbtree_insert(ngx_thread_volatile ng
 
 
 void
+ngx_rbtree_insert_timer_value(ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node,
+    ngx_rbtree_node_t *sentinel)
+{
+    for ( ;; ) {
+
+        /*
+         * Timer values
+         * 1) are spread in small range, usually several minutes,
+         * 2) and overflow each 49 days, if milliseconds are stored in 32 bits.
+         * The comparison takes into account that overflow.
+         */
+
+        if ((ngx_rbtree_key_int_t) node->key - (ngx_rbtree_key_int_t) temp->key
+            < 0)
+        {
+            /*  node->key < temp->key */
+
+            if (temp->left == sentinel) {
+                temp->left = node;
+                break;
+            }
+
+            temp = temp->left;
+
+        } else {
+
+            if (temp->right == sentinel) {
+                temp->right = node;
+                break;
+            }
+
+            temp = temp->right;
+        }
+    }
+
+    node->parent = temp;
+    node->left = sentinel;
+    node->right = sentinel;
+    ngx_rbt_red(node);
+}
+
+
+void
 ngx_rbtree_delete(ngx_thread_volatile ngx_rbtree_t *tree,
     ngx_rbtree_node_t *node)
 {
-    ngx_int_t            red;
+    ngx_uint_t           red;
     ngx_rbtree_node_t  **root, *sentinel, *subst, *temp, *w;
 
     /* a binary tree delete */
--- a/src/core/ngx_rbtree.h
+++ b/src/core/ngx_rbtree.h
@@ -23,19 +23,20 @@ struct ngx_rbtree_node_s {
     ngx_rbtree_node_t     *left;
     ngx_rbtree_node_t     *right;
     ngx_rbtree_node_t     *parent;
-    char                   color;
+    u_char                 color;
+    u_char                 data;
 };
 
 
 typedef struct ngx_rbtree_s  ngx_rbtree_t;
 
-typedef ngx_rbtree_node_t *(*ngx_rbtree_insert_pt) (ngx_rbtree_node_t *root,
+typedef void (*ngx_rbtree_insert_pt) (ngx_rbtree_node_t *root,
     ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
 
 struct ngx_rbtree_s {
     ngx_rbtree_node_t     *root;
     ngx_rbtree_node_t     *sentinel;
- /* ngx_rbtree_insert_pt   insert; */
+    ngx_rbtree_insert_pt   insert;
 };
 
 
@@ -43,6 +44,8 @@ void ngx_rbtree_insert(ngx_thread_volati
     ngx_rbtree_node_t *node);
 void ngx_rbtree_delete(ngx_thread_volatile ngx_rbtree_t *tree,
     ngx_rbtree_node_t *node);
+void ngx_rbtree_insert_timer_value(ngx_rbtree_node_t *root,
+    ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
 
 
 static ngx_inline ngx_rbtree_node_t *
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -23,6 +23,7 @@ ngx_event_timer_init(ngx_log_t *log)
 {
     ngx_event_timer_rbtree.root = &ngx_event_timer_sentinel;
     ngx_event_timer_rbtree.sentinel = &ngx_event_timer_sentinel;
+    ngx_event_timer_rbtree.insert = ngx_rbtree_insert_timer_value;
 
 #if (NGX_THREADS)