the red and black tree of Nginx
/** Copyright (c) Igor sysoev* Copyright (c) Nginx, inc.*/#ifndef _ngx_rbtree_h_included_#define _ngx_rbtree_h_included_ #include <ngx_config.h> #include <ngx_core.h>typedef ngx_uint_t ngx_rbtree_key_t;typedef ngx_int_t ngx_ rbtree_key_int_t;typedef struct ngx_rbtree_node_s ngx_rbtree_node_t;//red-black tree struct ngx_rbtree_node_s {//unsigned shaped keyword ngx_ rbtree_key_t key;//Left Dial hand node ngx_rbtree_node_t *left;//right child node ngx_rbtree_node_t *right;//parent Node ngx_rbtree_node_t *parent;// The color of the node, 0 for Black, and 1 for the red U_char color;//only 1 bytes of node data. Because the space represented is too small, it is generally seldom used. U_char data;}; typedef struct ngx_rbtree_s ngx_rbtree_t;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 {//points to the root node of the tree. ngx_rbtree_node_t *root;//points to the Nil Sentinel node ngx_rbtree_node_t *sentinel;//represents a function pointer to the red-black tree to add an element, which determines whether the behavior when adding a new node is replaced or new Ngx_rbtree _insert_pt insert;}; #define NGX_RBTREE_INIT (tree, S, i) \ngx_rbtree_sentinel_init (s); \ (tree)->root = s; \ (tree)->sentinel = s; \ (tree)->insert =Ivoid Ngx_rbtree_insert (ngx_thread_volatile ngx_rbtree_t *tree,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_value (ngx_rbtree_node_t *root, ngx_rbtree_node_t *node,ngx_rbtree_node_t *sentinel); void Ngx_rbtree_insert_timer_value (ngx_rbtree_node_t *root, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); #define NGX_RBT_RED (node)->color = 1) #define Ngx_rbt_ Black (node) (node)->color = 0) #define NGX_RBT_IS_RED (node)->color #define NGX_RBT_IS_BLACK (node) (!NGX _rbt_is_red (node)) #define NGX_RBT_COPY_COLOR (N1, n2) (N1->color = n2->color)/* A Sentinel must be black */#define NG X_rbtree_sentinel_init (node) ngx_rbt_black (node) static ngx_inline ngx_rbtree_node_t *ngx_rbtree_min (ngx_rbtree_ node_t *node, ngx_rbtree_node_t *sentinel) {while (Node->left! = Sentinel) {node = Node->left;} return node;} #endif/* _ngx_rbtree_h_included_ *//** Copyright (C) Igor sysoev* Copyright (C) Nginx, inc.*/#include <ngx_config.h> #include <ngx_core.h>/** the Red-black tree code is based on the Algori tHM described in* the ' Introduction to Algorithms ' by Cormen, Leiserson and rivest.*/static ngx_inline void Ngx_rbtree_lef T_rotate (ngx_rbtree_node_t **root,ngx_rbtree_node_t *sentinel, ngx_rbtree_node_t *node); static ngx_inline void Ngx_ Rbtree_right_rotate (ngx_rbtree_node_t **root,ngx_rbtree_node_t *sentinel, ngx_rbtree_node_t *node); void Ngx_rbtree_ Insert (ngx_thread_volatile ngx_rbtree_t *tree,ngx_rbtree_node_t *node) {ngx_rbtree_node_t **root, *temp, *sentinel;/* A binary tree Insert */root = (ngx_rbtree_node_t * *) &tree->root;sentinel = tree->sentinel;if (*root = = Sentinel {//empty tree Node->parent = Null;node->left = Sentinel;node->right = sentinel;ngx_rbt_black (node); *root = node; return;} Tree->insert (*root, node, sentinel);/* re-balance Tree */while (node! = *root && ngx_rbt_is_red (node-> Parent) {if (node->parent = = Node->parenT->parent->left) {temp = node->parent->parent->right;if (ngx_rbt_is_red (temp)) {Ngx_rbt_black (node- >parent); Ngx_rbt_black (temp); ngx_rbt_red (node->parent->parent); node = node->parent->parent;} else {if (node = = node->parent->right) {node = node->parent;ngx_rbtree_left_rotate (root, Sentinel, node);} Ngx_rbt_black (node->parent); ngx_rbt_red (node->parent->parent); Ngx_rbtree_right_rotate (Root, Sentinel, node->parent->parent);}} else {temp = node->parent->parent->left;if (ngx_rbt_is_red (temp)) {ngx_rbt_black (node->parent); ngx_rbt_ Black (temp); ngx_rbt_red (node->parent->parent); node = node->parent->parent;} else {if (node = = Node->parent->left) {node = node->parent;ngx_rbtree_right_rotate (root, Sentinel, node);} Ngx_rbt_black (node->parent); ngx_rbt_red (node->parent->parent); Ngx_rbtree_left_rotate (Root, Sentinel, node->parent->parent);}}} Ngx_rbt_black (*root);} void Ngx_rbtree_insert_value (Ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node,ngx_rbtree_node_t *sentinel) {ngx_rbtree_node_t **p;for (;;) {p = (Node->key < Temp->key)? &temp->left: &temp->right;if (*p = Sentinel) {break;} temp = *p;} *p = Node;node->parent = Temp;node->left = Sentinel;node->right = sentinel;ngx_rbt_red (node);} void Ngx_rbtree_insert_timer_value (ngx_rbtree_node_t *temp,ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) { ngx_rbtree_node_t **p;for (;;) {/** Timer values* 1) is spread in small range, usually several minutes,* 2) and overflow each, if milliseconds a Re stored in bits.* the comparison takes to account that overflow.*//* Node->key < Temp->key */p = ((NGX_RBT ree_key_int_t) Node->key-(ngx_rbtree_key_int_t) temp->key< 0)? &temp->left: &temp->right;if (*p = = Sentinel) {break;} temp = *p;} *p = Node;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_uint_t red;ngx_rbtree_node_t **root, *sentinel, *subst, * Temp, *w;/* a binary tree Delete */root = (ngx_rbtree_node_t * *) &tree->root;sentinel = tree->sentinel;//find y and X nodes if (Node->left = = Sentinel) {temp = NODE->RIGHT;SUBST = node;} else if (node->right = = Sentinel) {temp = Node-> ; left;subst = node;} else {subst = Ngx_rbtree_min (node->right, Sentinel), if (subst->left! = Sentinel) {temp = Subst->left;} else {Temp = Subst->right;}} The Y node is the root node if (subst = = *root) {*root = Temp;ngx_rbt_black (temp);/* DEBUG stuff */node->left = Null;node->right = N Ull;node->parent = Null;node->key = 0;return;} Red = ngx_rbt_is_red (subst);//Record Y-node color//y Parent child node if (subst = = subst->parent->left) {Subst->parent->left = temp;} else {subst->parent->right = temp;} Y Child's parent node if (subst = = node) {//Only one child node temp->parent = subst->parent;} else {if (subst->parent = = node) {temp-> Parent = Subst;} else {temp->parent = subst->parent;} Y-node Copy z-node Property subst->left = Node->left;subst->right = Node->right;subst->parent = Node->parent;ngx _rbt_copy_color (subst, node), if (node = = *root) {*root = subst;} else {//delete node's parent node's child node if (node = = Node->parent->left ) {node->parent->left = subst;} else {node->parent->right = subst;}} The parent node of the Y node if (subst->left! = Sentinel) {subst->left->parent = subst;} if (subst->right! = Sentinel) {subst->right->parent = subst;}} /* DEBUG Stuff */node->left = Null;node->right = Null;node->parent = Null;node->key = 0;if (red) {return;} /* A delete fixup */while (temp! = *root && ngx_rbt_is_black (temp)) {if (temp = = Temp->parent->left) {w = te Mp->parent->right;if (ngx_rbt_is_red (w)) {ngx_rbt_black (w); ngx_rbt_red (temp->parent); Ngx_rbtree_left_ Rotate (Root, Sentinel, temp->parent); w = temp->parent->right;} if (Ngx_rbt_is_black (w->left) && Ngx_rbt_is_black (w->(right)) {ngx_rbt_red (w); temp = temp->parent;} else {if (Ngx_rbt_is_black (w->right)) {Ngx_rbt_black (W->left) ; ngx_rbt_red (w); Ngx_rbtree_right_rotate (Root, Sentinel, W); w = temp->parent->right;} Ngx_rbt_copy_color (w, temp->parent); Ngx_rbt_black (temp->parent); Ngx_rbt_black (w->right); ngx_rbtree_ Left_rotate (Root, Sentinel, temp->parent); temp = *root;}} else {w = temp->parent->left;if (ngx_rbt_is_red (w)) {ngx_rbt_black (w); ngx_rbt_red (temp->parent); ngx_rbtree _right_rotate (Root, Sentinel, temp->parent); w = temp->parent->left;} if (Ngx_rbt_is_black (w->left) && ngx_rbt_is_black (w->right)) {ngx_rbt_red (w); temp = temp->parent;} else {if (Ngx_rbt_is_black (W->left)) {ngx_rbt_black (w->right); ngx_rbt_red (w); Ngx_rbtree_left_rotate (Root, Sentinel, W); w = temp->parent->left;} Ngx_rbt_copy_color (w, temp->parent); Ngx_rbt_black (temp->parent); Ngx_rbt_black (w->left); ngx_rbtree_ Right_rotate (Root, Sentinel, temp->parent); temp = *root;}}} Ngx_rbt_black (temp);} static ngx_inline void Ngx_rbtree_left_rotate (ngx_rbtree_node_t **root,ngx_rbtree_node_t *sentinel, Ngx_rbtree_node_ T *node) {ngx_rbtree_node_t *temp;//1, set node ytemp = NODE->RIGHT;//2, leave Y's left subtree as the right subtree of x node->right = Temp->left;if ( Temp->left! = Sentinel) {temp->left->parent = node;} 3, link y and x parent node temp->parent = node->parent;if (node = = *root) {*root = temp;} else if (node = = Node->parent->lef T) {node->parent->left = temp;} else {node->parent->right = temp;} 4, x as the left subtree of y temp->left = Node;node->parent = temp;} static ngx_inline void Ngx_rbtree_right_rotate (ngx_rbtree_node_t **root,ngx_rbtree_node_t *sentinel, Ngx_rbtree_node _t *node) {ngx_rbtree_node_t *temp;temp = Node->left;node->left = Temp->right;if (temp->right! = Sentinel) {T emp->right->parent = node;} Temp->parent = node->parent;if (node = = *root) {*root = temp;} else if (node = = node->parent->right) {Node-> ;p arent->right = temp;} ELSE {node->parent->left = temp;} Temp->right = Node;node->parent = temp;}
Above is nginx red black tree content, more relevant content please pay attention to topic.alibabacloud.com (www.php.cn)!