ngx_list是nginx中对链表的一个数据结构封装,起功能和普通的连接打通小异。先看看结构体定义
typedef struct ngx_list_part_s ngx_list_part_t;
struct ngx_list_part_s {
void *elts; //数据区空间的指针
ngx_uint_t nelts; //链表块中元素的个数
ngx_list_part_t *next; //下一个链表块的节点
};
typedef struct {
ngx_list_part_t *last; //指向最后一个链表块的指针
ngx_list_part_t part; //链表第一块的指针
size_t size; //链表中每个元素的空间大小
ngx_uint_t nalloc; //链表中容量大小,指的是最大能容下多少个元素
ngx_pool_t *pool; //当前链表分配空间的内存池
} ngx_list_t;
从这两个结构体定义来看还是挺有意思的, 从这个链表的定义中可以看出,一个链表实际上是有多个子链表构成。然后看看提供了一些什么样的接口吧。
ngx_list_t *
ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
ngx_list_t *list;
//list结构体本身申请空间
list = ngx_palloc(pool, sizeof(ngx_list_t));
if (list == NULL) {
return NULL;
}
//为list中数据区申请空间
list->part.elts = ngx_palloc(pool, n * size);
if (list->part.elts == NULL) {
return NULL;
}
list->part.nelts = 0; //初始化链表中的元素个数,一开始没有,所以是0
list->part.next = NULL; //下一个区块的指针
list->last = &list->part; //最后一个区块指针
list->size = size; //链表中单个元素的大小
list->nalloc = n; //当前表块中最大能容纳的元素个数
list->pool = pool; //链表所在的内存池
return list;
}
list创建函数,和ngx_array的函数功能类似。
void *
ngx_list_push(ngx_list_t *l)
{
void *elt;
ngx_list_part_t *last;
last = l->last;
if (last->nelts == l->nalloc) {
/* the last part is full, allocate a new list part */
last = ngx_palloc(l->pool, sizeof(ngx_list_part_t));
if (last == NULL) {
return NULL;
}
last->elts = ngx_palloc(l->pool, l->nalloc * l->size);
if (last->elts == NULL) {
return NULL;
}
last->nelts = 0;
last->next = NULL;
l->last->next = last;
l->last = last;
}
elt = (char *) last->elts + l->size * last->nelts; //返回数据要存放的位置的起始地址
last->nelts++;
return elt;
}
这个函数提供了将一个元素加入链表的结构,这个函数返回的是数据存放的其实地址,实际数据存放操作需要在链表外面完成。