Nginx Advanced data structure Source analysis (a)-----doubly linked list

Source: Internet
Author: User

ng_queue_t is a sequential container provided by Nginx, which organizes the data together in a doubly linked list.

The advantage of a linked list as a sequential container is that it efficiently performs insertions, deletions, merges, and so on, while moving the elements in the list only by modifying the pointer's direction, so it is well suited for frequently changing containers.

Compared to other sequential containers, it has the following three points:

(1) to achieve the sorting function, the amount is the insertion sort, although not very suitable for super-large-scale data sorting, but simple and practical.

(2) It is very lightweight and is not responsible for allocating the memory allocated by the list elements. ngx_queue_t just put these allocation number elements in a two-way chain.

(3) Support the merging of two linked lists.


Nginx in the design of this doubly linked list, because the container and elements share the ngx_queue_t structure, in order to avoid this structure members of the meaning of confusion, Nginx encapsulates the list of containers and elements of all methods.

ngx_queue_t header file:

typedef struct NGX_QUEUE_S ngx_queue_t;struct ngx_queue_s {ngx_queue_t *prev; ngx_queue_t *next;};                                                                #define NGX_QUEUE_INIT (q) \ Initialize, empty, point to the container structure (q)->prev = q;                                                    (q)->next = Q#define Ngx_queue_empty (h)                                           \ is empty (H = (h)->prev) #define Ngx_queue_insert_head (h, X)                                                        \ Insert List container Head (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 List container tail (x)->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) \ Returns the container struct pointer (h) #define NGX_QUEUE_NEXT (q)                                                     \ Returns the next element of Q (q)->next#define Ngx_queue_prev (q)                                                       \ Returns the previous element of Q (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) \ Disassemble                                                        Divided into two linked list (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 list (h)->prev->n                                                  ext = (n)->next; (n)->next->prev= (h)->prev;                                                        (h)->prev = (n)->prev; (h)->prev->next = h; #define NGX_QUEUE_DATA (q, type, link) \ Returns the address of the struct to which Q belongs (Ty PE *) ((U_char *) q-offsetof (type, link))

N There are only two methods in the gx_queue_t implementation file: One is to return the central element in the linked list, and the other is to sort the list.

ngx_queue_t *ngx_queue_middle (ngx_queue_t *queue)//Return list center element {ngx_queue_t *middle, *next;    Middle = ngx_queue_head (queue);    if (middle = = Ngx_queue_last (queue)) {//special case should also be judged separately, if there is only one, then return this element to middle;    } next = Ngx_queue_head (queue); for (;;)                 {middle = ngx_queue_next (middle);        One pointer goes one step, the other pointer goes two steps next = Ngx_queue_next (next);        if (next = = Ngx_queue_last (queue)) {//next Each step must judge the return middle;        } next = Ngx_queue_next (next);        if (next = = Ngx_queue_last (queue)) {//This also must be judged, consider really comprehensive AH return middle; }}}/* The stable insertion sort */voidngx_queue_sort (ngx_queue_t *queue, ngx_int_t (*cmp) (const ngx_queue_t *, cons    T ngx_queue_t *))//With Insert method {ngx_queue_t *q, *prev, *next;    Q = ngx_queue_head (queue);    if (q = = Ngx_queue_last (queue)) {//Only one node is not queued for return; } 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 separately next = Ngx_queue_next (q);        Ngx_queue_remove (q);            Do {if (CMP (prev, q) <= 0) {//If Prev is less than, this loop ends break; } prev = Ngx_queue_prev (prev);//otherwise than the previous element (prev! = Ngx_queue_sentinel (queue));//This is the end condition, prev is the linked list struct End Ngx_queue_insert_after (prev, q);//Insert Q}}




Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Nginx Advanced data structure Source analysis (a)-----doubly linked list

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.