blog:blog.csdn.net/chen19870707
Date:october 23h, 2014
1.ngx_list Advantages and characteristicsNgx_list _t is a sequential container, which is actually a combination of dynamic arrays and unidirectional lists, which is more simple to expand than dynamic arrays and can be expanded one at a time, so it combines the advantages of a list insert to delete an array subscript that does not need to be moved , the design is very amazing, in addition it has the following features:
2. Source code LocationHeader file: http://trac.nginx.org/nginx/browser/nginx/src/core/ngx_list.h
Source file: http://trac.nginx.org/nginx/browser/nginx/src/core/ngx_list.c
3. Data structure definitionIn front of the ngx_list_t is an array linked list, each node in the list is an array, ngx_list_part_t describes a link in the list of a node , which is an array, elts the first address of the group, Nelts is the number that the array already uses, and *next is the pointer to the next linked table node, as defined below:
1:typedef struct ngx_list_part_s ngx_list_part_t;
3://Describes a node in a linked list, which is an array.
4:struct ngx_list_part_s {
5:void *elts; First Address
6:ngx_uint_t Nelts; Number of already used
7:ngx_list_part_t *next; Pointer to the next linked list node
8:};
Ngx_list_t is to describe the entire list, where last is the final array in the list, part is the first group in the list, size is small for each element, Nalloc is the number of elements that each array can hold, and pool is the linked table memory pool object, as defined below:
1:typedef struct {
2:ngx_list_part_t *last; The last array element in a linked list
3:ngx_list_part_t part; First array of elements in a linked list
4:size_t size; The amount of space occupied by each array element
5:ngx_uint_t Nalloc; The capacity of each array node, which is the maximum number of elements each array can hold
6:ngx_pool_t *pool; The memory pool object pointer in the linked list
7:} ngx_list_t;
Its structure as shown, the bottom of the behavior of the memory image, you can see the whole memory only a ngx_list_t and a few ngx_list_part_s results, memory is not too much waste, nginx in the memory of the harsh really worth learning .
4. Linked lists create ngx_list_create and initialize Ngx_list_init 1://List creation, pool for memory pool object, size for each array element, n for the number of elements each array can hold
2:ngx_list_t *ngx_list_create (ngx_pool_t *pool, ngx_uint_t N, size_t size)
3: {
4:ngx_list_t *list;
6://ASSIGN NGX_LIST_T structure
7:list = Ngx_palloc (pool, sizeof (ngx_list_t));
8:if (list = = NULL) {
9:return NULL;
10:}
12://Initialization
13:if (Ngx_list_init (list, pool, n, size)! = NGX_OK) {
14:return NULL;
15:}
17:return list;
18:}
20://Linked list initialization, list is a linked list structure (created in create), pool is the size of each array element, and N is the number of elements that each array can hold
21:static ngx_inline ngx_int_t ngx_list_init (ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t N, size_t size)
22: {
23://Assign an array and point to it with the first node of the list
24:list->part.elts = Ngx_palloc (pool, n * size);
25:if (List->part.elts = = NULL) {
26:return Ngx_error;
27:}
29://Number of used 0
30:list->part.nelts = 0;
31://No next node, next refers to null
32:list->part.next = NULL;
33://The last node also points to the array just allocated
34:list->last = &list->part;
35://array each element is size
36:list->size = size;
37://array can hold the number of elements n
38:list->nalloc = n;
39://Pool of memory
40:list->pool = pool;
42:return NGX_OK;
43:}
As you can see, after the Ngx_list_init call succeeds, an array node is created.
5. Link list add element operation Ngx_list_push 1://List add element, L is linked list structure
2:void *ngx_list_push (ngx_list_t *l)
3: {
4:void *elt;
5:ngx_list_part_t *last;
7://last points to the last node of the list
8:last = l->last;
10://If the array of the last node is full
11:if (Last->nelts = = L->nalloc) {
*/* The last part was full, allocate a new list part */
15://Allocate a ngx_list_part_t array object from the memory pool
16:last = Ngx_palloc (l->pool, sizeof (ngx_list_part_t));
17:if (last = = NULL) {
18:return NULL;
19:}
21://Allocate space for array object elements from the memory pool, each element is size, and the number of elements is Nalloc
22:last->elts = Ngx_palloc (L->pool, L->nalloc * l->size);
23:if (Last->elts = = NULL) {
24:return NULL;
25:}
27://The newly allocated array already uses a node number of 0 and the next linked table node is null
28:last->nelts = 0;
29:last->next = NULL;
31://Link the newly allocated array to the linked list, and point the linked footer pointer to the newly allocated array
32:l->last->next = Last;
33:l->last = Last;
34:}
//elts: The first address of the array, ELTs + size * Nelts to the position of the allocation element
37:elt = (char *) Last->elts + l->size * last->nelts;
39://Number of allocations +1
40:last->nelts++;
42:return ELT;
43:}
You can see that the push idea is simple, each time to the list of the last array added, the array is full after the addition of an array node, where the time complexity of the push is O (1), there is no traversal operation, take full advantage of the"Linked-list-end interpolation"and the "array subscript index" advantage.
6. Questions
The source code only gives the list of insert operation, no deletion operation, looks incomplete, here guess this list structure should not be used directly, but is again encapsulated.
7. Actual combatAfter reading the source code, this list design is still very ingenious, combined with the array and the list of the advantages of each, really have to let people clap wow. Here are some examples of how to use ngx_list_t:
1:int Main ()
2: {
3:ngx_list_t *plist = ngx_list_create (r->pool,4,sizeof (ngx_str_t));
4:if (NULL = = pList)
5: {
6:return-1;
9:ngx_str_t *str = Ngx_list_push (pList);
10:if (NULL = = str)
11: {
12:return-1;
13:}
15:str->len = sizeof ("This was a test for ngx_list_t");
16:str->value = "This was a test for ngx_list_t";
18://Traversal
19:ngx_list_part_t *part = &pList->part;
20:ngx_str_t *str = part->elts;
22:for (int i = 0;; i++)
23: {
24:if (i >= part->nelts)
26://has traversed the last array, there is no next node
27:if (NULL = = Part->next)
28: {
29:break;
30:}
32://And the next array, part refers to the next array, and STR refers to the address of the new array
33:part = part->next;
34:str = part->elts;
36://Reset counter
37:i = 0;
38:}
40://Output node
41:cout << "list elemts:" << str[i] << Endl;
43:}