中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

在線咨詢網(wǎng)站模板做app推廣去哪找商家

在線咨詢網(wǎng)站模板,做app推廣去哪找商家,wordpress retina,公司seo排名優(yōu)化目錄 一、基本概述 二、數(shù)據(jù)結(jié)構(gòu) 三、接口描述與實現(xiàn) 1、相關(guān)宏接口 2、ngx_queue_middle 3、ngx_queue_sort 四、使用案例 整理自 nginx 1.9.2 源碼 和 《深入理解 Nginx:模塊開發(fā)與架構(gòu)解析》 一、基本概述 雙向鏈表的優(yōu)勢是可以快速進行數(shù)據(jù)插入、刪除與…

目錄

一、基本概述

二、數(shù)據(jù)結(jié)構(gòu)

三、接口描述與實現(xiàn)

1、相關(guān)宏接口

2、ngx_queue_middle

3、ngx_queue_sort

四、使用案例


整理自 nginx 1.9.2 源碼 和 《深入理解 Nginx:模塊開發(fā)與架構(gòu)解析》

一、基本概述

雙向鏈表的優(yōu)勢是可以快速進行數(shù)據(jù)插入、刪除與合并操作,但其查詢操作沒有數(shù)組性能高。

nginx 下 ngx_queue_t 還具備如下優(yōu)點:

(1)實現(xiàn)了排序功能;

(2)不負責(zé)節(jié)點元素的內(nèi)存分配操作,只提供輕量級的節(jié)點管理功能;

(3)內(nèi)存空間占用較小,每個節(jié)點元素只占用兩個指針的內(nèi)存損耗;

二、數(shù)據(jù)結(jié)構(gòu)

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

????????Nginx 在設(shè)計 ngx_queue_t 時,由于容器與元素共用了 ngx_queue_t 結(jié)構(gòu)體,為了避免 ngx_queue_t 結(jié)構(gòu)體成員的意義混亂,Nginx封裝了鏈表容器與元素的所有方法,這種情況非常少見,其他容器都需要直接使用成員變量來訪問,唯有 ngx_queue_t 雙向鏈表只能使用 API 接口進行數(shù)據(jù)訪問。

三、接口描述與實現(xiàn)

????????接口大多使用宏進行封裝。

1、相關(guān)宏接口

// 初始化鏈表容器 q,并置為空
#define ngx_queue_init(q)                                                     \(q)->prev = q;                                                            \(q)->next = q// 檢測鏈表容器是否為空,返回結(jié)果為 0 表示鏈表為空
#define ngx_queue_empty(h)                                                    \(h == (h)->prev)// 將 x 節(jié)點插到 h 節(jié)點的后面一位
#define ngx_queue_insert_head(h, x)                                           \(x)->next = (h)->next;                                                    \(x)->next->prev = x;                                                      \(x)->prev = h;                                                            \(h)->next = x// 將 x 節(jié)點插入 q 節(jié)點之后,此處可以直接復(fù)用 ngx_queue_insert_head
#define ngx_queue_insert_after   ngx_queue_insert_head// 將 x 插入 h 節(jié)點前面,鏈表首尾相連
#define ngx_queue_insert_tail(h, x)                                           \(x)->prev = (h)->prev;                                                    \(x)->prev->next = x;                                                      \(x)->next = h;                                                            \(h)->prev = x// 	返回鏈表容器 h 中的第一個元素節(jié)點 ngx_queue_t 指針
#define ngx_queue_head(h)                                                     \(h)->next//	返回鏈表容器 h 中最后一個元素節(jié)點 ngx_queue_t 指針
#define ngx_queue_last(h)                                                     \(h)->prev//	返回容器鏈表結(jié)構(gòu)體的指針
#define ngx_queue_sentinel(h)                                                 \(h)//	返回 q 元素的下一個元素
#define ngx_queue_next(q)                                                     \(q)->next// 返回 q 元素的前一個元素
#define ngx_queue_prev(q)                                                     \(q)->prev// 從鏈表中移除 x 節(jié)點,注意因為是雙向鏈表,所以只需要 x 節(jié)點作為參數(shù)即可
#define ngx_queue_remove(x)                                                   \(x)->next->prev = (x)->prev;                                              \(x)->prev->next = (x)->next/* h 為鏈表容器,q 為鏈表 h 中的一個元素,這個方法可以將鏈表 h 以元素 q 為界拆分為兩個鏈表 h 和n,其中 h 由原鏈表的前半部分組成(不包含 q),而 n 由后半部分組成,q 為首元素,如果以前 n 有成員,則新的 n 為從 h 中拆分的部分加上 n 原有的數(shù)據(jù) 
*/
#define ngx_queue_split(h, q, n)                                              \(n)->prev = (h)->prev;                                                    \(n)->prev->next = n;                                                      \(n)->next = q;                                                            \(h)->prev = (q)->prev;                                                    \(h)->prev->next = h;                                                      \(q)->prev = n;// 將鏈表 n 合并到 h 鏈表的末尾
#define ngx_queue_add(h, n)                                                   \(h)->prev->next = (n)->next;                                              \(n)->next->prev = (h)->prev;                                              \(h)->prev = (n)->prev;                                                    \(h)->prev->next = h;/*返回 q 元素(ngx_queue_t類型)所屬結(jié)構(gòu)體的地址。q 為鏈表中某個節(jié)點指針 ngx_queue_t 類型;type 為鏈表元素的結(jié)構(gòu)體類型名稱(該結(jié)構(gòu)體中必須包含 ngx_queue_t 類型的成員);1ink 是上面這個結(jié)構(gòu)體中 ngx_queue_t 類型的成員名字;例如:typedef struct {u_char* str;ngx_queue_t qEle;int num;} TestNode;
*//* Offset of member MEMBER in a struct of type TYPE. */
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define ngx_queue_data(q, type, link)                                         \(type *) ((u_char *) q - offsetof(type, link))

2、ngx_queue_middle

????????返回鏈表的中心元素,例如鏈表共有 N 個元素,則 ngx_queue_middle 將返回第(N/2 + 1)個元素。

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);/*middle 指針每次循環(huán)探索一步、next 指針每次循環(huán)探索兩步;當(dāng) next 抵達鏈表尾部時,middle 正好在鏈表中心位置。*/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;}}
}

3、ngx_queue_sort

void
ngx_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);// q 節(jié)點是當(dāng)前需要排序的節(jié)點ngx_queue_remove(q); // 下面循環(huán)將決定把 q 節(jié)點插入到什么位置;// 從 q 節(jié)點的前面節(jié)點開始比較,找到合適的位置再插入。do {// 自定義排序函數(shù),可以降序或升序if (cmp(prev, q) <= 0) {break;}prev = ngx_queue_prev(prev);} while (prev != ngx_queue_sentinel(queue)); //查找這個元素需要插入到前面依據(jù)拍好序的隊列的那個地方// 找到合適位置后插入該節(jié)點ngx_queue_insert_after(prev, q);}
}

四、使用案例

????????定義一個簡單的鏈表,并使用 ngx_queue_sort 方法對所有元素排序。在這個例子中,可以看到如何定義、初始化 ngx_queue_t 容器,如何定義任意類型的鏈表元素,如何遍歷鏈表,如何自定義排序方法并執(zhí)行排序。

// 鏈表元素結(jié)構(gòu)體中必須包含 ngx_queue_t 類型的成員,它可以在任意位置
typedef struct 
{u_char* str;ngx_queue_t qEle;int num;
} TestNode;// 升序排序
ngx_int_t compTestNode(const ngx_queue_t* a, const ngx_queue_t* b)
{/*首先使用 ngx_queue_data 方法由 ngx_queue_t 變量獲取元素結(jié)構(gòu)體 TestNode 的地址 */TestNode* aNode = ngx_queue_data(a, TestNode, qEle);TestNode* bNode = ngx_queue_data(b, TestNode, qEle);//返回 num 成員的比較結(jié)果return aNode->num > bNode->num;
}// 定義雙向鏈表容器 queueContainer,并將其初始化為空鏈表
// 注意,ngx_queue_t 結(jié)構(gòu)體遍歷必須使用 ngx_queue_init 初始化
ngx_queue_t queueContainer;
ngx_queue_init(&queueContainer);

? ? ngx_queue_t 雙向鏈表是完全不負責(zé)分配內(nèi)存的,每一個鏈表元素必須自己管理自己所占用的內(nèi)存。因此,本例在進程棧中定義了 5 個 TestNode 結(jié)構(gòu)體作為鏈表元素,并把它們的 num 成員初始化為 0,1,2,3,4, 如下所示。

int i = 0;
TestNode node[5];
for (; i <5; i++)
{node[i].num = i;
}

????????下面把這 5 個 TestNode 結(jié)構(gòu)體添加到 queueContainer 鏈表中,注意,這里同時使用了ngx_queue_insert_tail、ngx_queue_insert_head、ngx_queue_insert_after 3 個添加方法,鏈表中元素順序以 num 標(biāo)識應(yīng)該為:3、1、0、2、4。

ngx_queue_insert_tail(&queueContainer, &node[0] qEle);
ngx_queue_insert_head(&queueContainer, &node[1].qEle);
ngx_queue_insert_tail(&queueContainer, &node[2].qEle);
// 在頭節(jié)點之后插入
ngx_queue_insert_after(&queueContainer, &node[3].qEle);
ngx_queue_insert_tail(&queueContainer, &node[4].qEle);

????????先排序,再從鏈表頭部遍歷到鏈表尾部。反向遍歷可以使用 ngx_queue_last 和 ngx_queue_prev 實現(xiàn)。

// 升序排序
ngx_queue_sort(&queueContainer, compTestNode);
// 遍歷鏈表
ngx_queue_t* q;
for (q = ngx_queue_head(&queueContainer); q != ngx_queue_sentinel(&queueContainer);q = ngx_queue_next(q))
{TestNode* eleNode = ngx_queue_data(q, TestNode, qEle);// 處理當(dāng)前的鏈表元素 eleNode// ...
}

使用案例還可以參考:Nginx 源碼學(xué)習(xí)-ngx的基本容器-ngx_queue-xueliangfei-ChinaUnix博客

http://www.risenshineclean.com/news/27544.html

相關(guān)文章:

  • 網(wǎng)站建設(shè)模板網(wǎng)站排名優(yōu)化快速
  • 自建個人網(wǎng)站怎么自己創(chuàng)建一個網(wǎng)頁
  • wordpress 游戲模版seo輿情優(yōu)化
  • crm管理seo培訓(xùn)一對一
  • 做網(wǎng)站應(yīng)注意什么新網(wǎng)域名注冊查詢
  • 寶安商城網(wǎng)站建設(shè)哪家便宜百度搜索引擎平臺
  • 興化網(wǎng)站建設(shè)推廣軟文發(fā)布平臺
  • 做任務(wù)得傭金的網(wǎng)站seo綜合查詢中的具體內(nèi)容有哪些
  • 怎么做免費的網(wǎng)站推廣高級seo
  • oa軟件開發(fā)定制seo求職
  • 網(wǎng)站文字設(shè)計搜索引擎營銷sem包括
  • 一個公司多個網(wǎng)站做優(yōu)化今天新聞頭條
  • 網(wǎng)站建設(shè)與維護作業(yè)東莞seo計費管理
  • 網(wǎng)站建設(shè)推廣怎么做百度旗下產(chǎn)品
  • 建設(shè)網(wǎng)站后怎么發(fā)布長沙網(wǎng)絡(luò)推廣公司
  • 網(wǎng)站打開的速度慢網(wǎng)絡(luò)營銷的工具和方法有哪些
  • wordpress儀表盤文件目錄seo挖關(guān)鍵詞
  • 微信小程序怎么做購物網(wǎng)站推廣普通話的宣傳內(nèi)容
  • 創(chuàng)業(yè) 做網(wǎng)站培訓(xùn)心得簡短200字
  • 邱縣網(wǎng)站建設(shè)今日國內(nèi)新聞大事20條
  • 四川省建設(shè)資格注冊中心網(wǎng)站重慶seo公司怎么樣
  • 龍巖做網(wǎng)站多少錢競價網(wǎng)絡(luò)推廣外包
  • 網(wǎng)站制作那家便宜網(wǎng)絡(luò)營銷有哪些推廣方式
  • 營銷微網(wǎng)站建設(shè)公司seo推廣方案怎么做
  • 網(wǎng)站顯示內(nèi)容不顯示企業(yè)營銷推廣怎么做
  • 貴陽模板建站定制做seo必須有網(wǎng)站嗎
  • 隨州做網(wǎng)站的公司全網(wǎng)關(guān)鍵詞云怎么查
  • 如何將自己做的網(wǎng)站發(fā)布鄭州網(wǎng)站建設(shè)推廣有限公司
  • wordpress安裝dplayerseo免費外鏈工具
  • 做平臺交易網(wǎng)站怎么收款優(yōu)化網(wǎng)站教程