Nginx源码分析—数组结构ngx_array_t

来源:互联网 发布:假面骑士ghost 知乎 编辑:程序博客网 时间:2024/05/16 18:44

.Nginx源码分析—数组结构ngx_array_t

    ngx_array_t结构:

    struct ngx_array_s{

        void  *elts;//数组数据区起始位置

        ngx_uint_t   netls;//数据区实际存放的元素个数;

        size_t       size;//每一个元素的个数;

        ngx_uint_t   nalloc;//数组所含空间个数,即实际分配的小空间个数;

        ngx_pool_t   *pool;//该数组在此内存池中分配;

};



数组的相关操作:

(1)创建数组:

ngx_array_t*  ngx_array_create(ngx_pool_t *p,ngx_uint_tn,size_t size)


(2)初始化数组:

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


(3)向数组中添加元素;

Void*ngx_array_push(ngx_array_t *a);

向数组中添加一个元素,返回在该数据区添加该元素的位置;

[cpp] view plain copy

1.  void *  

2. ngx_array_push(ngx_array_t*a)  

3.  {  

4.     void       *elt, *new;  

5.      size_t      size;  

6.     ngx_pool_t *p;  

7.     

8.     if (a->nelts ==a->nalloc) {  //数组数据区满  

9.     

10.        /* the arrayis full */  

11.    

12.        size = a->size *a->nalloc;  //计算数组数据区的大小  

13.    

14.        p = a->pool;  

15.    

16.        if ((u_char *)a->elts + size == p->d.last  //若内存池的last指针指向数组数据区的末尾  

17.             &&p->d.last + a->size <= p->d.end) //且内存池未使用的区域可以再分配一个size大小的小空间  

18.        {  

19.             /* 

20.             * the array allocation is the lastin the pool 

21.              * and there is space for newallocation 

22.             */  

23.    

24.            p->d.last +=a->size;  //分配一个size大小的小空间(a->size为数组一个元素的大小)  

25.             a->nalloc++;           //实际分配小空间的个数加1  

26.   

27.         } else {  

28.            /* allocate a new array */  

29.    

30.            new =ngx_palloc(p, 2 * size);  //否则,扩展数组数据区为原来的2  

31.             if (new == NULL) {  

32.                return NULL;  

33.             }  

34.   

35.             ngx_memcpy(new,a->elts, size);//将原来数据区的内容拷贝到新的数据区  

36.            a->elts = new;  

37.             a->nalloc *= 2;             //注意:此处转移数据后,并未释放原来的数据区,内存池将统一释放  

38.        }  

39.     }  

40.   

41.     elt = (u_char *)a->elts + a->size * a->nelts; //数据区中实际已经存放数据的子区的末尾  

42.    a->nelts++;                                  //即最后一个数据末尾,该指针就是下一个元素开始的位置  

43.    

44.    return elt;    //返回该末尾指针,即下一个元素应该存放的位置  

45. }  

Void *ngx_array_push_n(ngx_array_t*a,ngx_uint_t n);

向数组中添加n个元素,返回在该数据区添加n个元素的首位置;


Add元素小结:判断数据区是否已经满,若满,判断内存池last指针是否指向数据区的末尾位置,并且如果last指向末尾,再判断未用的内存部分是否够size,若够,nalloc++,否则,扩展数组数据区为原来的2倍

(4)销毁数组

Voidngx_array_destroy(ngx_array_t *a);

销毁数组的数组头部和数组的数据区

此处的销毁并没有用free等释放函数,只是改变了内存池中last的位置,维护效率更高。

ngx_array_t是一个顺序容器,支持达到数组容量上限时动态改变数组大小,具备以下特性:

下标直接索引,访问速度快,动态增长,由内存池统一管理分配出的内存,效率高。

1 0
原创粉丝点击