ngx_array_t is a sequential container that is used extensively in Nginx. It stores elements as an array and supports changing the size of the array when the upper bound of the array capacity is reached. It is similar to a vector container in C + + and has a built-in memory pool of nginx encapsulation, so the memory allocated by it is also applied in the memory pool.
Ngx_array_t has the following three advantages;
(1) Fast access speed;
(2) The number of elements allowed is uncertain;
(3) Responsible for allocating the memory of the element, which will have the memory pool unified management.
Dynamic arrays are expandable in two ways:
(1) If the remaining space in the current memory pool is greater than or equal to the new space required for this time, then this expansion will only expand the new space.
(2) If the remaining space in the current memory pool is less than the space required for this time, then for the Ngx_array_push method, the capacity of the original dynamic array will be increased by one time, and for Ngx_array_push_n, the amount of expansion depends on the parameters and the capacity of the original dynamic array.
Structure of a dynamic array:
typedef struct { void *elts;//first address ngx_uint_t nelts;//number of elements used size_t size;// Each array element occupies a memory size ngx_uint_t nalloc;//can hold the total size of the number of elements ngx_pool_t *pool;//Memory Pool object} ngx_array_t;
Initialization of a dynamic array:
Static Ngx_inline Ngx_int_tngx_array_init (ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t N, size_t size)//Initialize array { / * * Set "Array->nelts" before "array->elts", otherwise MSVC thinks * that ' array->nelts ' may Used without having been initialized * * array->nelts = 0; The first address is 0 array->size = size; Each element occupies a memory size of Array->nalloc = n; Number of elements allocated Array->pool = pool; Memory Pool object //request n*size Such a large memory space array->elts = Ngx_palloc (pool, n * size); if (array->elts = = NULL) { return ngx_error; } return NGX_OK;}
To create a dynamic array:
ngx_array_t *ngx_array_create (ngx_pool_t *p, ngx_uint_t N, size_t size)//create array { ngx_array_t *a; A = Ngx_palloc (p, sizeof (ngx_array_t));//Request the memory of the array itself if (a = = null) { return null; } if (Ngx_array_init (A, p, N, size)! = NGX_OK) {//Initialize, that is, the request can store the element's memory return NULL; } return A;}
To destroy a dynamic array:
Voidngx_array_destroy (ngx_array_t *a)//Destroy array { ngx_pool_t *p; p = a->pool; if ((U_char *) A->elts + a->size * A->nalloc = = p->d.last) {//Releases the memory that holds the element. Why should we judge??? P->d.last-= a->size * a->nalloc; } if ((U_char *) A + sizeof (ngx_array_t) = = P->d.last) {//Release node memory/Why should I judge it??? P->d.last = (U_char *) A; }}
To add an element to a dynamic array:
void *ngx_array_push (ngx_array_t *a) {void *elt, *new; size_t size; ngx_pool_t *p; if (a->nelts = = A->nalloc) {//If the array is full ... /* The array is full */size = A->size * a->nalloc; p = a->pool; if ((U_char *) a->elts + size = = p->d.last//Why add this equal sign to judge:?????? && p->d.last + a->size <= p->d.end)//If the Memory pool node has free memory {/* * the array al The last in the pool * and there are space for new allocation */P->d.las T + = a->size; a->nalloc++; } else {//did not reapply a twice-fold memory/* Allocate a new array */new = Ngx_pa Lloc (P, 2 * size); if (new = null) {return null; } ngx_memcpy (new, a->elts, size);//Copy the original array element to the new memory space a->elts = new; A->nalloc *= 2; }} ELT = (U_char *) A->elts + a->size * a->nelts; Add new Element a->nelts++; return ELT;} Add n elements to the current dynamic array:
void *ngx_array_push_n (ngx_array_t *a, ngx_uint_t N)//add n elements {void *elt, *new; size_t size; ngx_uint_t Nalloc; ngx_pool_t *p; Size = n * a->size; if (A->nelts + n > A->nalloc) {//If the number of added together is greater than the number of array elements */the array is full */p = a->pool; if ((U_char *) A->elts + a->size * A->nalloc = = p->d.last//equals still do not know why to judge???? && p->d.last + size <= p->d.end)//If the memory pool node remaining memory can hold the added element {/* * the array all Ocation is the last in the pool * and there are space for new allocation */P->d.last + = size; A->nalloc + = n; } else {/* Allocate a new array */Nalloc = 2 * ((n >= a->nalloc)? n:a->nalloc);//In addition to the meta The number of pixels and the number of elements that can be stored in the original array select the larger one multiplied by 2 new = Ngx_palloc (P, Nalloc * a->size);//Request Memory if (new = = NULL) { return NULL; } ngx_memcpy (NEW, A->elts, A->nelts * a->size);//Copy the original element a->elts = new; Update two variables a->nalloc = Nalloc; }} ELT = (U_char *) A->elts + a->size * a->nelts; The memory starting address of the element that can be stored a->nelts + = n; Update return ELT;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
The above describes the Nginx high-level data structure source Analysis (ii)-----Dynamic array, including the aspects of the content, I hope to be interested in PHP tutorial friends helpful.