nginx之array分析

来源:互联网 发布:sqlite数据库编辑器 编辑:程序博客网 时间:2024/05/16 01:26

nginx 数组结构体:

struct ngx_array_s {

    void        *elts;     内容

    ngx_uint_t   nelts;    已经使用了多少个字符串

    size_t       size;     每个字符串所占的大小 

    ngx_uint_t   nalloc;   预分配的多少个字符串,如果和nelts相等,则满了,然后根据情况确定是否需要重新分配内存

    ngx_pool_t  *pool;     指向内存池,此内存池用来容纳该数组

};

 

创建数组集合,以后每次申请一个数组,就从这个数组集合中分配内存

n是预先申请多少个数组,size是每个数组的大小。

ngx_array_t *

ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)

{

    ngx_array_t *a;

 

    a = ngx_palloc(p, sizeof(ngx_array_t));   先为数组头分配内存

    if (a == NULL) {

        return NULL;

    }

 

    a->elts = ngx_palloc(p, n * size);      这里分配的内存是数组内容的大小

    if (a->elts == NULL) {

        return NULL;

    }

 

    a->nelts = 0;

    a->size = size;

    a->nalloc = n;

    a->pool = p;         指向当前内存池

 

    return a;

}

 

这个函数就是定义一个数组了,先为数组分配好内存,在数组集合里面有内存池,当申请数组的时候,从内存池分配一块内存出来。

void *

ngx_array_push(ngx_array_t *a)

{

    void        *elt, *new;

    size_t       size;

    ngx_pool_t  *p;

 

    if (a->nelts == a->nalloc) {   如果这个数组集合满了,分为两种情况,还有剩余的空间和没有剩余空间,

                                   因为当内存池括大的时候,end有可能大于size

 

        /* the array is full */

 

        size = a->size * a->nalloc;  数组集合总的大小

 

        p = a->pool;

 

        if ((u_char *) a->elts + size == p->d.last    a->elts指向内存池的开始,数组分配已到最后了

            && p->d.last + a->size <= p->d.end)    如果还有剩余的空间

        {

            /*

             * the array allocation is the last in the pool

             * and there is space for new allocation

             */

 

            p->d.last += a->size;

            a->nalloc++;

 

        } else {   没有剩余的空间

            /* allocate a new array */

 

            new = ngx_palloc(p, 2 * size);    重新分配一个数组,大小是原来数组的两倍

            if (new == NULL) {

                return NULL;

            }

 

            ngx_memcpy(new, a->elts, size); 把原来的内容复制过来

            a->elts = new;   指向新分配的数组集合

            a->nalloc *= 2;

        }

    }

 

    elt = (u_char *) a->elts + a->size * a->nelts; 指向新分配的数组空间

    a->nelts++;  已使用多少个数组

 

    return elt;  返回新分配的数组,然后就可以往里面填充数据了。

}

 

 

void *

ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)   这个函数分配n个数组空间

 

 

这个函数销毁这个数组集合,并不是真的销毁,内存空间并没有被回收。

void

ngx_array_destroy(ngx_array_t *a)

{

    ngx_pool_t  *p;

 

    p = a->pool;

 

    if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {

        p->d.last -= a->size * a->nalloc;

    }

 

    if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {

        p->d.last = (u_char *) a;

    }

}

原创粉丝点击