[筆記] 解碼Nginx:列表(List)

樑濤發表於2012-11-25

解碼Nginx:列表(List)

樑濤(@無鋒之刃)
2012-11-25

nginx-1.2.5

原始碼檔案

src/core/ngx_list.h
src/core/ngx_list.c

設計思路

Nginx實現的列表接近於陣列,但有三點區別:

  1. 可以在指定記憶體塊上建立列表資料結構;
  2. 儲備元素區中無空閒元素時,分配新的儲備元素區,掛到單向連結串列中,而不是替換掉舊的,在擴充容量的同時減少記憶體處理次數;
  3. 不提供ngx_list_destroy(),完全依靠底層記憶體池管理記憶體。

列表適用於元素較大、或元素生命週期較長,擴充儲備元素區會跨越記憶體池中多個ngx_pool_data_t結構體的場景。

資料結構

        ngx_list_create(pool, n, size)           ngx_list_push()                 ...
         |                                        |
         +- ngx_palloc()---------\                +- ngx_palloc()--\
         |                       |                |                |
         \- ngx_palloc()----------------\         \- ngx_palloc()---------\
                                 |      |                          |      |
          ngx_list_t             V      |                          |      |
         +-----------------------+      |                          |      |
         | last                  | --\  |                          |      |
         +-----------------------+   |  |                          |      |
         | ngx_list_part_t part  |   |  |        ngx_list_part_t   V      |
         |  +--------------------+   +--------> +------------------+      |  /-> ...
  /------+- | elts               |   |  |   /-- | elts             |      |  |
  |      |  +--------------------+   |  |   |   +------------------+      |  |
  |      |  | netls              |   |  |   |   | netls            | --\  |  |
  |      |  +--------------------+   |  |   |   +------------------+   |  |  |
  |      |  | next               | --/  |   |   | next             | --------/
  |      +-----------------------+      |   |   +------------------+   |  |
  |  /-- | size            bytes |      |   |                          |  |
  |  |   +-----------------------+      |   |                          |  |
  |  |   | nalloc            = n | --\  |   |                          |  |
  |  |   +-----------------------+   |  |   |                          |  |
  |  |   | pool                  |   |  |   |                          |  |
  |  |   +-----------------------+   |  |   |                          |  |
  |  |                               |  |   |                          |  |
  |  |                               |  |   |                          |  |
  |  |                           /------/   |                      /------/
  |  |                           |   |      |                      |   | 
  |  |                           V   |      |                      V   | 
  \----> +-----------------------+  -+-     \-> +------------------+  -+-
     |   | elem 0                |   A          | elem 5           |   A 
     |   /                       /   |          /                  /   | 
     |   /                       /   |          /                  /   | 
     |   |                       |   |          |                  |   | 
     |   +-----------------------+   |          +------------------+   | 
     |   | elem 1                |   |          | elem 6           |   | 
     |   /                       /   |          /                  /   | 
     |   /                       /   |          /                  /   | 
     |   |                       |   |          |                  |   | 
    -+-  +-----------------------+   |          +------------------+   | 
     A   | elem 2                |   |          | elem 7           |   | 
     |   /                       /   |          /                  /   | 
     |   /                       /   |          /                  /   | 
     V   |                       |   |          |                  |   V 
    ---  +-----------------------+   |          +------------------+  ---
         | elem 3                |   |          | unpushed         |
         /                       /   |          / elements         /
         /                       /   |          /                  /
         |                       |   |          /                  /
         +-----------------------+   |          /                  /
         / elem 4                /   |          /                  /
         /                       /   |          /                  /
         |                       |   V          |                  |
         +-----------------------+  ---         +------------------+

介面函式

ngx_list_create(pool, n, size)

ngx_list_create()負責動態建立一個列表,動作序列如下:

  1. 從pool中分配ngx_list_t結構體;
  2. 從pool中分配能容納n個size大小的元素的儲備元素區塊;
  3. 適當地初始化ngx_list_t結構體。

ngx_list_init(pool, n, size)

ngx_list_create()負責在給定的記憶體塊上建立一個列表,動作序列如下:

  1. 從pool中分配能容納n個size大小的元素的儲備元素區塊;
  2. 適當地初始化ngx_list_t結構體。

ngx_list_push(list)

ngx_list_push()負責向陣列中“壓入”一個元素(實際為取得一個空元素的首址),動作序列如下:

  1. 若列表中還有空元素,直接取得其首址並返回;
  2. 分配新的ngx_list_part_t結構體和儲備元素區塊,將結構體追加到列表單向連結串列尾部後分配新的空元素並返回。

相關文章