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 * 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 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 * 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. */ 540Sigor@sysoev.ru new_alloc = 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 * 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 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 } 112*1489St.nateldemoura@f5.com 113*1489St.nateldemoura@f5.com 114*1489St.nateldemoura@f5.com nxt_array_t * 115*1489St.nateldemoura@f5.com nxt_array_copy(nxt_mp_t *mp, nxt_array_t *dst, nxt_array_t *src) 116*1489St.nateldemoura@f5.com { 117*1489St.nateldemoura@f5.com void *data; 118*1489St.nateldemoura@f5.com uint32_t i, size; 119*1489St.nateldemoura@f5.com 120*1489St.nateldemoura@f5.com size = src->size; 121*1489St.nateldemoura@f5.com 122*1489St.nateldemoura@f5.com if (dst == NULL) { 123*1489St.nateldemoura@f5.com dst = nxt_array_create(mp, src->nelts, size); 124*1489St.nateldemoura@f5.com if (nxt_slow_path(dst == NULL)) { 125*1489St.nateldemoura@f5.com return NULL; 126*1489St.nateldemoura@f5.com } 127*1489St.nateldemoura@f5.com } 128*1489St.nateldemoura@f5.com 129*1489St.nateldemoura@f5.com nxt_assert(size == dst->size); 130*1489St.nateldemoura@f5.com 131*1489St.nateldemoura@f5.com if (dst->nalloc >= src->nelts) { 132*1489St.nateldemoura@f5.com nxt_memcpy(dst->elts, src->elts, src->nelts * size); 133*1489St.nateldemoura@f5.com 134*1489St.nateldemoura@f5.com } else { 135*1489St.nateldemoura@f5.com nxt_memcpy(dst->elts, src->elts, dst->nelts * size); 136*1489St.nateldemoura@f5.com 137*1489St.nateldemoura@f5.com for (i = dst->nelts; i < src->nelts; i++) { 138*1489St.nateldemoura@f5.com data = nxt_array_add(dst); 139*1489St.nateldemoura@f5.com if (nxt_slow_path(data == NULL)) { 140*1489St.nateldemoura@f5.com return NULL; 141*1489St.nateldemoura@f5.com } 142*1489St.nateldemoura@f5.com 143*1489St.nateldemoura@f5.com nxt_memcpy(data, src->elts + (i * size), size); 144*1489St.nateldemoura@f5.com } 145*1489St.nateldemoura@f5.com } 146*1489St.nateldemoura@f5.com 147*1489St.nateldemoura@f5.com dst->nelts = src->nelts; 148*1489St.nateldemoura@f5.com 149*1489St.nateldemoura@f5.com return dst; 150*1489St.nateldemoura@f5.com } 151