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);
此函数是从参数指定的链表中获取一个可存放元素的单元地址。然后再通过这个地址向其中填入数据。和数组的操作一样,这是大牛的编码风格。
图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;}
- nginx源码分析-链表
- nginx源码分析-链表
- nginx源码分析
- Nginx源码分析-数组
- Nginx源码分析链接
- 关于nginx源码分析
- nginx源码分析
- nginx源码分析
- Nginx源码分析
- Nginx源码分析链接
- Nginx源码分析一
- Nginx源码分析1
- Nginx源码分析-ngx_htttp_footer_filter_module
- Nginx 源码结构分析
- Nginx 源码结构分析
- nginx源码分析
- nginx源码分析
- nginx源码分析--数组
- SQL之exists工作原理
- 古代没有拼音
- Linux调试器工作原理——基础篇
- SOA On Tomcat专题5--JNDI
- android模拟器安装apk应用程序
- nginx源码分析-链表
- jpa注解的一些用法
- Android下编译自己的库文件jar并在应用中调用
- http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
- AudioRecord实现"助听器" ,录制和播放功能
- vs2010 c++打开双摄像头
- WordPress网站开发 资料
- Sublime Text2下安装 Zen Coding(现更名为Emmet)
- 核心态和用户态 到底是os还是cpu的状态?