一、ngx_queue_t双向链表

1.ngx_queue_t容器的优势在于:

1) 实现了排序功能;

2) 它非常轻量级,是一个纯粹的双向链表。它不负责链表元素所占内存的分配,与Nginx封装的ngx_pool_t内存池完全无关。

3) 支持两个链表间的合并。

typedef struct ngx_queue_s ngx_queue_t;struct ngx_queue_s {ngx_queue_t *prev;ngx_queue_t *next;
};

2.ngx_queue_t容器提供的操作方式

3.ngx_queue_t双向链表容器所支持的方法

方法名 参数含义 执行意义
ngx_queue_init(h) h为链表容器结构体ngx_queue_t的指针 将链表容器h初始化,这时会自动置为空链表
ngx_queue_empty(h) h为链表容器结构体ngx_queue_t的指针 检测链表容器中是否为空,即是否没有一个元素存在。如果返回非0,表示链表h是空的。
ngx_queue_insert_head(h, x) h为链表容器结构体ngx_queue_t的指针,x为插入元素结构体中ngx_queue_t成员的指针 将元素x插入到链表容器h的头部
ngx_queue_insert_tail(h, x) h为链表容器结构体ngx_queue_t的指针,x为插入元素结构体中ngx_queue_t成员的指针

将元素x添加到链表容器h的末尾

ngx_queue_head(h) h为链表容器结构体ngx_queue_t的指针 返回链表容器h中的第一个元素的ngx_queue_t结构体指针
ngx_queue_last(h) h为链表容器结构体ngx_queue_t的指针 返回链表容器中的最后一个元素的ngx_queue_t结构体指针
ngx_queue_sentinel(h) h为链表容器结构体ngx_queue_t的指针 返回链表容器结构体的指针
ngx_queue_remove(x) x为插入元素结构体中ngx_queue_t成员的指针 由容器中移除x元素
ngx_queue_split(h, q,n) h为链表容器结构体ngx_queue_t的指针 ngx_queue_split用于拆分链表,h是链表容器,而q是链表h中的一个元素。这个方法将链表h以元素q为界拆分成两个链表h和n,其中h由原链表的前半部分构成(不包括q),而n由原链表的后半部分构成,q是它的首元素。
ngx_queue_add(h, n) h为链表容器结构体ngx_queue_t的指针,n为另一个链表容器结构体ngx_queue_t的指针 合并链表,将n链表添加到h链表的末尾
ngx_queue_middle(h) h为链表容器结构体ngx_queue_t的指针 返回链表中心元素,如,链表共有N个元素,ng_queue_middle方法将返回第N/2+1个元素,例如,链表有4个元素,将会返回第3个元素(不是第2个元素)
ngx_queue_sort(h, cmpfunc) h为链表容器结构体ngx_queue_t的指针,cmpfunc是两个链表元素的比较方法,如果它返回正数,则表示以升序排序 使用插入排序法对链表进行排序,cmpfunc需要使用者自己实现,它的原型是这样的:ngx_int_t (*cmpfunc)(const ngx_queue_t *, const ngx_queue_t *)

4.  ngx_queue_t双向链表中的元素所支持的方法

方法名 参数含义 执行意义
ngx_queue_next(q) q为链表中某一个元素结构体的ngx_queue_t成员的指针 返回q元素的下一个元素
ngx_queue_prev(q) q为链表中某一个元素结构体的ngx_queue_t成员的指针 返回q元素的上一个元素
ngx_queue_data(q, type, link) q为链表中某一个元素结构体的ngx_queue_t成员的指针,type为链表元素的结构体类型名称(该结构体中必须包含ngx_queue_t类型的成员),lin开始上面这个结构体中ngx_queue_t类型的成员名字 返回q元素(ngx_queue_t类型)所属结构体(任何struct类型,其中可在任意位置包含ngx_queue_t类型的成员)的地址
ngx_queue_insert_after(q, x) q为链表中某个元素结构体的ngx_queue_t成员的指针,x为插入元素结构体中ngx_queue_t成员的指针 将元素x插入到元素q之后

5.空容器时ngx_queue_t结构体成员的值

6.当仅含1个元素时,容器、元素中的ngx_queue_t结构体成员的值

7.当含有两个或多个元素时,容器、元素中的ngx_queue_t结构体中prev、next成员的值

二、ngx_array_t动态数组

ngx_array_t是一个顺序容器,它在Nginx中大量使用。ngx_array_t容器以数组的形式存储元素,并支持在达到数组容量的上限时动态改变数组的大小。

优点:

1)访问速度快

2)允许元素个数具备不确定性;

3)负责元素占用内存的分配,这些内存将由内存池统一管理。

1.ngx_array_t动态数组的实现仅使用1个结构体,如下:

typedef struct ngx_array_s ngx_array_t;
struct ngx_array_s {//elts指向数组的首地址void *elts;//nelts是数组中已经使用的元素个数ngx_uint_t nelts;//每个数组元素占用的内存大小size_t size;//当前数组中能够容纳元素个数的总大小ngx_uint_t nalloc;//内存池对象ngx_pool_t *pool;
};

2.ngx_array_t动态数组结构体中的成员及其提供的方法

3.ngx_array_t动态数组提供的方法

三、ngx_list_t单向链表

相当于动态数组与单向链表的结合体。

四、ngx_rbtree_t红黑树

ngx_rbtree_t是使用红黑树实现的一种关联容器,Nginx的核心模块(如定时器管理、文件缓存模块等)在需要快速检索、查找的场合下都使用了ngx_rbtree_t容器。

顺序容器的检索效率通常情况下都比较差,一般只能遍历检索指定元素。当需要容器的检索速度很快,或者需要支持范围查询时,ngx_rbtree_t红黑树容器是一个非常好的选择。

什么是自平衡二叉查找树?在不断地向二叉查找树中添加、删除节点时,二叉查找树自身通过形态的变换,始终保持着一定程度上的平衡,即为自平衡二叉查找树。自平衡二叉查找树有许多种不同的实现方式,如AVL树和红黑树。红黑树是一种自平衡性较好的二叉查找树,它在Linux内核、C++的STL库等许多场合下都作为核心数据结构使用。

ngx_rbtree_t红黑树容器中的元素都是有序的,它支持快速的检索、插入、删除操作,也支持范围查询、遍历等操作,是一种应用场景非常广泛的高级数据结构。

红黑树是指每个节点都带有颜色属性的二叉查找树,其中颜色为红色或黑色。除了二叉查找树的一般要求以外,对于红黑树还有如下的额外的特性。

特性1:节点时红色或黑色。

特性2:根节点是黑色。

特性3:所有叶子节点都是黑色(叶子是NIL节点,也叫“哨兵”)。

特性4:每个红色节点的两个子节点都是黑色(每个叶子节点到根节点的所有路径上不能有两个连续的红色节点)>

特性5:从任一节点到其每个叶子节点的所有简单路径都包含相同数目的黑色节点。

1.ngx_rbtree_t红黑树的典型图示

2.红黑树节点的结构体及其提供的方法

3.ngx_rbtree_node_t结构体的定义

typedef struct ngx_rbtree_s ngx_rbtree_t;/*为解决不同节点含有相同关键字的元素冲突问题,红黑树设置了ngx_rbtree_insert_pt指针,这样可灵活地添加冲突元素 */
typedef void (*ngx_rbtree_insert_pt)(ngx_rbtree_node_t *root,ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);struct ngx_rbtree_s {//指向树的根节点。注意,根节点也是数据元素ngx_rbtree_node_t *root;//指向NIL哨兵节点ngx_rbtree_node_t *sentinel;//表示红黑树添加元素的函数指针,它决定在添加新节点时的行为究竟是替换还是新增ngx_rbtree_insert_pt insert;
};

ngx_rbtree_t结构体的root成员指向根节点,而sentinel成员指向哨兵节点。

4.Nginx为红黑树已经实现好的3种数据添加方法

5.ngx_str_rbtree_insert_value的实现

五、ngx_radix_tree_t基数树

详见资料

六、支持通配符的散列表

6.1 ngx_hash_t基本散列表

详见资料

6.2 支持通配符的散列表

详见资料

《深入理解Nginx 模块开发与架构解析》之高级数据结构摘录相关推荐

  1. 推荐我的新书《深入理解Nginx:模块开发与架构解析》

    http://www.china-pub.com/STATIC/zt_mb/zt_huodong_2013_3.asp?filename=2013_jsj_nginx_20130401 目录 < ...

  2. 《深入理解NGINX 模块开发与架构解析》之摘抄学习

    1.基于Nginx框架开发程序有5个优势: (1).Nginx将网络.磁盘及定时器等异步事件的驱动都做了非常好的封装,基于它开发将可以忽略这些事件处理的细节; (2).Nginx封装了许多平台无关的接 ...

  3. 深入理解Nginx 模块开发与架构解析-陶辉 读书笔记

    前言 1. nginx是一个优秀的事件驱动框架,nginx非常适合开发在传输层以TCP对外提供服务的服务器程序.基于nginx框架开发程序有5个优势: * nginx将网络.磁盘及定时器等异步事件的驱 ...

  4. 后台开发经典书籍--深入理解Nginx模块开发与架构

  5. 《深入理解Nginx:模块开发与架构解析》一3.3 如何将自己的HTTP模块编译进Nginx...

    3.3 如何将自己的HTTP模块编译进Nginx Nginx提供了一种简单的方式将第三方的模块编译到Nginx中.首先把源代码文件全部放到一个目录下,同时在该目录中编写一个文件用于通知Nginx如何编 ...

  6. 《深入理解Nginx-模块开发与架构解析》

    一.研究Nginx前的准备工作 1.常见负载均衡 1)Apache:被设计成了一个重量级的.不支持高并发的Web服务器 2)Lighttpd和Nginx都是轻量级.高性能的Web服务器:欧美前者用的多 ...

  7. 《深入理解Nginx:模块开发与架构解析》一1.2 为什么选择Nginx

    1.2 为什么选择Nginx 为什么选择Nginx?因为它具有以下特点: (1)更快 这表现在两个方面:一方面,在正常情况下,单次请求会得到更快的响应:另一方面,在高峰期(如有数以万计的并发请求),N ...

  8. 《深入理解Nginx:模块开发与架构解析》一1.6 Nginx的命令行控制

    1.6 Nginx的命令行控制 在Linux中,需要使用命令行来控制Nginx服务器的启动与停止.重载配置文件.回滚日志文件.平滑升级等行为.默认情况下,Nginx被安装在目录/usr/local/n ...

  9. 【Linux网络编程】Nginx -- 模块开发(upstream / subrequest)

    [Linux网络编程]Nginx -- 模块开发(upstream / subrequest) [1]upstream VS subrequest 简介 upstream 为访问上游服务器,它把Ngi ...

最新文章

  1. 跟我学Springboot开发后端管理系统7:Matrxi-Web权限设计
  2. 如何开好一个 OKR 评审会议?
  3. mke2fs和mkfs命令使用
  4. Leetcode 188.买卖股票的最佳时机IV
  5. python如何提交作业_用python 实现录入学生作业情况的小程序
  6. 计算机4级英语词汇,四级词汇,2020英语四级必背词汇?
  7. 前端如何引用字体文件
  8. sap--TCODE 之 SE93 将事务代码分配给程序(转)
  9. 回撤率 python_【Python量化】O(n)复杂度实现最大回撤的计算
  10. 商品订单管理系统(参考答案)
  11. Ubuntu下WIFI不稳定问题
  12. JTopo添加动态连线
  13. 关于BIRT的一些认识
  14. xampp 配置php版本,XAMPP各个版本配置
  15. 世界上最快的浏览器(mxnitro浏览器)
  16. 计算机编程课程顺序_您可以在八月开始学习450项免费的在线编程和计算机科学课程...
  17. 浙里办对接H5微应用遇到的问题
  18. Cornfields
  19. 新坑--阿里云图库引入
  20. 21 根火柴游戏(常胜将军)

热门文章

  1. MySQL(二)数据的检索和过滤
  2. Apache Spark概述
  3. CSS3属性之background
  4. 【一起去大厂系列】深入理解MySQL中where 1 = 1的用处
  5. Dev-Cpp 常用的快捷键(持续更新)
  6. [leetcode] 141.环形链表
  7. iphone文件访问ftp服务器,将文件上传到iPhone上的FTP服务器
  8. 华为鸿蒙OS合作方,华为发布鸿蒙OS元服务,超300家应用合作伙伴加入
  9. 64位jdk连接32位的mysql_在64位客户端使用32位的ODBC配置
  10. iis php mysql wiki_Windows下安装MediaWiki (iis+php+mysql+mediawiki)