您的位置:首页 > 理论基础 > 数据结构算法

Nginx 源码分析-- ngx_array、ngx_list基本数据结构

2012-06-10 10:40 567 查看
  应该说大家对这两个数据结构相当熟悉了,因此我们一并将它们进行分析,瞧一瞧nginx是如何实现它们的。在此篇之前,我们已经对nginx 内存池(pool)进行了分析,在此基础上来理解ngnix对它们的实现将变得非常简单,特别是内存池(pool)中的ngx_palloc 函数在这两个结构中多次用到,若不清楚想了解原理的可以看看我前面写的文章,它返回的是在内存池分配好空间了的首地址。

一、ngx_array 数组:

struct ngx_array_s {
void        *elts;
ngx_uint_t   nelts;
size_t       size;
ngx_uint_t   nalloc;
ngx_pool_t  *pool;
};


  参数说明:elts为array数组中元素的首地址,nelts数组中已分配的元素个数,size每个元素大小,nalloc数组容量,pool其所在的内存池。

  能够支持五种函数操作:

  创建数组:

    ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);

  数组初始化:

    ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size)

  数组注销:

    ngx_array_destroy(ngx_array_t *a);

  添加一个数组元素:

    ngx_array_push(ngx_array_t *a);

  添加n个数组元素:

    ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);

  ngx_array_create和ngx_array_init,代码比较简明就不多说了,值得注意的是两者之间的差别,ngx_array_init使用情形是已经存在了ngx_array_t的结构体,而ngx_array_create则从零开始建起,贴出代码:

View Code

void *
ngx_list_push(ngx_list_t *l)
{
void             *elt;
ngx_list_part_t  *last;

last = l->last;

if (last->nelts == l->nalloc) {

/* the last part is full, allocate a new list part */

last = ngx_palloc(l->pool, sizeof(ngx_list_part_t));
if (last == NULL) {
return NULL;
}

last->elts = ngx_palloc(l->pool, l->nalloc * l->size);
if (last->elts == NULL) {
return NULL;
}

last->nelts = 0;
last->next = NULL;

l->last->next = last;
l->last = last;
}

elt = (char *) last->elts + l->size * last->nelts;
last->nelts++;

return elt;
}


  一个主要的if解释如下,如果最后一个链表中的元素个数达到了最大,那么就需要扩充管理链表的链表;如果没有达到最大就正常分配节点单元。如图示1,便于理解

  



图1 ngx_list 结构示意图

  我们可以从图中看出,ngx_list 是一种链式存储和顺序储存相结合的链表结构,并不是像传统的链表结构。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: