Nginx源码分析—数组结构ngx

    xiaoxiao2021-03-25  74

    .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是一个顺序容器,支持达到数组容量上限时动态改变数组大小,具备以下特性:

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

    转载请注明原文地址: https://ju.6miu.com/read-39364.html

    最新回复(0)