blog:blog.csdn.net/chen19870707
Date:october 20h, 2014
1.ngx_array Advantages and characteristicsNgx_array _t is a sequential container that supports dynamically changing the size of an array when the array capacity is reached, similar to the vector in STL, with the following characteristics:
- Subscript Direct index, fast access speed
- Dynamic growth
- Efficient allocation of memory allocated by the slab memory pool for unified management
2. Source code LocationHeader file: Http://trac.nginx.org/nginx/browser/nginx/src/core/ngx_array.h
Source file: http://trac.nginx.org/nginx/browser/nginx/src/core/ngx_array.c
3. Data structure definitiontypedef struct {void *elts; ELTs points to the first address of the array ngx_uint_t nelts; Nelts is the number of elements already used in the array size_t size; Each array element occupies memory size ngx_uint_t nalloc; The total size of the current array can accommodate the number of Yuan ngx_pool_t *pool; Memory Pool Object} ngx_array_t;
Its structure is as follows:4. Dynamic arrays Create ngx_array_create and initialize Ngx_array_initP is the memory pool, n is the number of elements initially allocated, size is the amount of memory each element occupies
ngx_array_t * Ngx_array_create (ngx_pool_t *p, ngx_uint_t N, size_t size) { ngx_array_t *a; //Assigning dynamic array pointers a = Ngx_palloc (p, sizeof (ngx_array_t)); if (a = = null) { return null; }  &N bsp; if (Ngx_array_init (A, p, N, size)! = NGX_OK) { return NULL; &n bsp; } return A; } static Ngx_inline ngx_int_t ngx_array_init (ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t N, size_t size) { &nbs p; /* * set "Array->nelts" before "array->elts", otherwise MSVC thinks & nbsp; * that ' array->nelts ' may be used without have been initialized * * & nbsp //Initialization data array->nelts = 0; array->size = size; Array->nalloc= N; array->pool = pool; //Allocate n sizes of memory, ELTs points to the first address array->elts = Ngx_palloc (pool, n * size); if (array->elts = = NULL) { return ngx_error; & nbsp; } return NGX_OK; }
5. Dynamic Array Release Ngx_array_destroyVoidngx_array_destroy (ngx_array_t *a) {ngx_pool_t *p; p = a->pool; Release the dynamic array for each element if ((U_char *) A->elts + a->size * A->nalloc = = p->d.last) {p->d.last-= A->size * a->nalloc; }//Release the dynamic array first pointer if ((U_CHAR *) A + sizeof (ngx_array_t) = = p->d.last) {p->d.last = (U_char *) A; }}
This is used in the memory pool release operation, and then explained in detail, here to use it as a release. 6. Adding elements to a dynamic array operation Ngx_array_push and Ngx_array_push_n 1.ngx_array_pushA pointer to the dynamic array to add to void * Ngx_array_push (ngx_array_t *a) { void *elt, *new; size_t size; ngx_pool_t *p; //used and pre-assigned number are equal, array is full if (a->nelts = = A->nalloc) { /* The array is full */ //Redistribution Pre-allocation nalloc, now there are 2*nalloc size = A->size * a->nalloc; p = a->pool; //If memory pool memory is enough, Allocate directly from the memory pool, assigning only one if ((U_char *) a->elts + size = = p->d.last & nbsp; && p->d.last + a->size <= p->d.end) { /* * The array allocation is the last in the pool & nbsp; * And there are space for new allocation & nbsp; */ //memory pool tail pointer moves back one element size, allocates memory for an element, and puts nalloc+1 P->d.last + = a->size; a->nalloc++; //If memory pool memory is not enough, allocate a new array with a size of twice times Nalloc } else { /* Allocate a new array */ //memory allocation new = Ngx_palloc (P, 2 * size); if (new = = NULL) { return null; } //Copy the previous array to the new array and set the array size to the previous twice Times ngx_memcpy (new, a->elts, size); a->elts = new; a-> Nalloc *= 2; } } //Assigned number +1, and return ELT = (U_char *) A->elts + a->size * a->nelts; a->nelts++; return ELT;}
as you can see, when there is room in the memory pool, only one element is added when the array is full, and when the memory pool has no unallocated space, the 2*nalloc size is allocated directly, with the memory pool, which is more efficient than the direct 2n+1 of the vector.
2.ngx_array_push_nA is the array to put, N is the number to put in void *ngx_array_push_n (ngx_array_t *a, ngx_uint_t N) { void *elt, *new; size_t size; ngx_uint_t nalloc; ngx_pool_t *p; size = n * a-> size; //If the number of remaining arrays is not allocated if (A->nelts + n > A->nalloc) { /* The array is full */ p = a->pool; & nbsp; //If the remaining in the memory pool is sufficient to allocate n elements, allocate if ((U_char *) from the memory pool A->elts + a->size * A->nalloc = = p->d.last && p->d.last + size <= p->d.end) { /* * The array allocation is the last in the pool * And there are space for new allocation */ p-> D.last + = size; A->nalloc + = n; //If the remaining in the memory pool is not enough to allocate n elements } else { /* Allocate a new array */ // Allocate 2n when n is larger than the number of pre-allocated nalloc, otherwise allocate 2*nalloc Nalloc = 2 * ((n >= a->nalloc) n:a->nalloc); new = Ngx_palloc (P, Nalloc * a->size); if (new = = NULL) { Return null; } // Copy the previous element, set nalloc ngx_memcpy (new, A->elts, A- >nelts * a->size); a->elts = new; A->nalloc = nalloc; } } //Increase assigned number and return ELT = (U_char *) A->elts + A- >size * a->nelts; A->nelts + = n; return ELT;}
7. Actual combatThe main significance of the study of Open source code is to understand the principles of design and application of the occasion, and in the appropriate use of code, if the simple analysis of code, but can not be used, certainly not up to the purpose of learning, here give Ngx_array test code, hope to do more hands-on.
1:typedef struct
4:int age;
5:}student;
7:ngx_array_t* Parray = ngx_array_create (cf->pool,1,sizeof (Student));
9:student *pstudent = Ngx_array_push (Parray);
10:pstudent->age = 10;
12:students *pstudents = Ngx_array_push_n (parray,3);
13:pstudents->age = 1;
: (pstudents + 1)->age = 2;
17://Traversal
18:student *pstudent = parray->elts;
19:ngx_uint_i = 0;
20:for (; i < parray->nelts;i++)
21: {
22:a = pstudent + i;
23://....
24:}