Nginx learning six advanced data structures-two-way linked list ngx_queue_t

Source: Internet
Author: User

1 ngx_queue_t Introduction

Ngx_queue_t is a lightweight two-way linked list container provided by nginx. It is not responsible for data storage and does not provide data memory allocation. It has only two pointers to import the data link into the linked list, unlike the queue provided by STL, the queue provided by STL helps users store data. Users only need to add data to the container. While ngx_queue_t, users must provide their own data storage memory, you must define a data structure to include ngx_queue_t in it, and then use the functions provided by ngx_queue_t for corresponding operations.

2 ngx_queue_t structure and its operations

2.1 ngx_queue_t

struct ngx_queue_s {    ngx_queue_t  *prev;    ngx_queue_t  *next;};
Ngx_queue_t provides only one pointer pointing to the precursor and one pointer pointing to the successor. The structure is very simple, which is also the reason for its versatility.

2.2 operation functions

Ngx_queue_init (q) // initialize the linked list ngx_queue_empty (h) // determine whether the linked list is empty ngx_queue_insert_head (H, X) // insert an element ngx_queue_insert_after in the header // insert an element ngx_queue_insert_tail (H, x) in front of element H // insert an element ngx_queue_head (h) in the end of element H) // returns the first element # define ngx_queue_last (h) // returns the last element ngx_queue_sentinel (h) // returns the ngx_queue_next (q) pointer of the linked list container struct) // return the next element ngx_queue_prev (q) of the next Q // return the previous element ngx_queue_remove (x) of Q // Delete the x node ngx_queue_split (H, Q, n) // divides H into two linked lists, H and N, and the first element of N is qngx_queue_add (H, n) // adds the chain table n to the end of the chain table ngx_queue_data (Q, type, link) // retrieve the type address containing Q, so that we can access the members in the type.

Ngx_queue_t provides 14 common operations for users, including insert, delete, move, and access data. These 14 functions are macro-defined, if you are interested, you can refer to the source code, which is very simple. Here is the last operation function ngx_queue_data:

#define ngx_queue_data(q, type, link)                                             (type *) ((u_char *) q - offsetof(type, link))

Q is a pointer to ngx_queue_t. type is a user-defined data type that contains ngx_queue_t. link is a member of type and the type is ngx_queue_t.

Here is a column to illustrate the usage of this operation.

First, let's look at a custom struct:

typedef struct{ngx_int_t num;ngx_str_t str;ngx_queue_t queue;}TestNode;

If we have a ngx_queue_t pointer Q pointing to testnode. queue. Now we don't know the testnode address. We only know the queue. If we want to access the member num in testnode, we must know the address of testnode to access its num member. How do I know the address of testnode? Ngx_queue_data is now available. We can use the following statement to obtain the address of testnode:

TestNode* testnode  = ngx_queue_data(q, TestNode, queue);
In this way, we can access num.
2.3 ngx_queue_middle

This function extracts the node at the center of the linked list. With a slow pointer midlle and a fast pointer next, middle does not take one step, and next takes two steps. When the next pointer reaches the Link List, midlle points to the center of the linked list.


Ngx_queue_t * Queue (queue * Queue) {ngx_queue_t * middle, * Next; middle = ngx_queue_head (Queue); If (middle = ngx_queue_last (Queue) {return middle ;} next = ngx_queue_head (Queue); For (;) {// middle each step forward, two steps forward next until the end of the linked list is middle = ngx_queue_next (middle ); next = ngx_queue_next (next); If (next = ngx_queue_last (Queue) {return middle;} next = ngx_queue_next (next); If (next = ngx_queue_last (Queue )) {return middle ;}}}

2.4 ngx_ngx_queue_sort

Terminate (distinct * queue, ngx_int_t (* CMP) (const ngx_queue_t *, const ngx_queue_t *) {ngx_queue_t * q, * Prev, * Next; q = ngx_queue_head (Queue ); if (q = ngx_queue_last (Queue) {return;} // each element in the traversal chain table, and then traverse whether the element before it is bigger than it, until you find the first element that is no larger than it, and then insert it. For (q = ngx_queue_next (Q); Q! = Ngx_queue_sentinel (Queue); q = NEXT) {Prev = ngx_queue_prev (Q); next = ngx_queue_next (Q); ngx_queue_remove (Q ); do {// traverse the element above it if (CMP (prev, q) <= 0) {break;} Prev = ngx_queue_prev (prev);} while (prev! = Ngx_queue_sentinel (Queue); ngx_queue_insert_after (prev, q); // The element before Q must be smaller than Q }}

3. Example

# Include <stdio. h> # include <stdlib. h> # include <ngx_config.h> # include <ngx_core.h> # include <ngx_conf_file.h> # include <nginx. h> # include <ngx_queue.h> ///////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //// // The two items must be written, there is no compilation error volatile ngx_cycle_t * ngx_cycle; void ngx_log_error_core (ngx_uint_t level, ngx_log_t * log, ngx_err_t err, const C Har * FMT ,...) {}////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// ///// typedef struct {ngx_int_t num; ngx_str_t STR; ngx_queue_t queue;} testnode; ngx_int_t compare_node (const ngx_queue_t * left, const limit * right) {testnode * left_node = ngx_queue_data (left, testnode, queue ); testnode * right_node = ngx_queue_data (right, testnode, Queue); Return left_node-> num> right_node-> num;} int main () {ngx_queue_t quehead; ngx_queue_init (& quehead); testnode node [10]; ngx_int_t I; for (I = 0; I <10; ++ I) {node [I]. num = rand () % 100;} ngx_queue_insert_head (& quehead, & node [0]. queue); ngx_queue_insert_tail (& quehead, & node [1]. queue); ngx_queue_insert_after (& quehead, & node [2]. queue); ngx_queue_insert_head (& quehead, & node [4]. queue); ngx_queue_insert_tail (& Quehead, & node [3]. queue); ngx_queue_insert_head (& quehead, & node [5]. queue); ngx_queue_insert_tail (& quehead, & node [6]. queue); ngx_queue_insert_after (& quehead, & node [7]. queue); ngx_queue_insert_head (& quehead, & node [8]. queue); ngx_queue_insert_tail (& quehead, & node [9]. queue); ngx_queue_t * q; For (q = ngx_queue_head (& quehead); Q! = Ngx_queue_sentinel (& quehead); q = ngx_queue_next (q) {testnode * node = ngx_queue_data (Q, testnode, queue); printf ("num = % d \ n ", node-> num);} ngx_queue_sort (& quehead, compare_node); printf ("\ n"); For (q = ngx_queue_head (& quehead); Q! = Ngx_queue_sentinel (& quehead); q = ngx_queue_next (q) {testnode * node = ngx_queue_data (Q, testnode, queue); printf ("num = % d \ n ", node-> num);} return 0 ;}

Http://blog.csdn.net/xiaoliangsky/article/details/39646141

Nginx learning six advanced data structures-two-way linked list ngx_queue_t

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.