前言
Nginx中list的实现很简单,内部采用链表的形式串联起多个节点,其中每个节点采用一个数组的形式,可以存储多个数据。在源码文件中src/core/ngx_list.h|.c
中可以看到相关的函数并不多,只有创建
,初始化
,添加
三个方法,在明白了内存池
的相关逻辑后,阅读起来还是很轻松的。
储备知识
数据格式定义
节点
1 2 3 4 5 6 7
| 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; };
|
list
1 2 3 4 5 6 7
| 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_create
创建list 参数顺序依次为 内存相关的内存池pool 每个节点的容量大小n 每个元素的大小size
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| ngx_list_t * ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size) { ngx_list_t *list;
list = ngx_palloc(pool, sizeof(ngx_list_t)); if (list == NULL) { return NULL; }
if (ngx_list_init(list, pool, n, size) != NGX_OK) { return NULL; }
return list; }
|
ngx_list_init
list初始化 主要是为节点申请存储空间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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_push
往list中插入数据 该方法返回一个list中的地址 赋值操作在外部完成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| 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; last->nelts++;
return elt; }
|