nginx中的ngx_array_t类似于c语言中的数组,其是基于内存池动态分配的。主要包含在文件src/core/ngx_array.h和/src/core/ngx_array.c两个文件中。
1、ngx_array_t的数组结构
typedef struct {
void *elts; //数组的首地址
ngx_uint_t nelts; //数组中的实际占用的元素个数
size_t size; //每个元素的大小
ngx_uint_t nalloc; //数组的总容量
ngx_pool_t *pool; //内存池
} ngx_array_t;
2、数组的操作
数组的操作主要有5个
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);
static ngx_inline ngx_int_t
ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size)
创建数组
数组创建是函数ngx_array_create来完成。首先在内存池中分配数组头,再分配数组区。
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;
}
数组的销毁
是由ngx_array_destroy来完成,修改内存池中数组区的last指针
void
ngx_array_destroy(ngx_array_t *a)
{
ngx_pool_t *p;
p = a->pool;
//修改last指针,销毁数组的数组区
if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
p->d.last -= a->size * a->nalloc;
}
//修改lastr指针,销毁数组头
if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
p->d.last = (u_char *) a;
}
}
数组中添加元素
由函数ngx_array_push和ngx_array_push_n来完成,ngx_array_push是添加一个元素,ngx_array_push_n是添加n个元素。两个函数原来差不多,下面只是以添加一个元素为例。
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) //内存池中可以继续分配,直接修改last指针
{
/*
* 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); //内存池中分配2倍数组大小的空间
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中的数组结构ngx_array_t作了分析,包括其数组结构、数组的创建、销毁、添加元素。