nginx之array分析

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;

    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章