: This article mainly introduces nginx advanced data structure Source Code Analysis (1) ----- two-way linked list. For more information about PHP tutorials, see. Ng_queue_t is an ordered container provided by Nginx. it organizes data together in a two-way linked list.
As an ordered container, a linked list can efficiently perform insert, delete, and merge operations. when moving elements in a linked list, you only need to modify the pointer. therefore, it is suitable for frequent modification of containers.
Compared with other sequential containers, it has the following advantages:
(1) the sorting function is implemented, and the insert sorting is adopted. although it is not suitable for sorting ultra-large scale data, it is simple and practical.
(2) it is very lightweight and does not allocate memory occupied by linked list elements. Ngx_queue_t only links the memory elements of these allocation numbers with a two-way linked list.
(3) merge two linked lists.
During Nginx's design of this two-way linked list, because containers and elements share the ngx_queue_t struct, Nginx encapsulates all the methods of linked list containers and elements to avoid confusion in the meaning of these struct members.
Ngx_queue_t header file:
Typedef struct into ngx_queue_t; struct ngx_queue_s {ngx_queue_t * prev; ngx_queue_t * next;}; # define ngx_queue_init (q) \ initialization, empty, all pointing to the container struct (q) -> prev = q; \ (q)-> next = q # define ngx_queue_empty (h) \ whether it is null (h = (h)-> prev) # define ngx_queue_insert_head (h, x) \ insert the head of the linked list container (x)-> next = (h)-> next; \ (x)-> next-> prev = x; \ (x)-> prev = h; \ (h)-> next = x # define ngx_queue_insert_after ngx_queue_insert_head # define ngx_queue_insert_tail (h, x) \ insert the tail of the linked list container) -> prev = (h)-> prev; \ (x)-> prev-> next = x; \ (x)-> next = h; \ (h) -> prev = x # define ngx_queue_head (h) \ returns the first struct pointer (h)-> next # define ngx_queue_last (h) \ returns the last struct pointer (h) -> prev # define ngx_queue_sentinel (h) \ return container struct pointer (h) # define ngx_queue_next (q) \ return the next element of q (q) -> next # define ngx_queue_prev (q) \ returns the previous element (q) of q-> prev # if (NGX_DEBUG) # define ngx_queue_remove (x) \ (x) -> next-> prev = (x)-> prev; \ (x)-> prev-> next = (x)-> next; \ (x) -> prev = NULL; \ (x)-> next = NULL # else # define ngx_queue_remove (x) \ delete x (x)-> next-> prev = (x) -> prev; \ (x)-> prev-> next = (x)-> next # endif # define ngx_queue_split (h, q, n) \ split into two linked lists (n)-> prev = (h)-> prev; \ (n)-> prev-> next = n; \ (n) -> next = q; \ (h)-> prev = (q)-> prev; \ (h)-> prev-> next = h; \ (q) -> prev = n; # define ngx_queue_add (h, n) \ merge linked list (h)-> prev-> next = (n)-> next; \ (n) -> next-> prev = (h)-> prev; \ (h)-> prev = (n)-> prev; \ (h) -> prev-> next = h; # define ngx_queue_data (q, type, link) \ returns the structure address (type *) (u_char *) q-offsetof (type, link ))
There are only two methods in the ngx_queue_t implementation File: one is to return the central element in the linked list, and the other is to sort the linked list.
Ngx_queue_t * queue (queue * queue) // returns the central element {ngx_queue_t * middle, * next; middle = ngx_queue_head (queue); if (middle = ngx_queue_last (queue )) {// in special cases, you should also judge it separately. if there is only one, return this element return middle;} next = ngx_queue_head (queue); (;;) {middle = ngx_queue_next (middle); // one pointer goes one step, and the other pointer goes two steps: next = ngx_queue_next (next); if (next = ngx_queue_last (queue )) {// next the return middle should be judged every step;} Next = ngx_queue_next (next); if (next = ngx_queue_last (queue) {// this also needs to be judged. please consider the full solution: return middle ;}}} /* the stable insertion sort */queue (ngx_queue_t * queue, ngx_int_t (* cmp) (const queue *, const ngx_queue_t *) // sort by insertion {ngx_queue_t * q, * prev, * next; q = ngx_queue_head (queue); if (q = ngx_queue_last (queue) {// return is not required if there is only one node ;} for (q = ngx_queue_next (q); q! = Ngx_queue_sentinel (queue); q = next) {prev = ngx_queue_prev (q); // Save the front and back nodes of q respectively. next = ngx_queue_next (q); ngx_queue_remove (q ); do {if (cmp (prev, q) <= 0) {// if the prev is smaller than, this loop ends with break;} prev = ngx_queue_prev (prev ); // otherwise, compare with the previous element} while (prev! = Ngx_queue_sentinel (queue); // This is the end condition, and prev is the end of the chain table struct ngx_queue_insert_after (prev, q); // Insert q }}
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.
The above introduces nginx advanced data structure Source Code Analysis (1) ----- two-way linked list, including content, hope to be helpful to friends interested in PHP tutorials.