nginx 源码学习笔记(八)——基本容器——array数组

来源:互联网 发布:网络威胁别人什么罪 编辑:程序博客网 时间:2024/05/16 12:55

对应文件为core/ngx_array.{c|h}

ngx_array是nginx内部封装的,使用ngx_pool_t对内存池进行分配的数组容器,其中的数据是在一整片内存区中连续存放的。更新数据时只能在尾部压入1个或多个元素。这里单纯的觉得和数组没有差别。

 

数组的实现结构为:

[cpp] view plaincopyprint?
  1. <span style="font-size:16px;">struct ngx_array_s {  
  2.     void        *elts;   //具体的数据区域的指针  
  3.     ngx_uint_t   nelts;   //数组实际包含的元素数量  
  4.     size_t       size;    //数组单个元素的大小  
  5.     ngx_uint_t   nalloc;   //数组容器预先(或者重新)分配的内存大小 !!!这部分为预计的存储元素数量!!!  
  6.     ngx_pool_t  *pool;    //分配的内存池  
  7. };  
  8. </span>  

常用操作有:

[cpp] view plaincopyprint?
  1. <span style="font-size:16px;">//创建数组  
  2. ngx_array_t *  
  3. ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)  
  4. {  
  5.     ngx_array_t *a;  
  6.   
  7.     a = ngx_palloc(p, sizeof(ngx_array_t));   //分配数组空间  
  8.     if (a == NULL) {  
  9.         return NULL;  
  10.     }  
  11.     a->elts = ngx_palloc(p, n * size);        //分配数据区域空间  
  12.     if (a->elts == NULL) {  
  13.         return NULL;  
  14.     }  
  15.     a->nelts = 0;                       //初始化信息  
  16.     a->size = size;  
  17.     a->nalloc = n;  
  18.     a->pool = p;  
  19.     return a;  
  20. }  
  21.   
  22. //摧毁数组  
  23. void  
  24. ngx_array_destroy(ngx_array_t *a)  
  25. {  
  26.     ngx_pool_t  *p;  
  27.     p = a->pool;  
  28.     if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {  //如果有数据 判断总数据量是否等于p追后地址  
  29.         p->d.last -= a->size * a->nalloc;     //如果等于,指针迁移总数据量位数即可  
  30.     }  
  31.     if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {     //如果没有数据  
  32.         p->d.last = (u_char *) a;                       //直接把指针移动到a的地址上  
  33.     }  
  34. }  
  35.   
  36. //  
  37. void *  
  38. ngx_array_push(ngx_array_t *a)  
  39. {  
  40.     void        *elt, *new;  
  41.     size_t       size;  
  42.     ngx_pool_t  *p;  
  43.     if (a->nelts == a->nalloc) {                         //数组已经存满  
  44.         /* the array is full */  
  45.         size = a->size * a->nalloc;  
  46.         p = a->pool;  
  47.         if ((u_char *) a->elts + size == p->d.last          //如果总数据量等于last地址,并且新加的数据在可用范围内  
  48.             && p->d.last + a->size <= p->d.end)  
  49.         {  
  50.             /* 
  51.              * the array allocation is the last in the pool 
  52.              * and there is space for new allocation 
  53.              */  
  54.             p->d.last += a->size;                    //last后移  
  55.             a->nalloc++;                          //总数据量增加  
  56.         } else {  
  57.             /* allocate a new array */               //如果不是,创建新的内存空间  
  58.             new = ngx_palloc(p, 2 * size);            //创建一个两倍大小的内存空间  
  59.             if (new == NULL) {  
  60.                 return NULL;  
  61.             }  
  62.             ngx_memcpy(new, a->elts, size);        //复制到新的内存空间  
  63.             a->elts = new;                       //指向新地址  
  64.             a->nalloc *= 2;                       //可容纳总数量*2  
  65.         }  
  66.     }  
  67.     elt = (u_char *) a->elts + a->size * a->nelts;        //新指针用于返回  
  68.     a->nelts++;                                  //实际数量增加  
  69.     return elt;                                  //返回指针指向的地址,这里只进行内存分配,还需要对返回的新指针进行赋值,等操作才可以实现数组的添加,这里要特殊注意  
  70. }  
  71. //void * ngx_array_push_n(ngx_array_t *a, ngx_uint_t n) //对于这个函数就不多讲了  
  72.   
  73. </span>  


总结:

ngx_array_create 在未创建ngx_array_t结构体时创建数组
ngx_array_init 在创建ngx_array_t结构体后创建数组
ngx_array_destroy 销毁数组
ngx_array_push 在数组中压入一个数据,得到一个数据指针,在这里就不用再分配内存了,可以直接使用分配的内存

ngx_array_push_n 在数组中压入 n个数据,得到一个数据指针,在这里就不用再分配内存了,可以直接使用分配的内存

0 0