[筆記] 解碼Nginx:陣列(Array)
解碼Nginx:陣列(Array)
樑濤(@無鋒之刃)
2012-11-24 ~ 2012-11-25
nginx-1.2.5
原始碼檔案
src/core/ngx_array.h
src/core/ngx_array.c
設計思路
陣列是非常常用的資料結構。為降低使用時的時間開銷,Nginx對陣列設計做了不少簡化:
- 使用從給定記憶體池中預分配好的儲備元素區塊;
- 儲備元素區塊無空閒元素供分配時,嘗試從原記憶體池中分配新的空閒元素,或擴充儲備元素區塊以完成分配;
- “分配”,或“壓入”,只是取得新的空閒元素的首址,不負責建立實際元素;
- “釋放”只是調整原記憶體池的欄位,不負責清理實際元素,或者乾脆推遲釋放時機;
- 使用者可以直接訪問陣列的各個欄位,以取得最佳效能。
陣列適用於元素較小、或元素生命週期較短,擴充儲備元素區不會跨越記憶體池中多個ngx_pool_data_t結構體的場景。
資料結構
ngx_array_create(pool, n, size) ngx_array_push()/ ...
| ngx_array_push_n()
| |
+- ngx_palloc()-----\ /---?- ngx_palloc()------\
| | | |
\- ngx_palloc()-------------------\ | |
| | | |
ngx_array_t V | | |
+-------------------+ | | |
/----- | elts | ======================\ |
| +-------------------+ | | H |
| | nelts | -------\ | | H |
| +-------------------+ | | | H |
| /-- | size bytes | | | | H |
| | +-------------------+ | | | H |
| | | nalloc = n | --\ | | | H |
| | +-------------------+ | | | | H |
| | | pool | | | | | H |
| | +-------------------+ | | | | H |
| | | | | | H |
| | | | | | H |
| | /-------------/ | H |
| | | | | | H |
| | | | | | H |
| | V | | | V V
\----> +-------------------+ -+- -+- | +-------------------+
| | elem 0 | A A | | elem 0 |
| / / | | | / /
| / / | | | / /
| | | | | | | |
| +-------------------+ | | | +-------------------+
| | elem 1 | | | | | elem 1 |
| / / | | | / /
| / / | | | / /
| | | | | | | |
-+- +-------------------+ | | | +-------------------+
A | elem 2 | | | | | elem 2 |
| / / | | | / /
| / / | | | / /
V | | | V | | |
--- +-------------------+ | --- | +-------------------+
| unpushed | | | | elem 3 |
/ elements / | | / /
/ / | | / /
/ / | | | |
/ / | | +-------------------|
/ / | | | elem 4 |
/ / | | / /
/ / | | / /
| | V | | |
+-------------------+ --- <----------/ +-------------------+
| extended | | elem 5 |
/ area / / /
/ (in place) / / /
/ / | /
/ / +-------------------|
/ / | unpushed |
/ / / elements /
/ / / /
| = size * n | | |
+-------------------+ +-------------------+
介面函式
ngx_array_create(pool, n, size)
ngx_array_create()負責動態建立一個陣列,動作序列如下:
- 從pool中分配ngx_array_t結構體;
- 從pool中分配能容納n個size大小的元素的儲備元素區塊;
- 適當地初始化ngx_array_t結構體。
ngx_array_destroy(array)
ngx_array_destroy()負責“釋放”陣列使用的記憶體塊(實際為推遲釋放時機),但不清理其中的各個元素。動作序列如下:
- 如果儲備元素區塊位於pool的末尾,直接移動pool->current->d.last指標,指向“釋放”後的地址;
- 如果ngx_array_t結構體位於pool的末尾,直接移動pool->current->d.lat指標,指向“釋放”後的地址;
- 否則什麼也不做。
ngx_array_push(array)/ngx_array_push_n(array, n)
ngx_array_push()負責向陣列中“壓入”一個元素(實際為取得一個空閒元素的首址),動作序列如下:
- 若陣列中還有空閒元素,直接取得其首址並返回;
- 若陣列的儲備元素區塊位於pool的儲備記憶體塊中最末位置,且其還有size大小的剩餘空間,則直接分配新的空閒元素並返回;
- 重新分配新的儲備元素區塊(原區塊的2倍大小)並複製已有元素,將新區塊首址存入elts欄位後分配新的空閒元素並返回。
ngx_array_push_n()與前者相似,可以一次返回n個新的空閒元素的切片首址。
相關文章
- Array陣列陣列
- JavaScript Array 陣列JavaScript陣列
- JS 陣列筆記JS陣列筆記
- GO 筆記-陣列Go筆記陣列
- 陣列筆記1陣列筆記
- Ruby 札記 - Ruby 集合家族之陣列(Array)陣列
- day05陣列array陣列
- 內建物件--Array(陣列)物件陣列
- IOS筆記之陣列iOS筆記陣列
- 【筆記】字尾陣列筆記陣列
- JavaScript筆記(6)陣列JavaScript筆記陣列
- jQuery遍歷array陣列元素程式碼例項jQuery陣列
- JavaScript中陣列Array.sort()排序方法詳解JavaScript陣列排序
- 圖解:什麼是旋轉陣列(Rotate Array)?圖解陣列
- JavaScript刪除array陣列元素JavaScript陣列
- LeetCode Shuffle an Array(打亂陣列)LeetCode陣列
- Knockout Observable Array(監控陣列)陣列
- TPU &“脈動陣列”(systolic array)陣列
- 瞭解下C# 陣列(Array)C#陣列
- C++ ——vector陣列筆記C++陣列筆記
- 【筆記/模板】樹狀陣列筆記陣列
- Java 學習筆記 二維陣列和物件陣列Java筆記陣列物件
- linux Shell 命令列-03-array Shell 陣列Linux命令列陣列
- Array.apply生成陣列小結APP陣列
- Go 基礎教程--6 陣列 ArrayGo陣列
- Go 基礎教程--5 陣列 ArrayGo陣列
- 雙陣列字典樹(Double Array Trie)陣列
- PHP陣列函式-array_mapPHP陣列函式
- 字尾陣列 學習筆記陣列筆記
- 字尾陣列學習筆記陣列筆記
- c++筆記_多維陣列C++筆記陣列
- JavaScript 學習筆記 - 多維陣列變為一維陣列JavaScript筆記陣列
- JS陣列Array的全部方法彙總JS陣列
- Array · 刪除陣列中指定的元素陣列
- JS常用陣列方法總結筆記JS陣列筆記
- Nginx 原始碼分析:ngx_array_tNginx原始碼
- javascript 陣列(array) 常用的方法集錦(上)JavaScript陣列
- 二維陣列排序函式array_multisort()陣列排序函式
- Array · 判斷某元素是否在陣列中陣列