1 2 /* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7 #include <nxt_main.h> 8 9 10 nxt_array_t * 11 nxt_array_create(nxt_mp_t *mp, nxt_uint_t n, size_t size) 12 { 13 nxt_array_t *array; 14 15 array = nxt_mp_alloc(mp, sizeof(nxt_array_t) + n * size); 16 17 if (nxt_slow_path(array == NULL)) { 18 return NULL; 19 } 20 21 array->elts = nxt_pointer_to(array, sizeof(nxt_array_t)); 22 array->nelts = 0; 23 array->size = size; 24 array->nalloc = n; 25 array->mem_pool = mp; 26 27 return array; 28 } 29 30 31 void 32 nxt_array_destroy(nxt_array_t *array) 33 { 34 if (array->elts != nxt_pointer_to(array, sizeof(nxt_array_t))) { 35 nxt_mp_free(array->mem_pool, array->elts); 36 } 37 38 nxt_mp_free(array->mem_pool, array); 39 } 40 41 42 void * 43 nxt_array_add(nxt_array_t *array) 44 { 45 void *p; 46 uint32_t nalloc, new_alloc; 47 48 nalloc = array->nalloc; 49 50 if (array->nelts == nalloc) { 51 52 if (nalloc < 16) { 53 /* Allocate new array twice larger than current. */ 54 new_alloc = nalloc * 2; 55 56 } else { 57 /* Allocate new array 1.5 times larger than current. */ 58 new_alloc = nalloc + nalloc / 2; 59 } 60 61 p = nxt_mp_alloc(array->mem_pool, array->size * new_alloc); 62 63 if (nxt_slow_path(p == NULL)) { 64 return NULL; 65 } 66 67 nxt_memcpy(p, array->elts, array->size * nalloc); 68 69 if (array->elts != nxt_pointer_to(array, sizeof(nxt_array_t))) { 70 nxt_mp_free(array->mem_pool, array->elts); 71 } 72 73 array->elts = p; 74 array->nalloc = new_alloc; 75 } 76 77 p = nxt_pointer_to(array->elts, array->size * array->nelts); 78 array->nelts++; 79 80 return p; 81 } 82 83 84 void * 85 nxt_array_zero_add(nxt_array_t *array) 86 { 87 void *p; 88 89 p = nxt_array_add(array); 90 91 if (nxt_fast_path(p != NULL)) { 92 nxt_memzero(p, array->size); 93 } 94 95 return p; 96 } 97 98 99 void 100 nxt_array_remove(nxt_array_t *array, void *elt) 101 { 102 void *last; 103 104 last = nxt_array_last(array); 105 106 if (elt != last) { 107 nxt_memcpy(elt, last, array->size); 108 } 109 110 array->nelts--; 111 } 112 113 114 nxt_array_t * 115 nxt_array_copy(nxt_mp_t *mp, nxt_array_t *dst, nxt_array_t *src) 116 { 117 void *data; 118 uint32_t i, size; 119 120 size = src->size; 121 122 if (dst == NULL) { 123 dst = nxt_array_create(mp, src->nelts, size); 124 if (nxt_slow_path(dst == NULL)) { 125 return NULL; 126 } 127 } 128 129 nxt_assert(size == dst->size); 130 131 if (dst->nalloc >= src->nelts) { 132 nxt_memcpy(dst->elts, src->elts, src->nelts * size); 133 134 } else { 135 nxt_memcpy(dst->elts, src->elts, dst->nelts * size); 136 137 for (i = dst->nelts; i < src->nelts; i++) { 138 data = nxt_array_add(dst); 139 if (nxt_slow_path(data == NULL)) { 140 return NULL; 141 } 142 143 nxt_memcpy(data, src->elts + (i * size), size); 144 } 145 } 146 147 dst->nelts = src->nelts; 148 149 return dst; 150 } 151