Nginx高级数据结构总结之 ngx_queue_t 双向链表

来源:互联网 发布:大数据 维基百科 编辑:程序博客网 时间:2024/05/22 10:46

Nginx高级数据结构总结之 ngx_queue_t 双向链表

          

一、前言

在Nginx的基础上开发新的功能模块时,有些功能使用Nginx的高级数据结构会起到事半功倍的效果。链表作为顺序容器的优势在于,它可以高效地执行插入、删除、 合并等操作,在移动链表中的元素时只需要修改指针的指向,因此,它很适合频繁修改容器的场合。

 

二、ngx_queue_t 使用

2.1)ngx_queue_t 简要说明

           ngx_queue_t双向链表只使用了一个结构体,该结构体只有两个成员:prev,next。如下所示:

           typedefstruct ngx_queue_s  ngx_queue_t;

 

struct ngx_queue_s {

    ngx_queue_t  *prev;

    ngx_queue_t  *next;

};

详情可以参考Nginx源码文件src/core/ngx_queue.h文件。

 

2.2)ngx_queue_t 双向链表函数说明




以上截图出自《深入理解Nginx》

 

 

2.3)ngx_queue_t 双向链表函数使用例子

 

 

//定义一个结构体做为链表元素

typedef struct {

   ngx_queue_t ele;

   int num;

} TestNode;

 

ngx_int_t compTestNode(const ngx_queue_t*a, const ngx_queue_t* b)

{

/*⾸先使⽤ngx_queue_data⽅法由ngx_queue_t变量获取元素结构体TestNode的地址*/

   TestNode* aNode = ngx_queue_data(a, TestNode, ele);

   TestNode* bNode = ngx_queue_data(b, TestNode, ele);

// 返回num成员的⽐较结果

   return aNode->num < bNode->num;

}

 

 

 

           //新建链表

   ngx_queue_t queueContainer;

    //初始化

ngx_queue_init(&queueContainer);

 

           //创建测试链表元素

   int i = 0;

   TestNode node[5];

   for (; i < 5; i++)

    {

       node[i].num = i;

    }

          

           //添加元素

   ngx_queue_insert_tail(&queueContainer, &node[0].ele);

   ngx_queue_insert_tail(&queueContainer, &node[1].ele);

   ngx_queue_insert_tail(&queueContainer, &node[2].ele);

   ngx_queue_insert_tail(&queueContainer, &node[3].ele);

   ngx_queue_insert_tail(&queueContainer, &node[4].ele);

 

           //排序(降序)

   ngx_queue_sort(&queueContainer,compTestNode);

   ngx_queue_t* q;

 

          

           //判断链表是否为空

   if(ngx_queue_empty(&queueContainer) !=0){

 

       return NGX_ERROR;

}

 

//遍历链表

   for (q = ngx_queue_head(&queueContainer);

        q != ngx_queue_sentinel(&queueContainer);

        q = ngx_queue_next(q))

    {

       TestNode* eleNode = ngx_queue_data(q, TestNode, ele);

       printf("node value %d \n",eleNode->num);

    }

 

 

ngx_queue_tsplitQue;

//初始化

ngx_queue_init(&splitQue);

 

//链表拆分

   ngx_queue_split(&queueContainer,&node[3].ele,&splitQue);

 

           //遍历拆分后的链表

   for (q = ngx_queue_head(&splitQue);

        q != ngx_queue_sentinel(&splitQue);

        q = ngx_queue_next(q))

    {

       TestNode* eleNode = ngx_queue_data(q, TestNode, ele);

       printf("after split node value %d \n",eleNode->num);

}

 


 

测试结果:

node value 4

node value 3

node value 2

node value 1

node value 0

after split nodevalue 3

after split nodevalue 2

after split nodevalue 1

after split nodevalue 0

三、参考文献

           《深入理解Nginx》