nginx的list比较简单,主要在文件src/core/ngx_list.h和src/core/ngx_list.c两个文件中,可以说是麻雀虽小,五脏俱全。
1、ngx_list的结构
其定义如下:
struct ngx_list_part_s {
void *elts; //元素的首地址
ngx_uint_t nelts; //元素的个数
ngx_list_part_t *next; //指向下一个链表块,构成链表
};
//可以认为是管理链表的单元
typedef struct {
ngx_list_part_t *last; //指向list_part构成的链表的最后一个list_part
ngx_list_part_t part; //表示list_part构成的链表的每一个part
size_t size; //表示part中每个元素的大小
ngx_uint_t nalloc; //表示part中可以容纳最大的元素个数
ngx_pool_t *pool;
} ngx_list_t;
UML结构图表示为
2、ngx_list的操作
2.1 创建初始化
创建是由函数ngx_list_create来完成,当中调用了函数ngx_list_init
static ngx_inline ngx_int_t
ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
list->part.elts = ngx_palloc(pool, n * size); //内存池中分配part的元素elts数组,容量为n,每个元素大小为size
if (list->part.elts == NULL) {
return NGX_ERROR;
}
list->part.nelts = 0; //元素个数为0
list->part.next = NULL;
list->last = &list->part; //将last指针指向第一个part
list->size = size; //初始化元素大小
list->nalloc = n; //初始化容量
list->pool = pool;
return NGX_OK;
}
创建初始化时的结构分布图为
2.2 向list中添加元素
添加元素是由函数ngx_list_push,其实现为
void *
ngx_list_push(ngx_list_t *l)
{
void *elt;
ngx_list_part_t *last;
last = l->last;
//如果list_part中的已经填充满
if (last->nelts == l->nalloc) {
/* the last part is full, allocate a new list part */
//在内存池中申请list_part
last = ngx_palloc(l->pool, sizeof(ngx_list_part_t));
if (last == NULL) {
return NULL;
}
//申请elts
last->elts = ngx_palloc(l->pool, l->nalloc * l->size);
if (last->elts == NULL) {
return NULL;
}
last->nelts = 0;
last->next = NULL;
//设置list的last指针指向新申请的list_part,串成链表
l->last->next = last;
l->last = last;
}
elt = (char *) last->elts + l->size * last->nelts;
last->nelts++;
return elt;
}
list_push后的结构图为