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;
nginx链表给我的感觉有点像数组加链表的感觉。实现也简单只有三个函数。链表没有销毁函数,只有创建和使用。内存的回收最后统一交给内存池
- nalloc是一个节点最多的元素个数
- nelts是节点使用的元素个数
- size是节点元素的大小
这三个元素组成了一个数组,每个节点都是一个数组
链表的创建
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);//分配节点内存
if (list->part.elts == NULL) {
return NGX_ERROR;
}
list->part.nelts = 0; //初始化节点使用个数
list->part.next = NULL;
list->last = &list->part;
list->size = size; //节点元素的大小
list->nalloc = n; //最大节点元素个数
list->pool = pool;
return NGX_OK;
}
ngx_list_t *ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
ngx_list_t *list;
//分配ngx_list_t内存
list = ngx_palloc(pool, sizeof(ngx_list_t));
if (list == NULL) {
return NULL;
}
//初始化ngx_list_t
if (ngx_list_init(list, pool, n, size) != NGX_OK) {
return NULL;
}
return list;
}
链表的创建没什么难懂的地方主要是初始化各个字段
链表的使用
void *ngx_list_push(ngx_list_t *l)
{
void *elt;
ngx_list_part_t *last;
last = l->last;
//节点的元素使用完
if (last->nelts == l->nalloc) {
//重新分配一个节点
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;
//使用元素+1
last->nelts++;
return elt;
}
- 如果一个节点内存没有使用完,直接返回一个未使用的地址
- 如果节点内存使用完重新分配一个节点,并且使用尾插法插入链表,然后再分配内存