nginx源码分析--数组

来源:互联网 发布:凯立德端口波特率检测 编辑:程序博客网 时间:2024/04/30 19:47

ngx_array.h

/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */#ifndef _NGX_ARRAY_H_INCLUDED_#define _NGX_ARRAY_H_INCLUDED_#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; // 数组的内存是由哪个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);/*    数组初始化函数    @param array 储存数组元数据的结构体指针    @param pool 用于分配内存的pool    @param n 该数组分配共可以存储几个元素    @param size 该数组中每个元素的大小    @return NGX_OK | NGX_ERROR*/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->nelts = 0;     // 初始化数组中每个元素的大小    array->size = size;    // 数组可以储存n个size大小的元素    array->nalloc = n;    array->pool = pool;    // 给数组分配n*size大小的内存    array->elts = ngx_palloc(pool, n * size);    if (array->elts == NULL) {        return NGX_ERROR;    }    return NGX_OK;}#endif /* _NGX_ARRAY_H_INCLUDED_ */

ngx_array.c

/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */#include <ngx_config.h>#include <ngx_core.h>/*    创建数组函数    @param pool 用于分配内存的pool    @param n 该数组分配共可以存储几个元素    @param size 该数组中每个元素的大小    @return 存储数组元数据的ngx_array_t结构体*/ngx_array_t * ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size){    ngx_array_t *a;    // 在pool里给存储元数据的结构体分配内存    a = ngx_palloc(p, sizeof(ngx_array_t));    if (a == NULL) {        return NULL;    }    // 在pool里给数组分配内存,并用a->elts指向始地址    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;}/*    销毁数组函数 这个函数在nginx中并没有用到    @param a 储存数组元数据的结构体指针*/void ngx_array_destroy(ngx_array_t *a){    ngx_pool_t  *p;    p = a->pool;    // 判断是否p->last指针的值是否恰好等于数组的末地址,否则会”释放“数组和p->last之间的数据    if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {        p->d.last -= a->size * a->nalloc;    }    if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {        p->d.last = (u_char *) a;    }}/*    在原数组基础增加一个元素空间,如果原数组空间不够需要重新开辟内存    @param a 储存数组元数据的结构体指针    @return elt 新增内存的首地址*/void * ngx_array_push(ngx_array_t *a){    void        *elt, *new;    size_t       size;    ngx_pool_t  *p;    // 数组已存满了    if (a->nelts == a->nalloc) {        /* the array is full */        // 数组的总大小        size = a->size * a->nalloc;        p = a->pool;        // 如果数组的末地址和p->last指针相等并且追加size大小的空间后不会超过p->end,才能追加分配内存        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             */            // 在数组末地址处追加size大小的内存,并且nalloc+1表示数组可以数组可以储存的元素个数加1             p->d.last += a->size;            a->nalloc++;        }         // 如果数组满,并且无法追加内存时        else {            /* allocate a new array */            // 需要重新开辟大小为原来两倍的内存            new = ngx_palloc(p, 2 * size);            if (new == NULL) {                return NULL;            }            // 把原来的数据复制过去            ngx_memcpy(new, a->elts, size);            // 数组首地址指针指向新的内存地址            a->elts = new;            // 数组容量变为原来的两倍            a->nalloc *= 2;        }    }    /*        数组原来就有空间,或者数组已经存满并且追加内存分配成功,或者数组存满并重新开辟了内存,        a->elts + a->size * a->nelts都等于此时数组的第一个可用地址,也就是下一个数据可以由        这个地址开始存储,elt只需要指向此时的数组末地址就行,    */    elt = (u_char *) a->elts + a->size * a->nelts;    // 数组已存储的元素个数加一    a->nelts++;    // 返回数组第一个可用的内存地址,也就是下一个数据可以由这个地址开始存储    return elt;}/*    在原数组基础增加n个元素空间,如果原数组空间不够需要重新开辟内存    @param a 储存数组元数据的结构体指针    @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;    size = n * a->size;    // 数组增加n个元素后超过可存储元素的个数    if (a->nelts + n > a->nalloc) {        /* the array is full */        p = a->pool;        // 同ngx_array_push函数        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             */            p->d.last += size;            a->nalloc += n;        } else {            /* allocate a new array */            /*                如果追加的元素个数n比原来可存储的元素个数a->nalloc还大,否则开辟2*a->nalloc个空间可能还是比n小,                例如之前最大能存储5个,已经存储了2个,现在需要多存储12个,那么5*2<12,                ,所以需要重新开辟2*n个空间,保证能多存储n个元素,其他的同ngx_array_push函数。            */            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);            a->elts = new;            a->nalloc = nalloc;        }    }    elt = (u_char *) a->elts + a->size * a->nelts;    a->nelts += n;    return elt;}
0 0