nginx----queue
来源:互联网 发布:dsa p57 数据升级工具 编辑:程序博客网 时间:2024/06/04 22:16
1、数据结构
nginx中queue的数据结构非常简单,其中并不包含任何实际数据相关的结构,只有两个指针用于找到前后的元素。
struct ngx_queue_s { ngx_queue_t *prev; ngx_queue_t *next;};
2、基本操作
queue的操作也几乎都是通过宏定义来实现的,队列包含的具体操作如下:#define ngx_queue_init(q) //队列的初始化 #define ngx_queue_empty(h) //判断队列是否为空#define ngx_queue_insert_head(h, x) //在头节点后插入一个节点 #define ngx_queue_insert_tail(h, x) //在尾部节点后插入一个节点 #define ngx_queue_head(h) //返回队列的头节点 #define ngx_queue_last(h) //返回队列的尾部节点 #define ngx_queue_next(q) //返回q节点后面的一个节点 #define ngx_queue_prev(q) //返回q节点的前一个节点#define ngx_queue_remove(x) //将节点x从队列中移除#define ngx_queue_split(h, q, n) //分割队列 #define ngx_queue_add(h, n) //链接队列队列的这些操作与以前学过的链表的操作十分类似。除了上述操作外,链表还通过函数实现了获取中间节点以及队列排序。
获取中间节点:
ngx_queue_t *ngx_queue_middle(ngx_queue_t *queue){ ngx_queue_t *middle, *next; middle = ngx_queue_head(queue); if (middle == ngx_queue_last(queue)) { return middle; } next = ngx_queue_head(queue); for ( ;; ) { middle = ngx_queue_next(middle); next = ngx_queue_next(next); if (next == ngx_queue_last(queue)) { //偶数个节点,返回后半队列的第一个节点 return middle; } next = ngx_queue_next(next); if (next == ngx_queue_last(queue)) { //奇数个节点,返回中间节点 return middle; } }}有上述代码可知,middle和next初始时都是指向队列的头节点,而middle每次移动一个节点,next每次移动两个节点,则当next遍历完整个队列时,middle则刚好遍历到了队列的一半,即指向队列的中间节点。
eg:middle=2时,next=2或3;middle=3时,next=4或5;即当next指向最后一个节点时,middle总是指向中间节点,即第(totalNodeNum/2 + 1)个节点。当节点总数为奇数时,则恰好返回中间节点,当节点总数为偶数时,则返回后半部分的第一个节点。
上图分别对应了偶数个节点和奇数个节点的情况
队列排序:
voidngx_queue_sort(ngx_queue_t *queue, ngx_int_t (*cmp)(const ngx_queue_t *, const ngx_queue_t *)){ ngx_queue_t *q, *prev, *next; q = ngx_queue_head(queue); if (q == ngx_queue_last(queue)) { return; } for (q = ngx_queue_next(q); q != ngx_queue_sentinel(queue); q = next) { prev = ngx_queue_prev(q); next = ngx_queue_next(q); ngx_queue_remove(q); do { if (cmp(prev, q) <= 0) { //与前面已经排序好的节点相比较,找到合适的位置 break; } prev = ngx_queue_prev(prev); } while (prev != ngx_queue_sentinel(queue)); ngx_queue_insert_after(prev, q); //将节点插入到该位置中 }}队列排序是依次遍历队列中的每一个节点,将其插入到前面已经排好序的队列中,这是一种稳定的简单插入排序。
3、由于单纯的队列只是简单的构成队列,而不涉及数据部分的,因此当我们使用队列时,需要自己设计数据结构,在其中嵌入数据部分和队列。
一个简单的示意图如下:
队列在数据结构中间,上面或下面都可能存放其它数据。通过queue将所有节点链接起来。
可通过如下的宏定义获取队列节点数据
#define ngx_queue_data(q, type, link) \ (type *) ((u_char *) q - offsetof(type, link))其中q为指向queue的指针,type为自定义的嵌入了数据和队列的结构,link为queue结构在type结构中的名称
q减去queue在结构体中的偏移量即可得到指向type结构首地址的指针,然后通过(type *)类型转换即可得到type结构。如下图所示:
0 0
- nginx queue
- nginx----queue
- nginx源码----queue篇
- nginx -- datastruct:queue
- nginx queue设计
- Nginx:双向队列(Queue)
- 解码Nginx:双向队列(Queue)
- 【Nginx源码剖析-数据结构】双向链表(queue)【未完】
- Queue
- queue
- Queue
- QUEUE ~
- queue
- queue
- queue
- queue
- queue
- queue
- [Microsoft][ODBC 驱动程序管理器] 无效的描述器索引
- 存储一个图的内存开销
- uva 10905 Children's Game 儿童游戏
- GRE写作必备句型
- openrefactory/c之添加自反任务(四)
- nginx----queue
- 自动生成地图 物体 Generator
- shell学习四十五天----xargs
- wireshark
- 关于C++ const 的全面总结
- Effective OC : 1-5
- 兔子--android.view.windowmanager BadTokenException :unable to add window token null is not for applica
- AWK命令详解
- js中return的用法