Nginx source code full annotation (10) ngx_radix_tree

Source: Internet
Author: User
Ngx_radix_tree.h
// Unused node # define ngx_radix_no_value (uintptr_t)-1 typedef struct skip; struct ngx_radix_node_s {ngx_radix_node_t * right; // The root node of the right subtree returns * left; // The left subtree root node ngx_radix_node_t * parent; // parent node uintptr_t value; // Value Field}; typedef struct {ngx_radix_node_t * root; // The root node ngx_pool_t * pool; // The Memory Pool ngx_radix_node_t * free used by the tree; // idle nodes are connected to a linked list starting from free, and char * start; size_t size;} ngx_radix_tree_t is connected to each node through the right pointer;
Ngx_radix_tree.c
Static void * ngx_radix_alloc (decision * tree); returns * ngx_radix_tree_create (ngx_pool_t * Pool, ngx_int_t preallocate) {uint32_t key, mask, Inc; decision * tree; // allocate the memory tree = ngx_palloc (pool, sizeof (ngx_radix_tree_t) for the tree struct); If (tree = NULL) {return NULL ;} // initialize each member tree-> pool = pool; tree-> free = NULL; tree-> Start = NULL; tree-> size = 0; // allocate memory for the root node (In fact, there may not be any re-Memory Allocation Operations. For details, see See section ngx_radix_alloc.) tree-> root = ngx_radix_alloc (tree); If (tree-> root = NULL) {return NULL ;} // initialize tree of the root node-> root-> right = NULL; tree-> root-> left = NULL; tree-> root-> parent = NULL; tree-> root-> value = ngx_radix_no_value; // if the number of pre-allocated nodes is 0, return the tree directly. If (preallocate = 0) {return tree ;} /** preallocation of first nodes: 0, 1, 00, 01, 10, 11,000,001, etc. * increases TLB hits even if First lookup iterations. * On 32-bit platforms the 7 preallocated bits takes continuous 4 K, * 8-8 K, 9-16 K, etc. on 64-bit platforms the 6 preallocated bits * takes continuous 4 K, 7-8 K, 8-16 K, etc. there is no sense to * To preallocate more than one page, because further preallocation * distributes the only bit per page. instead, a random insertion * may distribute several bits per page. * * Thus, by default we preallocate maximum * 6 bits on amd64 (64-bit platform and 4 K pages) * 7 bits on i386 (32-bit platform and 4 K pages) * 7 bits on sparc64 in 64-Bit mode (8 K pages) * 8 bits on sparc64 in 32-Bit mode (8 K pages) * /// the following part is very interesting. You can refer to the above English comments. Simply put, if an X bits value corresponds to its Radix tree // has an x + 1 layer, then the number of nodes is 2 ^ (x + 1) -1 (Data Structure knowledge, you can easily prove this conclusion ). If (preallocate =-1) {// Based on the pagesize, determine how many Radix tree switches can be allocated (ngx_pagesize/sizeof (ngx_radix_tree_t) {/* amd64 */Case 128: preallocate = 6; break;/* i386, sparc64 */case 256: preallocate = 7; break;/* sparc64 in 32-Bit mode */Default: preallocate = 8 ;}} mask = 0; Inc = 0x80000000; // The number of preallocate values. In the end, the maximum number of bits in the mask is 1, and the other value is 0. Throughout the cycle, the mask keeps shifting right and adds a new 1 to the // highest bit. While (preallocate --) {key = 0; mask> = 1; mask | = 0x80000000; do {If (ngx_radix32tree_insert (tree, key, mask, ngx_radix_no_value )! = Ngx_ OK) {return NULL;} key + = Inc;} while (key); INC >>=1;} return tree;} // The mask is the mask, it is used to intercept part of the bit in the key and insert it into the tree number. The corresponding value is pair (ngx_radix_tree_t * tree, uint32_t key, uint32_t mask, uintptr_t value) {uint32_t bit; ngx_radix_node_t * node, * Next; bit = 0x80000000; node = tree-> root; next = tree-> root; while (BIT & Mask) {If (Key & bit) {next = node-> right;} els E {next = node-> left;} // the current node is a leaf node and the IF (next = NULL) {break;} bit >>=1; node = next;} // next is not null, because bit & Mask is 0 to exit the above while if (next) {If (node-> value! = Ngx_radix_no_value) {return ngx_busy;} node-> value = value; return ngx_ OK;} // If next is null, a new node is allocated from the tree while (BIT & Mask) {next = ngx_radix_alloc (tree); If (next = NULL) {return ngx_error;} next-> right = NULL; next-> left = NULL; next-> parent = node; next-> value = ngx_radix_no_value; If (Key & bit) {node-> right = next;} else {node-> left = next ;} bit> = 1; node = next;} node-> Value = Value; return ngx_ OK;} // After the node is deleted from the radix tree, it will be placed in the free linked list (ngx_radix_tree_t * tree, uint32_t key, uint32_t mask) {uint32_t bit; ngx_radix_node_t * node; bit = 0x80000000; node = tree-> root; while (node & (BIT & Mask) {// key this bit is 1, next, find the right subtree if (Key & bit) {node = node-> right; // The Key is 0, indicates that the Left subtree} else {node = node-> left;} bit >>=1;} // The node to be deleted does not exist if (node = N Ull) {return ngx_error;} // If (node-> right | node-> left) {If (node-> value! = Ngx_radix_no_value) {node-> value = ngx_radix_no_value; return ngx_ OK;} // The node to be deleted has a subtree. If the value of this node is invalid, return ngx_error is considered as an error ;} for (;) {// If the node is the right node if (node-> parent-> right = node) {node-> parent-> right = NULL; // If the node is a left node} else {node-> parent-> left = NULL;} node-> right = tree-> free; tree-> free = node; node = node-> parent; If (node-> right | node-> left) {break;} If (node-> value! = Ngx_radix_no_value) {break;} // If (node-> parent = NULL) {break;} return ngx_ OK ;} // search for the key value in the tree. The key is an unsigned 32-bit integer, and each digit starts from the root of the tree. // select the left subtree (0) when searching) or the right subtree (1) contains (ngx_radix_tree_t * tree, uint32_t key) {uint32_t bit; uintptr_t value; ngx_radix_node_t * node; // The highest bit in the initial state is 1, used for the following "and" operation, determine the left and right subtree bit = 0x80000000; value = ngx_radix_no_value; node = tree-> root; // start from the root/ /Theoretically, it can be up to 32 cycles (the key is 32 bits). In fact, if the node is found to be null, it indicates that the previous loop is already a leaf node while (node) {If (node-> value! = Ngx_radix_no_value) {value = node-> value;} // If (Key & bit) {node = node-> right, if (Key & bit; // if this bit is 0, the left subtree} else {node = node-> left;} bit >>=1;} // returns the value of the found node return value ;} static void * ngx_radix_alloc (ngx_radix_tree_t * tree) {char * P, if the free value is not zero, the system returns the free if (tree-> free) {P = (char *) tree-> free; tree-> free = tree-> free-> right; return P ;}/ /It is called when the radix tree is created. Tree-> size is 0, and the IF branch if (tree-> size <sizeof (ngx_radix_node_t) is entered )) {// memory alignment with ngx_pagesize, from the memory pool tree-> pool, allocate the ngx_pagesize memory to start // ngx_pagesize, which is the ngx_ OS _init (in src/OS/Unix/ngx_posix_init.c and src/OS/Win32/ngx_win32_init.c () function. The value of pagesize is related to the processor architecture. Tree-> Start = ngx_pmemalign (tree-> pool, ngx_pagesize, ngx_pagesize); If (tree-> Start = NULL) {return NULL ;} // tree-> size: the size of the allocated memory tree-> size = ngx_pagesize ;} // tree-> Start Plus ngx_radix_node_t size to be occupied // tree-> size minus ngx_radix_node_t size to be occupied P = tree-> Start; tree-> Start + = sizeof (ngx_radix_node_t); tree-> size-= sizeof (ngx_radix_node_t); // although the return value type is void *, however, all calls are converted to ngx_radix_node_t return P ;}

Nginx source code full annotation (10) ngx_radix_tree

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.