前言
Nginx中list的实现很简单,内部采用链表的形式串联起多个节点,其中每个节点采用一个数组的形式,可以存储多个数据。在源码文件中src/core/ngx_list.h|.c中可以看到相关的函数并不多,只有创建,初始化,添加三个方法,在明白了内存池的相关逻辑后,阅读起来还是很轻松的。
储备知识
数据格式定义
节点
| 12
 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
| 12
 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
| 12
 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初始化 主要是为节点申请存储空间
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | static ngx_inline ngx_int_tngx_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中的地址 赋值操作在外部完成
| 12
 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;
 }
 
 |