解码Nginx:数组(Array)

来源:互联网 发布:2016年网络交易额 编辑:程序博客网 时间:2024/05/22 03:11

源码文件

src/core/ngx_array.h
src/core/ngx_array.c

设计思路

数组是非常常用的数据结构。为降低使用时的时间开销,Nginx对数组设计做了不少简化:

  1. 使用从给定内存池中预分配好的储备元素区块;
  2. 储备元素区块无空闲元素供分配时,尝试从原内存池中分配新的空闲元素,或扩充储备元素区块以完成分配;
  3. “分配”,或“压入”,只是取得新的空闲元素的首址,不负责创建实际元素;
  4. “释放”只是调整原内存池的字段,不负责清理实际元素,或者干脆推迟释放时机;
  5. 使用者可以直接访问数组的各个字段,以取得最佳性能。

数组适用于元素较小、或元素生命周期较短,扩充储备元素区不会跨越内存池中多个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()负责动态创建一个数组,动作序列如下:

  1. 从pool中分配ngx_array_t结构体;
  2. 从pool中分配能容纳n个size大小的元素的储备元素区块;
  3. 适当地初始化ngx_array_t结构体。

ngx_array_destroy(array)

ngx_array_destroy()负责“释放”数组使用的内存块(实际为推迟释放时机),但不清理其中的各个元素。动作序列如下:

  1. 如果储备元素区块位于pool的末尾,直接移动pool->current->d.last指针,指向“释放”后的地址;
  2. 如果ngx_array_t结构体位于pool的末尾,直接移动pool->current->d.lat指针,指向“释放”后的地址;
  3. 否则什么也不做。

ngx_array_push(array)/ngx_array_push_n(array, n)

ngx_array_push()负责向数组中“压入”一个元素(实际为取得一个空闲元素的首址),动作序列如下:

  1. 若数组中还有空闲元素,直接取得其首址并返回;
  2. 若数组的储备元素区块位于pool的储备内存块中最末位置,且其还有size大小的剩余空间,则直接分配新的空闲元素并返回;
  3. 重新分配新的储备元素区块(原区块的2倍大小)并复制已有元素,将新区块首址存入elts字段后分配新的空闲元素并返回。

ngx_array_push_n()与前者相似,可以一次返回n个新的空闲元素的切片首址。


转自:http://www.ituring.com.cn/article/19056  

其他资料 :

http://blog.csdn.net/livelylittlefish/article/details/6599056

http://blog.csdn.net/sunhappy2200/article/details/5915189

原创粉丝点击