10Sigor@sysoev.ru
20Sigor@sysoev.ru /*
30Sigor@sysoev.ru * Copyright (C) Igor Sysoev
40Sigor@sysoev.ru * Copyright (C) NGINX, Inc.
50Sigor@sysoev.ru */
60Sigor@sysoev.ru
70Sigor@sysoev.ru #include <nxt_main.h>
80Sigor@sysoev.ru
90Sigor@sysoev.ru
100Sigor@sysoev.ru nxt_array_t *
nxt_array_create(nxt_mp_t * mp,nxt_uint_t n,size_t size)1165Sigor@sysoev.ru nxt_array_create(nxt_mp_t *mp, nxt_uint_t n, size_t size)
120Sigor@sysoev.ru {
130Sigor@sysoev.ru nxt_array_t *array;
140Sigor@sysoev.ru
1565Sigor@sysoev.ru array = nxt_mp_alloc(mp, sizeof(nxt_array_t) + n * size);
160Sigor@sysoev.ru
170Sigor@sysoev.ru if (nxt_slow_path(array == NULL)) {
180Sigor@sysoev.ru return NULL;
190Sigor@sysoev.ru }
200Sigor@sysoev.ru
2198Svbart@nginx.com array->elts = nxt_pointer_to(array, sizeof(nxt_array_t));
220Sigor@sysoev.ru array->nelts = 0;
230Sigor@sysoev.ru array->size = size;
240Sigor@sysoev.ru array->nalloc = n;
250Sigor@sysoev.ru array->mem_pool = mp;
260Sigor@sysoev.ru
270Sigor@sysoev.ru return array;
280Sigor@sysoev.ru }
290Sigor@sysoev.ru
300Sigor@sysoev.ru
31146Smax.romanov@nginx.com void
nxt_array_destroy(nxt_array_t * array)32146Smax.romanov@nginx.com nxt_array_destroy(nxt_array_t *array)
33146Smax.romanov@nginx.com {
34146Smax.romanov@nginx.com if (array->elts != nxt_pointer_to(array, sizeof(nxt_array_t))) {
35146Smax.romanov@nginx.com nxt_mp_free(array->mem_pool, array->elts);
36146Smax.romanov@nginx.com }
37146Smax.romanov@nginx.com
38146Smax.romanov@nginx.com nxt_mp_free(array->mem_pool, array);
39146Smax.romanov@nginx.com }
40146Smax.romanov@nginx.com
41146Smax.romanov@nginx.com
420Sigor@sysoev.ru void *
nxt_array_add(nxt_array_t * array)430Sigor@sysoev.ru nxt_array_add(nxt_array_t *array)
440Sigor@sysoev.ru {
450Sigor@sysoev.ru void *p;
460Sigor@sysoev.ru uint32_t nalloc, new_alloc;
470Sigor@sysoev.ru
480Sigor@sysoev.ru nalloc = array->nalloc;
490Sigor@sysoev.ru
500Sigor@sysoev.ru if (array->nelts == nalloc) {
510Sigor@sysoev.ru
520Sigor@sysoev.ru if (nalloc < 16) {
530Sigor@sysoev.ru /* Allocate new array twice larger than current. */
54*1563Svbart@nginx.com new_alloc = (nalloc == 0) ? 4 : nalloc * 2;
550Sigor@sysoev.ru
560Sigor@sysoev.ru } else {
570Sigor@sysoev.ru /* Allocate new array 1.5 times larger than current. */
580Sigor@sysoev.ru new_alloc = nalloc + nalloc / 2;
590Sigor@sysoev.ru }
600Sigor@sysoev.ru
6165Sigor@sysoev.ru p = nxt_mp_alloc(array->mem_pool, array->size * new_alloc);
620Sigor@sysoev.ru
630Sigor@sysoev.ru if (nxt_slow_path(p == NULL)) {
640Sigor@sysoev.ru return NULL;
650Sigor@sysoev.ru }
660Sigor@sysoev.ru
670Sigor@sysoev.ru nxt_memcpy(p, array->elts, array->size * nalloc);
680Sigor@sysoev.ru
69146Smax.romanov@nginx.com if (array->elts != nxt_pointer_to(array, sizeof(nxt_array_t))) {
70146Smax.romanov@nginx.com nxt_mp_free(array->mem_pool, array->elts);
71146Smax.romanov@nginx.com }
7265Sigor@sysoev.ru
730Sigor@sysoev.ru array->elts = p;
740Sigor@sysoev.ru array->nalloc = new_alloc;
750Sigor@sysoev.ru }
760Sigor@sysoev.ru
7798Svbart@nginx.com p = nxt_pointer_to(array->elts, array->size * array->nelts);
780Sigor@sysoev.ru array->nelts++;
790Sigor@sysoev.ru
800Sigor@sysoev.ru return p;
810Sigor@sysoev.ru }
820Sigor@sysoev.ru
830Sigor@sysoev.ru
840Sigor@sysoev.ru void *
nxt_array_zero_add(nxt_array_t * array)850Sigor@sysoev.ru nxt_array_zero_add(nxt_array_t *array)
860Sigor@sysoev.ru {
870Sigor@sysoev.ru void *p;
880Sigor@sysoev.ru
890Sigor@sysoev.ru p = nxt_array_add(array);
900Sigor@sysoev.ru
910Sigor@sysoev.ru if (nxt_fast_path(p != NULL)) {
920Sigor@sysoev.ru nxt_memzero(p, array->size);
930Sigor@sysoev.ru }
940Sigor@sysoev.ru
950Sigor@sysoev.ru return p;
960Sigor@sysoev.ru }
970Sigor@sysoev.ru
980Sigor@sysoev.ru
990Sigor@sysoev.ru void
nxt_array_remove(nxt_array_t * array,void * elt)1000Sigor@sysoev.ru nxt_array_remove(nxt_array_t *array, void *elt)
1010Sigor@sysoev.ru {
1020Sigor@sysoev.ru void *last;
1030Sigor@sysoev.ru
1040Sigor@sysoev.ru last = nxt_array_last(array);
1050Sigor@sysoev.ru
1060Sigor@sysoev.ru if (elt != last) {
1070Sigor@sysoev.ru nxt_memcpy(elt, last, array->size);
1080Sigor@sysoev.ru }
1090Sigor@sysoev.ru
1100Sigor@sysoev.ru array->nelts--;
1110Sigor@sysoev.ru }
1121489St.nateldemoura@f5.com
1131489St.nateldemoura@f5.com
1141489St.nateldemoura@f5.com nxt_array_t *
nxt_array_copy(nxt_mp_t * mp,nxt_array_t * dst,nxt_array_t * src)1151489St.nateldemoura@f5.com nxt_array_copy(nxt_mp_t *mp, nxt_array_t *dst, nxt_array_t *src)
1161489St.nateldemoura@f5.com {
1171489St.nateldemoura@f5.com void *data;
1181489St.nateldemoura@f5.com uint32_t i, size;
1191489St.nateldemoura@f5.com
1201489St.nateldemoura@f5.com size = src->size;
1211489St.nateldemoura@f5.com
1221489St.nateldemoura@f5.com if (dst == NULL) {
1231489St.nateldemoura@f5.com dst = nxt_array_create(mp, src->nelts, size);
1241489St.nateldemoura@f5.com if (nxt_slow_path(dst == NULL)) {
1251489St.nateldemoura@f5.com return NULL;
1261489St.nateldemoura@f5.com }
1271489St.nateldemoura@f5.com }
1281489St.nateldemoura@f5.com
1291489St.nateldemoura@f5.com nxt_assert(size == dst->size);
1301489St.nateldemoura@f5.com
1311489St.nateldemoura@f5.com if (dst->nalloc >= src->nelts) {
1321489St.nateldemoura@f5.com nxt_memcpy(dst->elts, src->elts, src->nelts * size);
1331489St.nateldemoura@f5.com
1341489St.nateldemoura@f5.com } else {
1351489St.nateldemoura@f5.com nxt_memcpy(dst->elts, src->elts, dst->nelts * size);
1361489St.nateldemoura@f5.com
1371489St.nateldemoura@f5.com for (i = dst->nelts; i < src->nelts; i++) {
1381489St.nateldemoura@f5.com data = nxt_array_add(dst);
1391489St.nateldemoura@f5.com if (nxt_slow_path(data == NULL)) {
1401489St.nateldemoura@f5.com return NULL;
1411489St.nateldemoura@f5.com }
1421489St.nateldemoura@f5.com
1431489St.nateldemoura@f5.com nxt_memcpy(data, src->elts + (i * size), size);
1441489St.nateldemoura@f5.com }
1451489St.nateldemoura@f5.com }
1461489St.nateldemoura@f5.com
1471489St.nateldemoura@f5.com dst->nelts = src->nelts;
1481489St.nateldemoura@f5.com
1491489St.nateldemoura@f5.com return dst;
1501489St.nateldemoura@f5.com }
151