1 2
| src/core/ngx_list.h src/core/ngx_list.c
|
list 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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_create
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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; }
|
示意图如下:
nalloc 为 4 ,代表可存放 4 个节点。
还可以明显看到,nginx
的链表中会提前创建出一个节点。到后面你就会看到,nginx
的链表中的节点,如果在没有扩容的情况下,是不会继续创建新节点的。因为它的数据存储在其他内存,这块内存起始地址由
elts 指针指向。
ngx_list_push
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
| 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; }
|
示意图:
空间不足,如果现在添加一个数据,将触发扩容。
基本使用
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
| typedef struct { int value; } test_element_t;
void test_list() { ngx_pool_t *ngx_pool = ngx_create_pool(2048, NULL);
ngx_list_t* ngx_list = ngx_list_create(ngx_pool,2,sizeof(test_element_t));
test_element_t* index1 = ngx_list_push(ngx_list); index1->value = 10; test_element_t* index2 = ngx_list_push(ngx_list); index2->value = 20; test_element_t* index3 = ngx_list_push(ngx_list); index3->value = 30;
ngx_list_part_t *part = &ngx_list->part; test_element_t *data = part->elts; for (unsigned int i = 0; ; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; data = part->elts; i = 0; } printf("Element value: %d\n", data[i].value); } }
|