Nginx Array Structure ngx_array_t

Source: Internet
Author: User

Overview

The source of this section is from SRC/CORE/NGX_ARRAY.H/.C. Nginx source array similar to the previous introduction of the "STL source code Analysis-Vector of sequence container", in Nginx array, memory allocation is based on the memory pool, is not fixed, nor how much memory to apply, if the current memory is not enough to store the required elements, Apply by twice times the memory size of the current array, which reduces the number of memory allocations and increases efficiency.

Array data structure

The data structure of a dynamic array is defined as follows:

typedef struct {    void        *elts;  /* The first address of the array data region */    ngx_uint_t   nelts;/* The number of actual data in the array */    size_t       size;  /* The size of bytes occupied by a single element */    ngx_uint_t   nalloc;/* Array capacity */    ngx_pool_t  *pool;  /* The memory pool where the array object resides */} ngx_array_t;

The array structure diagram is as follows:



Basic Operations for arrays

/* Create a new dynamic array */ngx_array_t *ngx_array_create (ngx_pool_t *p, ngx_uint_t N, size_t size);/* Destroys an array object, memory is reclaimed by the memory pool */void Ngx_array _destroy (ngx_array_t *a);/* Adds a new element to the existing array */void *ngx_array_push (ngx_array_t *a);/* adds n new elements to the existing array */void *ngx_array_ Push_n (ngx_array_t *a, ngx_uint_t N);

To create a new dynamic array:

The operation to create an array is implemented as follows, the array header is assigned first, and then the array data area is allocated, and the two allocations are made in the incoming memory pool (pool-directed memory pools). The array header is then simply initialized and the starting position of the array header is returned.

/* Create dynamic Array object */ngx_array_t *ngx_array_create (ngx_pool_t *p, ngx_uint_t N, size_t size) {ngx_array_t *a;    /* Assign dynamic Array header */a = Ngx_palloc (p, sizeof (ngx_array_t));    if (a = = null) {return null;    }/* Allocates a dynamic array data area of capacity N and initializes it */if (Ngx_array_init (A, p, N, size)! = NGX_OK) {return NULL; } return A; /* When an array object is allocated on the heap, and after calling Ngx_array_destroy, you need to call this function if you want to reuse it *//* if the array object is allocated on the stack, call this function */static ngx_inline ngx_int_tngx_ Array_init (ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t N, size_t size) {/* * set "array->nelts" before "arr Ay->elts ", otherwise MSVC thinks * that" array->nelts "could be used without have been initialized */*    Initialize the array member, note: Nelts must be initialized first */array->nelts = 0 than ELTs;    array->size = size;    Array->nalloc = n;    Array->pool = pool;    /* Memory required for allocating array data fields */Array->elts = Ngx_palloc (pool, n * size);    if (array->elts = = NULL) {return ngx_error; } return NGX_OK;}

Destroying dynamic arrays

The operation to destroy the array is implemented as follows, including destroying the array data area and the group header. The destroy action actually modifies the last pointer of the memory pool, that is, the memory of the array is reclaimed by the memory pool, and does not call the free memory operation.

/* Destroys the array object, that is, the memory occupied by the array is reclaimed by the memory pool */voidngx_array_destroy (ngx_array_t *a) {    ngx_pool_t  *p;    p = a->pool;    /* To move the last pointer of the memory pool, free the memory occupied by all elements of the array *    /if ((U_char *) A->elts + a->size * A->nalloc = = p->d.last) {        p->d . Last-= A->size * a->nalloc;    }    /* Releases the memory occupied by the array's first pointer */    if ((U_char *) A + sizeof (ngx_array_t) = = p->d.last) {        P->d.last = (U_char *) A;}    }

Add element action

Arrays add elements with two operations, Ngx_array_push and Ngx_array_push_n, adding one and more elements, respectively. The actual add operation is not done in either of these functions, only the memory space required for the element is requested in both functions, and the first address pointing to that memory space is returned, and the element is added in the form of a pointer assignment.

/* Array adds an element */void *ngx_array_push (ngx_array_t *a) {void *elt, *new;    size_t size;    ngx_pool_t *p;  /* Determine if the array is full */if (a->nelts = = A->nalloc) {/* If the existing array contains more than the number of elements */* The array is full */*        Calculates the memory size occupied by all elements of an array */size = A->size * a->nalloc;        p = a->pool;            if ((U_char *) a->elts + size = = P->d.last && p->d.last + a->size <= p->d.end)             /* If the memory space of the current memory pool accommodates at least one element size */{/* * The array allocation is the last in the pool            * And there is space for new allocation */p->d.last + = a->size;        a->nalloc++;  } else {/* If the current memory pool is not sufficient to accommodate one element, the new array memory is allocated */* Allocate a new array */            */new = Ngx_palloc (P, 2 * size);            if (new = null) {return null;          }/* First copy all elements of an existing array into the new array */  ngx_memcpy (new, a->elts, size);            A->elts = new;        A->nalloc *= 2;    }} ELT = (U_char *) A->elts + a->size * a->nelts;    a->nelts++; /* Returns a pointer to the newly added element */return ELT;}    /* array increases n elements */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 (A->nelts + n > A->nalloc) {/* The array is full */p = a->pool; if ((U_char *) A->elts + a->size * a->nalloc = p->d.last && p->d.last + size <= P-&G T;d.end) {/* * The array allocation is the last in the pool * and there is SPAC            E for new allocation */p->d.last + = size;        A->nalloc + = n;            } else {/* Allocate a new array */Nalloc = 2 * ((n >= a->nalloc)? n:a->nalloc); New =Ngx_palloc (P, Nalloc * a->size);            if (new = null) {return null;            } ngx_memcpy (New, A->elts, A->nelts * a->size);            A->elts = new;        A->nalloc = Nalloc;    }} ELT = (U_char *) A->elts + a->size * a->nelts; A->nelts + = n;



Nginx Array Structure ngx_array_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.