nginx学习七 高级数据结构之动态数组ngx_array_t
1 ngx_array_t結構
ngx_array_t是nginx內部使用的數組結構。nginx的數組結構在存儲上與大家認知的C語言內置的數組有相似性。比方實際上存儲數據的區域也是一大塊連續的內存。
可是數組除了存儲數據的內存以外還包括一些元信息來描寫敘述相關的一些信息,而且能夠動態增長。以下
我們從數組的定義上來具體的了解一下。
ngx_array_t的定義位于src/core/ngx_array.c|h里面。
struct ngx_array_s {void *elts;//數組的首地址ngx_uint_t nelts;//數組中已經使用的元素個數size_t size; //每一個元素占用的內存大小ngx_uint_t nalloc;//當前數組中可以容納元素的個數ngx_pool_t *pool; //內存池對象 }; elts指向存儲數據內存的起始地址。
nelts是數組中實際已經存儲的元素個數
size是每一個數組元素占用內存的大小。比方int占用4個字節的大小,size=4。
nalloc是數組空間大小。
pool成員函數負責管理數組使用的內存。
2函數操作
nginx為數組提供了五個操作函數例如以下:
//創建一個動態數組。數組的大小為n,每一個元素的大小為size
ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);
//銷毀已分配的動態數組元素空間和動態數組對象
void ngx_array_destroy(ngx_array_t *a);
//向數組中加入一個元素,返回這個新元素的地址。假設數組空間已經用完,數組會自己主動擴充空間
void *ngx_array_push(ngx_array_t *a);
//向數組中加入n個元素,返回這n個元素中第一個元素的地址
void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);
//和create函數的功能差點兒相同,僅僅只是這個array不能為空,返回值為是否初始化成功
static ngx_inline ngx_int_t
ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size)
2.1ngx_array_create
ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);
創建一個數組,p是內存池對象, n為數組存儲元素的個數, size為每一個元素占用的空間大小。
來看看源碼:
ngx_array_t * ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size) {ngx_array_t *a;//1:創建ngx_array_t指針。這個array的內存也是在p上申請的a = ngx_palloc(p, sizeof(ngx_array_t));if (a == NULL) {return NULL;}//2:申請數組存儲元素的內存a->elts = ngx_palloc(p, n * size);if (a->elts == NULL) {return NULL;}//初始化成員a->nelts = 0;a->size = size;a->nalloc = n;a->pool = p;return a;//返回數組指針 }
2.2 ngx_array_destroy
void ngx_array_destroy(ngx_array_t *a);
回收已分配給數組的內存,包含數組本身。看源碼:
void ngx_array_destroy(ngx_array_t *a) {ngx_pool_t *p;p = a->pool;//1:銷毀數組存儲元素的內存,即數據區的內存if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {p->d.last -= a->size * a->nalloc;}//2:銷毀數組本身的內存,即結構體array本身的內存//a = ngx_palloc(p, sizeof(ngx_array_t));這句代碼申請的內存if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {p->d.last = (u_char *) a;} }2.3 ngx_array_push
void *ngx_array_push(ngx_array_t *a);
向數組中加入元素。而且返回新添加元素的地址。看源代碼:
void * ngx_array_push(ngx_array_t *a) {void *elt, *new;size_t size;ngx_pool_t *p;if (a->nelts == a->nalloc) {//數組已滿size = a->size * a->nalloc;p = a->pool;if ((u_char *) a->elts + size == p->d.last&& p->d.last + a->size <= p->d.end)//假設p的剩余空間>=一個數組元素的空間。就分配一個空間給數組{p->d.last += a->size;//調整pool的last。即改動下一次可分配空間的事實上地址a->nalloc++;} else {new = ngx_palloc(p, 2 * size);//申請新的空間,大小是原來的2倍,假如pool的內存不足夠分配一個新的數組元素if (new == NULL) {return NULL;}ngx_memcpy(new, a->elts, size);//把原有的元素復制到新分配的內存區a->elts = new;//改動數組數據區的地址,使其指向新分配的內存區a->nalloc *= 2;//改動數組可容納的元素個數,是原來容納元素的2倍}}elt = (u_char *) a->elts + a->size * a->nelts;//新添加元素的地址a->nelts++;//數組中元素的個數加1return elt;//返回新添加元素的地址 }
調用這個函數并沒用真的加入進元素,它僅僅是返回新加元素將要被放入數組的地址,我們必須按例如以下操作才干真正的加入如元素:
//加入一個int元素 ngx_int_t* elem; elem = ngx_array_push(array);//得到新增元素地址 *elem = 10;
2.4ngx_array_push_n
void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);
向數組中加入n個元素。返回這n個元素中第一個元素的地址。
n : a->nalloc);//申請2倍的內存 new = ngx_palloc(p, nalloc * a->size); if (new == NULL) { return NULL; } ngx_memcpy(new, a->elts, a->nelts * a->size);//把原有的元素復制到新申請的內存中 a->elts = new;//改動數組元素區的地址 a->nalloc = nalloc;//改動數組可以容納的元素個數 } } elt = (u_char *) a->elts + a->size * a->nelts;//新增元素的首地址 a->nelts += n;//已存儲元素個數+n return elt; }
2.5 ngx_array_init
ngx_int_t ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size);
和create函數的功能差點兒相同,僅僅只是這個array不能為空,返回值為是否初始化成功
static ngx_inline ngx_int_t ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size) {/** set "array->nelts" before "array->elts", otherwise MSVC thinks* that "array->nelts" may be used without having been initialized*///初始化array,array不能為空array->nelts = 0;array->size = size;array->nalloc = n;array->pool = pool;array->elts = ngx_palloc(pool, n * size);//申請內存空間if (array->elts == NULL) {return NGX_ERROR;}return NGX_OK; }3 ngx_array_t的一個使用
void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);
http://blog.csdn.net/xiaoliangsky/article/details/39647771
總結
以上是生活随笔為你收集整理的nginx学习七 高级数据结构之动态数组ngx_array_t的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 推断股票强弱最有效的一个方法
- 下一篇: linux输入法