Nginx高效数据结构(2)——链表(ngx_list_t)

Nginx是我们学习编程的一个非常有参考价值的开源项目。良好的编码风格,高效的数据结构、架构设计。

通常学习Nginx主要有以下两种情形:

1)需求驱动型。在实际应用中,需要在Nginx的基础上,开发一些特定需求的模块,为此,我们需要去了解Nginx的工作原理、架构设计,并完成相关功能模块的开发。这种情形下,一个比较好的学习路线是从开发一个简单的“Hello,world” HTTP模块入手,逐步深入。

2)知识驱动型。单纯从学习编程的角度出发,Nginx的模块化设计,架构,高效数据结构设计等都是不可多得的学习资源!这种情形下,通常从学习其常用的数据结构开始是一个不错的选择。

快课网在此搜罗了一些优质资源。从本文开始讲述Nginx中常用的数据结构,主要包括Nginx的数组结构链表结构队列hash结构内存池等。

0. 序

本文继续介绍nginx的容器——链表。

链表实现文件:文件:./src/core/ngx_list.h/.c。.表示nginx-1.0.4代码目录,本文为/usr/src/nginx-1.0.4。

1. 链表结构

1.1 ngx_list_t结构

nginx的链表(头)结构为ngx_list_t,链表节点结构为ngx_list_part_t,定义如下。

 

其中,sizeof(ngx_list_t)=28,sizeof(ngx_list_part_t)=12。

由此可见,nginx的链表也要从内存池中分配。对于每一个节点(list part)将分配nalloc个大小为size的小空间,实际分配的大小为(nalloc * size)。详见下文的分析。

1.2 ngx_list_t的逻辑结构

ngx_list_t结构引用了ngx_pool_t结构。注:本文采用UML的方式画出该图。

list1

2. 链表操作

链表操作共3个,如下。

他们的实现都很简单,本文只分析创建链表和添加元素操作。

2.1创建链表

创建链表的操作实现如下,首先分配链表头(28B),然后分配头节点(即链表头中包含的part)数据区,两次分配均在传入的内存池(pool指向的内存池)中进行。然后简单初始化链表头并返回链表头的起始位置。

创建链表后内存池的物理结构图如下。

list2bak

2.2添加元素

添加元素操作实现如下,同nginx数组实现类似,其实际的添加操作并不在该函数中完成。函数ngx_list_push返回可以在该链表数据区中放置元素(元素可以是1个或多个)的位置,而添加操作即在获得添加位置之后进行,如后文的例子。

由此可见,向链表中添加元素实际上就是从内存池中分配链表节点(part)及其该节点的实际数据区,并修改链表节点(part)信息。

注1:与数组的区别,数组数据区满时要扩充数据区空间;而链表每次要分配节点及其数据区。

注2:链表的每个节点(part)的数据区中可以放置1个或多个元素,这里的元素可以是一个整数,也可以是一个结构。

下图是一个有3个节点的链表的逻辑结构图。

list3bak

图中的线太多,容易眼晕,下面这个图可能好一些。

list4bak

3. 一个例子

理解并掌握开源软件的最好方式莫过于自己写一些测试代码,或者改写软件本身,并进行调试来进一步理解开源软件的原理和设计方法。本节给出一个创建内存池并从中分配一个链表的简单例子。在该例中,链表的每个节点(part)可存放5个元素,每个元素4字节大小,创建链表后,要向链表添加15个整型元素。

3.1代码

3.2如何编译

本文编写的makefile文件如下:

3.3运行结果

 

该例子中内存池和数组的(内存)物理结构可参考2.3节的图。

4. 小结

本文针对nginx-1.0.4的容器——链表结构进行了较为全面的分析,包括链表相关数据结构,链表创建和向链表中添加元素等。最后通过一个简单例子向读者展示nginx链表创建和添加元素操作,同时借此向读者展示编译测试代码的方法。

系列文章:

从开源代码Nginx中学习编码风格

nginx架构初探

Nginx高效数据结构(1)——数组(ngx_array_t)

Nginx高效数据结构(2)——链表(ngx_list_t)

Nginx高效数据结构(3)——队列(ngx_queue_t)

Nginx高效数据结构(4)——Hash表(ngx_hash_t)

Nginx高效数据结构(5)——内存池(ngx_pool_t)

作者:阿波

EDITED BY:快课(www.cricode.com)

本文链接:http://cricode.com/2972.html

转载请保留原始作者信息及本文链接,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值