mirror of
https://github.com/nginx/nginx.git
synced 2025-01-08 07:03:01 -06:00
rbtree insert procedure
This commit is contained in:
parent
d2ad7cb3d7
commit
8c5f37e7d3
@ -47,53 +47,10 @@ ngx_rbtree_insert(ngx_thread_volatile ngx_rbtree_t *tree,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
tree->insert(*root, node, sentinel);
|
||||||
* 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;
|
|
||||||
|
|
||||||
|
|
||||||
/* re-balance tree */
|
/* re-balance tree */
|
||||||
|
|
||||||
ngx_rbt_red(node);
|
|
||||||
|
|
||||||
while (node != *root && ngx_rbt_is_red(node->parent)) {
|
while (node != *root && ngx_rbt_is_red(node->parent)) {
|
||||||
|
|
||||||
if (node->parent == node->parent->parent->left) {
|
if (node->parent == node->parent->parent->left) {
|
||||||
@ -136,18 +93,60 @@ ngx_rbtree_insert(ngx_thread_volatile ngx_rbtree_t *tree,
|
|||||||
ngx_rbtree_left_rotate(root, sentinel, node->parent->parent);
|
ngx_rbtree_left_rotate(root, sentinel, node->parent->parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_rbt_black(*root);
|
ngx_rbt_black(*root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
void
|
||||||
ngx_rbtree_delete(ngx_thread_volatile ngx_rbtree_t *tree,
|
ngx_rbtree_delete(ngx_thread_volatile ngx_rbtree_t *tree,
|
||||||
ngx_rbtree_node_t *node)
|
ngx_rbtree_node_t *node)
|
||||||
{
|
{
|
||||||
ngx_int_t red;
|
ngx_uint_t red;
|
||||||
ngx_rbtree_node_t **root, *sentinel, *subst, *temp, *w;
|
ngx_rbtree_node_t **root, *sentinel, *subst, *temp, *w;
|
||||||
|
|
||||||
/* a binary tree delete */
|
/* a binary tree delete */
|
||||||
|
@ -23,19 +23,20 @@ struct ngx_rbtree_node_s {
|
|||||||
ngx_rbtree_node_t *left;
|
ngx_rbtree_node_t *left;
|
||||||
ngx_rbtree_node_t *right;
|
ngx_rbtree_node_t *right;
|
||||||
ngx_rbtree_node_t *parent;
|
ngx_rbtree_node_t *parent;
|
||||||
char color;
|
u_char color;
|
||||||
|
u_char data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct ngx_rbtree_s ngx_rbtree_t;
|
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);
|
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
|
||||||
|
|
||||||
struct ngx_rbtree_s {
|
struct ngx_rbtree_s {
|
||||||
ngx_rbtree_node_t *root;
|
ngx_rbtree_node_t *root;
|
||||||
ngx_rbtree_node_t *sentinel;
|
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_volatile ngx_rbtree_t *tree,
|
|||||||
ngx_rbtree_node_t *node);
|
ngx_rbtree_node_t *node);
|
||||||
void ngx_rbtree_delete(ngx_thread_volatile ngx_rbtree_t *tree,
|
void ngx_rbtree_delete(ngx_thread_volatile ngx_rbtree_t *tree,
|
||||||
ngx_rbtree_node_t *node);
|
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 *
|
static ngx_inline ngx_rbtree_node_t *
|
||||||
|
@ -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.root = &ngx_event_timer_sentinel;
|
||||||
ngx_event_timer_rbtree.sentinel = &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)
|
#if (NGX_THREADS)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user