nginx学习七 高级数据结构之动态数组ngx_array_t
1 ngx_array_t結(jié)構(gòu)
ngx_array_t是nginx內(nèi)部使用的數(shù)組結(jié)構(gòu)。nginx的數(shù)組結(jié)構(gòu)在存儲(chǔ)上與大家認(rèn)知的C語(yǔ)言?xún)?nèi)置的數(shù)組有相似性。比方實(shí)際上存儲(chǔ)數(shù)據(jù)的區(qū)域也是一大塊連續(xù)的內(nèi)存。
可是數(shù)組除了存儲(chǔ)數(shù)據(jù)的內(nèi)存以外還包括一些元信息來(lái)描寫(xiě)敘述相關(guān)的一些信息,而且能夠動(dòng)態(tài)增長(zhǎng)。以下
我們從數(shù)組的定義上來(lái)具體的了解一下。
ngx_array_t的定義位于src/core/ngx_array.c|h里面。
struct ngx_array_s {void *elts;//數(shù)組的首地址ngx_uint_t nelts;//數(shù)組中已經(jīng)使用的元素個(gè)數(shù)size_t size; //每一個(gè)元素占用的內(nèi)存大小ngx_uint_t nalloc;//當(dāng)前數(shù)組中可以容納元素的個(gè)數(shù)ngx_pool_t *pool; //內(nèi)存池對(duì)象 }; elts指向存儲(chǔ)數(shù)據(jù)內(nèi)存的起始地址。
nelts是數(shù)組中實(shí)際已經(jīng)存儲(chǔ)的元素個(gè)數(shù)
size是每一個(gè)數(shù)組元素占用內(nèi)存的大小。比方int占用4個(gè)字節(jié)的大小,size=4。
nalloc是數(shù)組空間大小。
pool成員函數(shù)負(fù)責(zé)管理數(shù)組使用的內(nèi)存。
2函數(shù)操作
nginx為數(shù)組提供了五個(gè)操作函數(shù)例如以下:
//創(chuàng)建一個(gè)動(dòng)態(tài)數(shù)組。數(shù)組的大小為n,每一個(gè)元素的大小為size
ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);
//銷(xiāo)毀已分配的動(dòng)態(tài)數(shù)組元素空間和動(dòng)態(tài)數(shù)組對(duì)象
void ngx_array_destroy(ngx_array_t *a);
//向數(shù)組中加入一個(gè)元素,返回這個(gè)新元素的地址。假設(shè)數(shù)組空間已經(jīng)用完,數(shù)組會(huì)自己主動(dòng)擴(kuò)充空間
void *ngx_array_push(ngx_array_t *a);
//向數(shù)組中加入n個(gè)元素,返回這n個(gè)元素中第一個(gè)元素的地址
void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);
//和create函數(shù)的功能差點(diǎn)兒相同,僅僅只是這個(gè)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);
創(chuàng)建一個(gè)數(shù)組,p是內(nèi)存池對(duì)象, n為數(shù)組存儲(chǔ)元素的個(gè)數(shù), size為每一個(gè)元素占用的空間大小。
來(lái)看看源碼:
ngx_array_t * ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size) {ngx_array_t *a;//1:創(chuàng)建ngx_array_t指針。這個(gè)array的內(nèi)存也是在p上申請(qǐng)的a = ngx_palloc(p, sizeof(ngx_array_t));if (a == NULL) {return NULL;}//2:申請(qǐng)數(shù)組存儲(chǔ)元素的內(nèi)存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;//返回?cái)?shù)組指針 }
2.2 ngx_array_destroy
void ngx_array_destroy(ngx_array_t *a);
回收已分配給數(shù)組的內(nèi)存,包含數(shù)組本身。看源碼:
void ngx_array_destroy(ngx_array_t *a) {ngx_pool_t *p;p = a->pool;//1:銷(xiāo)毀數(shù)組存儲(chǔ)元素的內(nèi)存,即數(shù)據(jù)區(qū)的內(nèi)存if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {p->d.last -= a->size * a->nalloc;}//2:銷(xiāo)毀數(shù)組本身的內(nèi)存,即結(jié)構(gòu)體array本身的內(nèi)存//a = ngx_palloc(p, sizeof(ngx_array_t));這句代碼申請(qǐng)的內(nèi)存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);
向數(shù)組中加入元素。而且返回新添加元素的地址。看源代碼:
void * ngx_array_push(ngx_array_t *a) {void *elt, *new;size_t size;ngx_pool_t *p;if (a->nelts == a->nalloc) {//數(shù)組已滿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)//假設(shè)p的剩余空間>=一個(gè)數(shù)組元素的空間。就分配一個(gè)空間給數(shù)組{p->d.last += a->size;//調(diào)整pool的last。即改動(dòng)下一次可分配空間的事實(shí)上地址a->nalloc++;} else {new = ngx_palloc(p, 2 * size);//申請(qǐng)新的空間,大小是原來(lái)的2倍,假如pool的內(nèi)存不足夠分配一個(gè)新的數(shù)組元素if (new == NULL) {return NULL;}ngx_memcpy(new, a->elts, size);//把原有的元素復(fù)制到新分配的內(nèi)存區(qū)a->elts = new;//改動(dòng)數(shù)組數(shù)據(jù)區(qū)的地址,使其指向新分配的內(nèi)存區(qū)a->nalloc *= 2;//改動(dòng)數(shù)組可容納的元素個(gè)數(shù),是原來(lái)容納元素的2倍}}elt = (u_char *) a->elts + a->size * a->nelts;//新添加元素的地址a->nelts++;//數(shù)組中元素的個(gè)數(shù)加1return elt;//返回新添加元素的地址 }
調(diào)用這個(gè)函數(shù)并沒(méi)用真的加入進(jìn)元素,它僅僅是返回新加元素將要被放入數(shù)組的地址,我們必須按例如以下操作才干真正的加入如元素:
//加入一個(gè)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);
向數(shù)組中加入n個(gè)元素。返回這n個(gè)元素中第一個(gè)元素的地址。
n : a->nalloc);//申請(qǐng)2倍的內(nèi)存 new = ngx_palloc(p, nalloc * a->size); if (new == NULL) { return NULL; } ngx_memcpy(new, a->elts, a->nelts * a->size);//把原有的元素復(fù)制到新申請(qǐng)的內(nèi)存中 a->elts = new;//改動(dòng)數(shù)組元素區(qū)的地址 a->nalloc = nalloc;//改動(dòng)數(shù)組可以容納的元素個(gè)數(shù) } } elt = (u_char *) a->elts + a->size * a->nelts;//新增元素的首地址 a->nelts += n;//已存儲(chǔ)元素個(gè)數(shù)+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函數(shù)的功能差點(diǎn)兒相同,僅僅只是這個(gè)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);//申請(qǐng)內(nèi)存空間if (array->elts == NULL) {return NGX_ERROR;}return NGX_OK; }3 ngx_array_t的一個(gè)使用
void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);
http://blog.csdn.net/xiaoliangsky/article/details/39647771
總結(jié)
以上是生活随笔為你收集整理的nginx学习七 高级数据结构之动态数组ngx_array_t的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 推断股票强弱最有效的一个方法
- 下一篇: Distributed Systems-