1 2 /* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7 #include <nxt_main.h> 8 9 10 nxt_vector_t * 11 nxt_vector_create(nxt_uint_t items, size_t item_size, 12 const nxt_mem_proto_t *proto, void *pool) 13 { 14 nxt_vector_t *vector; 15 16 vector = proto->alloc(pool, sizeof(nxt_vector_t) + items * item_size); 17 18 if (nxt_fast_path(vector != NULL)) { 19 vector->start = (char *) vector + sizeof(nxt_vector_t); 20 vector->items = 0; 21 vector->item_size = item_size; 22 vector->avalaible = items; 23 vector->type = NXT_VECTOR_EMBEDDED; 24 } 25 26 return vector; 27 } 28 29 30 void * 31 nxt_vector_init(nxt_vector_t *vector, nxt_uint_t items, size_t item_size, 32 const nxt_mem_proto_t *proto, void *pool) 33 { 34 vector->start = proto->alloc(pool, items * item_size); 35 36 if (nxt_fast_path(vector->start != NULL)) { 37 vector->items = 0; 38 vector->item_size = item_size; 39 vector->avalaible = items; 40 vector->type = NXT_VECTOR_INITED; 41 } 42 43 return vector->start; 44 } 45 46 47 void 48 nxt_vector_destroy(nxt_vector_t *vector, const nxt_mem_proto_t *proto, 49 void *pool) 50 { 51 switch (vector->type) { 52 53 case NXT_VECTOR_INITED: 54 proto->free(pool, vector->start); 55 #if (NXT_DEBUG) 56 vector->start = NULL; 57 vector->items = 0; 58 vector->avalaible = 0; 59 #endif 60 break; 61 62 case NXT_VECTOR_DESCRETE: 63 proto->free(pool, vector->start); 64 65 /* Fall through. */ 66 67 case NXT_VECTOR_EMBEDDED: 68 proto->free(pool, vector); 69 break; 70 } 71 } 72 73 74 void * 75 nxt_vector_add(nxt_vector_t *vector, const nxt_mem_proto_t *proto, void *pool) 76 { 77 void *item, *start, *old; 78 size_t size; 79 uint32_t n; 80 81 n = vector->avalaible; 82 83 if (n == vector->items) { 84 85 if (n < 16) { 86 /* Allocate new vector twice as much as current. */ 87 n *= 2; 88 89 } else { 90 /* Allocate new vector half as much as current. */ 91 n += n / 2; 92 } 93 94 size = n * vector->item_size; 95 96 start = proto->alloc(pool, size); 97 if (nxt_slow_path(start == NULL)) { 98 return NULL; 99 } 100 101 vector->avalaible = n; 102 old = vector->start; 103 vector->start = start; 104 105 nxt_memcpy(start, old, size); 106 107 if (vector->type == NXT_VECTOR_EMBEDDED) { 108 vector->type = NXT_VECTOR_DESCRETE; 109 110 } else { 111 proto->free(pool, old); 112 } 113 } 114 115 item = (char *) vector->start + vector->item_size * vector->items; 116 117 vector->items++; 118 119 return item; 120 } 121 122 123 void * 124 nxt_vector_zero_add(nxt_vector_t *vector, const nxt_mem_proto_t *proto, 125 void *pool) 126 { 127 void *item; 128 129 item = nxt_vector_add(vector, proto, pool); 130 131 if (nxt_fast_path(item != NULL)) { 132 nxt_memzero(item, vector->item_size); 133 } 134 135 return item; 136 } 137 138 139 void 140 nxt_vector_remove(nxt_vector_t *vector, void *item) 141 { 142 u_char *next, *last, *end; 143 uint32_t item_size; 144 145 item_size = vector->item_size; 146 end = (u_char *) vector->start + item_size * vector->items; 147 last = end - item_size; 148 149 if (item != last) { 150 next = (u_char *) item + item_size; 151 152 nxt_memmove(item, next, end - next); 153 } 154 155 vector->items--; 156 } 157