nginx的数据结构之nginx_array

nginx_array

nginx内部自己实现了许多数据结构,这些数据结构是nginx项目的基石。
nginx_array是nginx实现的一个最基础的数据结构,其类型可以是根据自己的需要进行定义。
详见<nginx_array.h>中的:

typedef struct {
    void        *elts;
    ngx_uint_t   nelts;
    size_t       size;
    ngx_uint_t   nalloc; 
    ngx_pool_t  *pool;
} ngx_array_t;

elts: 可以是ngx_keyval_t, ngx_str_t, ngx_bufs_t, ngx_hash_key_t等
nelts: 指出当前已使用的elts的个数
size: 每个elts的大小
nalloc: 指定申请被申请的空间能够容纳的元素个数
pool: 指向当前分配空间的内存池

nginx对外的函数:

ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);
void ngx_array_destroy(ngx_array_t *a);
void *ngx_array_push(ngx_array_t *a);
void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);

ngx_array_create以及ngx_array_destroy这两个函数比较简单,创建和内存回收的真正动作是由内存池相关动作所实现,因此销毁动作只是将指针指回之前未申请array的地址。
array_push和array_push_n在array的nelts剩余足够使用的,那么便直接使用,否则就要重新从内存池申请内存,而区别就在此:
ngx_array_push:

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
* 对于内存池所剩空间足够的,那么就直接扩容一个size
 */

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

} else {
/** 
*allocate a new array 
*如果当前内存池中剩余的空间小于本次需要新增的空间,
*那么对ngx_array_push方法来说,
*会将原先动态数组的容量扩容一倍
*/

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

ngx_array_push_n:

 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->d.end)
        {
/**
* the array allocation is the last in the pool
* and there is space for new allocation
*如果当前内存池中剩余的空间大于或者等于本次需要新增的空间,
*那么本次扩容将只扩充新增的空间。
*对于ngx_array_push_n来说,就是扩充n个元素。
 */
             
    
            p->d.last += size;
            a->nalloc += n;

        } else {
/**
* allocate a new array 
*如果当前内存池中剩余的空间小于本次需要新增的空间,
*对于ngx_array_push_n来说,
*如果参数n小于原先动态数组的容量,
*将会扩容一倍;如果参数n大于原先动态数组的容量,
*这时会分配2×n大小的空间。
*/
            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; 

    return elt;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值