標籤:des style color io ar for sp 檔案 資料
數組標頭檔
ngx_array.h
#include <ngx_config.h>#include <ngx_core.h>struct ngx_array_s { void *elts; ngx_uint_t nelts; size_t size; ngx_uint_t nalloc; ngx_pool_t *pool;};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);void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);// 初始化似乎沒什麼好說的static ngx_inline ngx_int_tngx_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->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;}
數組源檔案
ngx_array.c
#include <ngx_config.h>#include <ngx_core.h>/* 建立一個 Nginx 數組,記憶體池地址為 p,元素個數為 n,每個元素大小為 size */ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size){ ngx_array_t *a; // 調用 ngx_palloc,從 記憶體池 p,為 Nginx 數組 a 分配記憶體 a = ngx_palloc(p, sizeof(ngx_array_t)); if (a == NULL) { return NULL; } // 調用 ngx_palloc,為 Nginx 數組 a 的 elts 分配記憶體,大小為 n * size 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;}voidngx_array_destroy(ngx_array_t *a){ ngx_pool_t *p; // 數組 a 的記憶體池地址 p = a->pool; // 數組 a 的最大儲存區的末尾,到了記憶體池的已用地區的末尾(可用性區域的開頭) // 即表示記憶體池目前最後一段儲存的是一個數組的儲存區 if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) { // 記憶體池已用地區末尾向前挪(每個元素大小 x 最大元素個數)位元組 p->d.last -= a->size * a->nalloc; } // 數組 a 結構體所佔用記憶體的末尾,為記憶體池的可用性區域的開頭 // 即表示記憶體池目前最後一段儲存的是一個數組的結構體 if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) { p->d.last = (u_char *) a; } // 上面先剪掉資料存放區區,再剪掉定義結構區}void *ngx_array_push(ngx_array_t *a){ void *elt, *new; size_t size; ngx_pool_t *p; // 數組滿了,即已儲存元素數 nelts 已達到最大容納數 nalloc if (a->nelts == a->nalloc) { /* the array is full */ // size 為數組的最大容量(最大容納數 x 每個元素大小) 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) { /* * the array allocation is the last in the pool * and there is space for new allocation */ // 分配一個元素,就得把 last 往下挪一個,即已用地區往下挪一個 p->d.last += a->size; // 分配一個元素,且記憶體池沒滿,就得把“最大元素數”加1 a->nalloc++; } else { // 記憶體池剩餘空間不夠 /* allocate a new array */ // 分配一個兩倍的空間(原來空間的兩倍) new = ngx_palloc(p, 2 * size); if (new == NULL) { return NULL; } // 把 a->elts 的東東拷貝到 new 裡,拷貝 size 位元組個資料 ngx_memcpy(new, a->elts, size); a->elts = new; // 新地址 a->nalloc *= 2; // 新最大容量 // size 不變(最大容量,即單個元素大小 x 最大元素數) // pool 不變 // nelts 已用元素數不變 } } // elt 為已用資料區的末尾 elt = (u_char *) a->elts + a->size * a->nelts; // 已存資料個數加 1 a->nelts++; // 返回這個已用資料區的末尾(可用資料區的開頭,或者說是下一個元素可以用的位置) return elt;}void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n){ void *elt, *new; size_t size; ngx_uint_t nalloc; ngx_pool_t *p; // 要放的 n 個元素所佔的總位元組數 size = n * a->size; // 已存元素數 + 要存的 n 個元素 > 最大容量(最大元素數) if (a->nelts + n > a->nalloc) { /* the array is full */ p = a->pool; // 數組的資料存放區區的末尾,到達了記憶體池的已用地區的末尾 // 且,記憶體池的已用地區末尾的下一個位置<=記憶體池的末尾,就是說記憶體池還有夠用的剩餘空間 if ((u_char *) a->elts + a->size * a->nalloc == p->d.last && p->d.last + size <= p->d.end) { /* * the array allocation is the last in the pool * and there is space for new allocation */ // 分配 n 個元素,就得把 last 往後挪 size = n * a->size p->d.last += size; // 分配 n 個元素,且記憶體池沒滿,就得把“最大元素數(最大容量)”加 n a->nalloc += n; } else { // 記憶體池剩餘空間不夠 /* allocate a new array */ // 準備分配一個兩倍的空間,nalloc是新空間的大小 // (如果原來最大容量大,則分配原來空間的兩倍;如果新要的n個元素更多,則分配n的兩倍) nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc); // 分配新空間 new = ngx_palloc(p, nalloc * a->size); if (new == NULL) { return NULL; } // 把老空間的東東,拷貝到新空間 ngx_memcpy(new, a->elts, a->nelts * a->size); // elts 新空間地址 a->elts = new; // nalloc 數組最大容量 a->nalloc = nalloc; } } // 要放入的 n 個元素的起始位置 elt = (u_char *) a->elts + a->size * a->nelts; // 已用元素數加 n a->nelts += n; // 返回n個東東的位置 return elt;}
Nginx源碼完全注釋(2)ngx_array.h / ngx_array.c