二倍自动扩容自增的数组,类似stl的vector,使用pool分配,pool的d.last 指定了最后一个分配的页,
分配时优先从这个page中看有没有剩余的空间,如果有则直接从这里分配,没有的话就要二倍
递增,再次尝试分配
* Copyright (C) Igor Sysoev
*/
#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;
};
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_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;
array->nalloc = n;
array->pool = pool;
array->elts = ngx_palloc(pool, n * size);
if (array->elts == NULL)
{
return NGX_ERROR;
}
return NGX_OK;
}
#endif /* _NGX_ARRAY_H_INCLUDED_ */
/*
* Copyright (C) Igor Sysoev
*/
#include <ngx_config.h>
#include <ngx_core.h>
ngx_array_t *
ngx_array_create( ngx_pool_t *p, ngx_uint_t n, size_t size )
{
ngx_array_t *a;
a = ngx_palloc( p, sizeof(ngx_array_t) );
if (a == NULL)
{
return NULL;
}
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;
}
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;
}
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, *newp;
size_t size;
ngx_pool_t *p;
if ( a->nelts == a->nalloc )
{
/* the array is full */
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
*/
p->d.last += a->size;
a->nalloc++;
}
else
{
/* allocate a new array */
newp = ngx_palloc( p, 2 * size );
if ( newp == NULL )
{
return NULL;
}
ngx_memcpy( newp, a->elts, size );
a->elts = newp;
a->nalloc *= 2;
}
}
elt = (u_char *) a->elts + a->size * a->nelts;
a->nelts++;
return elt;
}
void *
ngx_array_push_n( ngx_array_t *a, ngx_uint_t n )
{
void *elt, *newp;
size_t size;
ngx_uint_t nalloc;
ngx_pool_t *p;
size = n * a->size;
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
*/
p->d.last += size;
a->nalloc += n;
}
else
{
/* allocate a new array */
nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
newp = ngx_palloc(p, nalloc * a->size);
if (newp == NULL)
{
return NULL;
}
ngx_memcpy(newp, a->elts, a->nelts * a->size);
a->elts = newp;
a->nalloc = nalloc;
}
}
elt = (u_char *) a->elts + a->size * a->nelts;
a->nelts += n;
return elt;
}