PC6下载站

分类分类

nginx-1.0.4的容器源码分析—数组结构ngx_array_t

关注+2011-07-12作者:清晨

3 页 销毁数组
 

 2.2 销毁数组

 销毁数组的操作实现如下,包括销毁数组数据区和数组头。这里的销毁动作实际上就是修改内存池的last指针,并没有调用free等释放内存的操作,显然,这种维护效率是很高的。

view plaincopy to clipboardprint?
  1. void  
  2. ngx_array_destroy(ngx_array_t*a)  
  3. {  
  4.     ngx_pool_t *p;  
  5.    
  6.     p = a->pool;  
  7.    
  8.     if ((u_char *) a->elts+ a->size * a->nalloc == p->d.last) {  //先销毁数组数据区   
  9.         p->d.last -=a->size * a->nalloc;  //设置内存池的last指针   
  10.     }  
  11.    
  12.     if ((u_char *) a +sizeof(ngx_array_t) == p->d.last) {  //接着销毁数组头   
  13.         p->d.last = (u_char*) a;          //设置内存池的last指针   
  14.     }  
  15. }  

2.3 添加1个元素

 向数组添加元素的操作有两个,ngx_array_push和ngx_array_push_n,分别添加一个和多个元素。

 但实际的添加操作并不在这两个函数中完成,例如ngx_array_push返回可以在该数组数据区中添加这个元素的位置,ngx_array_push_n则返回可以在该数组数据区中添加n个元素的起始位置,而添加操作即在获得添加位置之后进行,如后文的例子。

view plaincopy to clipboardprint?
  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. }  

由此可见,向数组中添加元素实际上也是在修该内存池的last指针(若数组数据区满)及数组头信息,即使数组满了,需要扩展数据区内容,也只需要内存拷贝完成,并不需要数据的移动操作,这个效率也是相当高的。

展开全部

相关文章

更多+相同厂商

热门推荐

  • 最新排行
  • 最热排行
  • 评分最高
排行榜

    点击查看更多

      点击查看更多

        点击查看更多

        说两句网友评论

          我要评论...
          取消