diff options
Diffstat (limited to 'src/nxt_vector.c')
-rw-r--r-- | src/nxt_vector.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/nxt_vector.c b/src/nxt_vector.c new file mode 100644 index 00000000..faaf2f54 --- /dev/null +++ b/src/nxt_vector.c @@ -0,0 +1,156 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#include <nxt_main.h> + + +nxt_vector_t * +nxt_vector_create(nxt_uint_t items, size_t item_size, + const nxt_mem_proto_t *proto, void *pool) +{ + nxt_vector_t *vector; + + vector = proto->alloc(pool, sizeof(nxt_vector_t) + items * item_size); + + if (nxt_fast_path(vector != NULL)) { + vector->start = (char *) vector + sizeof(nxt_vector_t); + vector->items = 0; + vector->item_size = item_size; + vector->avalaible = items; + vector->type = NXT_VECTOR_EMBEDDED; + } + + return vector; +} + + +void * +nxt_vector_init(nxt_vector_t *vector, nxt_uint_t items, size_t item_size, + const nxt_mem_proto_t *proto, void *pool) +{ + vector->start = proto->alloc(pool, items * item_size); + + if (nxt_fast_path(vector->start != NULL)) { + vector->items = 0; + vector->item_size = item_size; + vector->avalaible = items; + vector->type = NXT_VECTOR_INITED; + } + + return vector->start; +} + + +void +nxt_vector_destroy(nxt_vector_t *vector, const nxt_mem_proto_t *proto, + void *pool) +{ + switch (vector->type) { + + case NXT_VECTOR_INITED: + proto->free(pool, vector->start); +#if (NXT_DEBUG) + vector->start = NULL; + vector->items = 0; + vector->avalaible = 0; +#endif + break; + + case NXT_VECTOR_DESCRETE: + proto->free(pool, vector->start); + + /* Fall through. */ + + case NXT_VECTOR_EMBEDDED: + proto->free(pool, vector); + break; + } +} + + +void * +nxt_vector_add(nxt_vector_t *vector, const nxt_mem_proto_t *proto, void *pool) +{ + void *item, *start, *old; + size_t size; + uint32_t n; + + n = vector->avalaible; + + if (n == vector->items) { + + if (n < 16) { + /* Allocate new vector twice as much as current. */ + n *= 2; + + } else { + /* Allocate new vector half as much as current. */ + n += n / 2; + } + + size = n * vector->item_size; + + start = proto->alloc(pool, size); + if (nxt_slow_path(start == NULL)) { + return NULL; + } + + vector->avalaible = n; + old = vector->start; + vector->start = start; + + nxt_memcpy(start, old, size); + + if (vector->type == NXT_VECTOR_EMBEDDED) { + vector->type = NXT_VECTOR_DESCRETE; + + } else { + proto->free(pool, old); + } + } + + item = (char *) vector->start + vector->item_size * vector->items; + + vector->items++; + + return item; +} + + +void * +nxt_vector_zero_add(nxt_vector_t *vector, const nxt_mem_proto_t *proto, + void *pool) +{ + void *item; + + item = nxt_vector_add(vector, proto, pool); + + if (nxt_fast_path(item != NULL)) { + nxt_memzero(item, vector->item_size); + } + + return item; +} + + +void +nxt_vector_remove(nxt_vector_t *vector, void *item) +{ + u_char *next, *last, *end; + uint32_t item_size; + + item_size = vector->item_size; + end = (u_char *) vector->start + item_size * vector->items; + last = end - item_size; + + if (item != last) { + next = (u_char *) item + item_size; + + nxt_memmove(item, next, end - next); + } + + vector->items--; +} |