nginx源码分析-链表

来源:互联网 发布:centos selinux 关闭 编辑:程序博客网 时间:2024/04/30 19:05

nginx封装的list和我们在学习数据结构时的list略有点区别。nginx的list算是数组和链表的结合。其用以下两个结构来维护一个list。

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_part_s是用来实现list的节点的,其实也就是一个数组。elts指针指向这个数组的开始地址,nelts是数组中实际存储的元素的个数,next当然就是指向下一个节点了。从这个结构可以看得出来nginx的链表是将一个个数组串联起来形成的链式结构。当然,你可以随便定义这个数组的大小,只要你愿意,你可以定义这个数组只有一个存储单元,这样就和普通的链表相差无几了。

 

结构ngx_list_t是用来维护整个链表的。链表第一个节点的地址就存储在part.elts中,我们可以通过l->part.elts这样的一个入口来遍历链表。size就是存储到链表中的元素的大小。nalloc就是每个数组节点的实际单元数。last指针始终指向最后一个节点,目的是可以通过此指针快速的找到能够存入元素的单元位置,因为链表是在一个节点满了,才分配下一个节点开始存储,所以新存入的节点一定是在链表的末尾。pool指针当然就是内存池了,整个链表的内存都是分配在此内存池上的。

 

nginx主要提供了如下两个接口函数来操作链表:

ngx_list_t *  ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size);  


 

此函数用来创建一个链表,n是链表的数组节点的单元数,size是元素的大小。

 

void *  ngx_list_push(ngx_list_t *l);  

 

此函数是从参数指定的链表中获取一个可存放元素的单元地址。然后再通过这个地址向其中填入数据。和数组的操作一样,这是大牛的编码风格。


 

ngx_list_t *  ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size);  

 

此函数用来创建一个链表,n是链表的数组节点的单元数,size是元素的大小。

void *  ngx_list_push(ngx_list_t *l);  
 

此函数是从参数指定的链表中获取一个可存放元素的单元地址。然后再通过这个地址向其中填入数据。和数组的操作一样,这是大牛的编码风格。

ngx_list 结构示意图

图1 ngx_list 结构示意图

 

转自 http://blog.csdn.net/marcky/article/details/5756461

http://www.cnblogs.com/jzhlin/archive/2012/06/10/ngx_list.html

源码:

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_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;    }    list->part.elts = ngx_palloc(pool, n * size);    if (list->part.elts == NULL) {        return NULL;    }    list->part.nelts = 0;    list->part.next = NULL;    list->last = &list->part;    list->size = size;    list->nalloc = n;    list->pool = pool;    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) {        /* 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;}


 

原创粉丝点击