Nginx源码初探之数据结构 - 数组数据结构

       nginx内部使用的数组结构是ngx_array_t,ngx_array_t是一个顺序容器,以数组的形式存储元素,并能够在容量达到最大值时动态扩容。Nginx数组属于基础数据结构部分,只要具备一定的开发经验,可以参考自己所熟悉的其他框架的数组。值得重复提出的一点是Nginx数组的内存事宜遵循,Nginx内存使用的类别化,层级化的原则,内存的使用在内存池中进行。

1.数据结构

typedef struct {
    void        *elts; /*数据区域的起始地址指针*/
    ngx_uint_t   nelts; /*已经存储的元素数量*/
    size_t       size;  /*单个元素的内存大小,Nginx数组的每个元素大小都相同*/
    ngx_uint_t   nalloc;/*数组已经分配的内存空间数量*/
    ngx_pool_t  *pool; /*数组所在内存池地址*/
} ngx_array_t;

从数据结构看,Nginx的数组本身只包含数组的管理,不保存实际的数据内容,同时Nginx的数组内存分配也必须是基于内存池实现,这点在数组的使用过程中体现的更加明显。

2.数组操作
2.1数组初始化

数组初始化参数包括,数组指针,用来分配数组内存的内存池,数组可以存储的数据长度,每个元素占用的空间大小。
初始化时已经存储的数量为0,然后在传入内存池中分配,数据长度*数据空间大小长度的内存给数组。

static ngx_inline ngx_int_t
ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
    /*
     * set "array->nelts" before "array->elts", otherwise MSVC thinks
     * that "array->nelts" may be used without having been initialized
     */

    array->nelts = 0;
    array->size = size;
    array->nalloc = n;
    array->pool = pool;

    array->elts = ngx_palloc(pool, n * size);
    if (array->elts == NULL) {
        return NGX_ERROR;
    }

    return NGX_OK;
}

2.2数组创建

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;
    }

    if (ngx_array_init(a, p, n, size) != NGX_OK) {
        return NULL;
    }

    return a;
}

2.3添加一个元素

       ngx_array_t数组添加元素主要工作是指针的移动和数据的管理,比如移动最后指针的位置,更新已存储数据nelts的值,存储空间size的值,可存储数据nalloc的值,以及在空间不足的时候扩大原来两倍的空内存空间。

void *
ngx_array_push(ngx_array_t *a)
{
    void        *elt, *new;
    size_t       size;
    ngx_pool_t  *p;

    if (a->nelts == a->nalloc) {

        /* the array is full */

        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)
        {
            /*
             * 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;
}

        Nginx数组操作不涉及数据内容的移动只在于指针的移动速度快、数组容量可动态扩容,不足之处在于动态扩容每次都是扩容为原来的两倍,不能根据实际需要分配。

发布了8 篇原创文章 · 获赞 0 · 访问量 117

猜你喜欢

转载自blog.csdn.net/mlydaemon/article/details/103944711
今日推荐