Rookie Nginx Source analysis data structure (a) dynamic array ngx_array_t[to]

Source: Internet
Author: User

Rookie Nginx Source analysis data structure (a) dynamic array ngx_array_t

  • Author:echo Chen (Chenbin)

  • Email:[email protected]

  • blog:blog.csdn.net/chen19870707

    Date:october 20h, 2014

    1.ngx_array Advantages and characteristics

    Ngx_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 Location

    Header 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 definition

    typedef 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_init

    P 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_destroy

    Voidngx_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_push

    A 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_n

    A 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 combat

    The 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:}

Rookie Nginx Source analysis data structure (a) dynamic array ngx_array_t[to]

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.