分类分类
关注+2011-07-12作者:清晨
2.2 销毁数组
销毁数组的操作实现如下,包括销毁数组数据区和数组头。这里的销毁动作实际上就是修改内存池的last指针,并没有调用free等释放内存的操作,显然,这种维护效率是很高的。
void ngx_array_destroy(ngx_array_t*a) { ngx_pool_t *p; p = a->pool; if ((u_char *) a->elts+ a->size * a->nalloc == p->d.last) { //先销毁数组数据区 p->d.last -=a->size * a->nalloc; //设置内存池的last指针 } if ((u_char *) a +sizeof(ngx_array_t) == p->d.last) { //接着销毁数组头 p->d.last = (u_char*) a; //设置内存池的last指针 } }
2.3 添加1个元素
向数组添加元素的操作有两个,ngx_array_push和ngx_array_push_n,分别添加一个和多个元素。
但实际的添加操作并不在这两个函数中完成,例如ngx_array_push返回可以在该数组数据区中添加这个元素的位置,ngx_array_push_n则返回可以在该数组数据区中添加n个元素的起始位置,而添加操作即在获得添加位置之后进行,如后文的例子。
void * ngx_array_push(ngx_array_t*a) { void *elt, *new; size_t size; ngx_pool_t *p; if (a->nelts ==a->nalloc) { //数组数据区满 /* the arrayis full */ size = a->size *a->nalloc; //计算数组数据区的大小 p = a->pool; if ((u_char *)a->elts + size == p->d.last //若内存池的last指针指向数组数据区的末尾 &&p->d.last + a->size <= p->d.end) //且内存池未使用的区域可以再分配一个size大小的小空间 { /* * the array allocation is the lastin the pool * and there is space for newallocation */ p->d.last +=a->size; //分配一个size大小的小空间(a->size为数组一个元素的大小) a->nalloc++; //实际分配小空间的个数加1 } else { /* allocate a new array */ new =ngx_palloc(p, 2 * size); //否则,扩展数组数据区为原来的2倍 if (new == NULL) { return NULL; } ngx_memcpy(new,a->elts, size);//将原来数据区的内容拷贝到新的数据区 a->elts = new; a->nalloc *= 2; //注意:此处转移数据后,并未释放原来的数据区,内存池将统一释放 } } elt = (u_char *)a->elts + a->size * a->nelts; //数据区中实际已经存放数据的子区的末尾 a->nelts++; //即最后一个数据末尾,该指针就是下一个元素开始的位置 return elt; //返回该末尾指针,即下一个元素应该存放的位置 }
由此可见,向数组中添加元素实际上也是在修该内存池的last指针(若数组数据区满)及数组头信息,即使数组满了,需要扩展数据区内容,也只需要内存拷贝完成,并不需要数据的移动操作,这个效率也是相当高的。
相关文章
更多+相同厂商
热门推荐
点击查看更多
点击查看更多
点击查看更多
说两句网友评论