xref: /unit/src/nxt_vector.c (revision 98:4077decf847b)
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_vector_t *
nxt_vector_create(nxt_uint_t items,size_t item_size,const nxt_mem_proto_t * proto,void * pool)110Sigor@sysoev.ru nxt_vector_create(nxt_uint_t items, size_t item_size,
120Sigor@sysoev.ru     const nxt_mem_proto_t *proto, void *pool)
130Sigor@sysoev.ru {
140Sigor@sysoev.ru     nxt_vector_t  *vector;
150Sigor@sysoev.ru 
160Sigor@sysoev.ru     vector = proto->alloc(pool, sizeof(nxt_vector_t) + items * item_size);
170Sigor@sysoev.ru 
180Sigor@sysoev.ru     if (nxt_fast_path(vector != NULL)) {
19*98Svbart@nginx.com         vector->start = nxt_pointer_to(vector, sizeof(nxt_vector_t));
200Sigor@sysoev.ru         vector->items = 0;
210Sigor@sysoev.ru         vector->item_size = item_size;
220Sigor@sysoev.ru         vector->avalaible = items;
230Sigor@sysoev.ru         vector->type = NXT_VECTOR_EMBEDDED;
240Sigor@sysoev.ru     }
250Sigor@sysoev.ru 
260Sigor@sysoev.ru     return vector;
270Sigor@sysoev.ru }
280Sigor@sysoev.ru 
290Sigor@sysoev.ru 
300Sigor@sysoev.ru void *
nxt_vector_init(nxt_vector_t * vector,nxt_uint_t items,size_t item_size,const nxt_mem_proto_t * proto,void * pool)310Sigor@sysoev.ru nxt_vector_init(nxt_vector_t *vector, nxt_uint_t items, size_t item_size,
320Sigor@sysoev.ru     const nxt_mem_proto_t *proto, void *pool)
330Sigor@sysoev.ru {
340Sigor@sysoev.ru     vector->start = proto->alloc(pool, items * item_size);
350Sigor@sysoev.ru 
360Sigor@sysoev.ru     if (nxt_fast_path(vector->start != NULL)) {
370Sigor@sysoev.ru         vector->items = 0;
380Sigor@sysoev.ru         vector->item_size = item_size;
390Sigor@sysoev.ru         vector->avalaible = items;
400Sigor@sysoev.ru         vector->type = NXT_VECTOR_INITED;
410Sigor@sysoev.ru     }
420Sigor@sysoev.ru 
430Sigor@sysoev.ru     return vector->start;
440Sigor@sysoev.ru }
450Sigor@sysoev.ru 
460Sigor@sysoev.ru 
470Sigor@sysoev.ru void
nxt_vector_destroy(nxt_vector_t * vector,const nxt_mem_proto_t * proto,void * pool)480Sigor@sysoev.ru nxt_vector_destroy(nxt_vector_t *vector, const nxt_mem_proto_t *proto,
490Sigor@sysoev.ru     void *pool)
500Sigor@sysoev.ru {
510Sigor@sysoev.ru     switch (vector->type) {
520Sigor@sysoev.ru 
530Sigor@sysoev.ru     case NXT_VECTOR_INITED:
540Sigor@sysoev.ru         proto->free(pool, vector->start);
550Sigor@sysoev.ru #if (NXT_DEBUG)
560Sigor@sysoev.ru         vector->start = NULL;
570Sigor@sysoev.ru         vector->items = 0;
580Sigor@sysoev.ru         vector->avalaible = 0;
590Sigor@sysoev.ru #endif
600Sigor@sysoev.ru         break;
610Sigor@sysoev.ru 
620Sigor@sysoev.ru     case NXT_VECTOR_DESCRETE:
630Sigor@sysoev.ru         proto->free(pool, vector->start);
640Sigor@sysoev.ru 
650Sigor@sysoev.ru         /* Fall through. */
660Sigor@sysoev.ru 
670Sigor@sysoev.ru     case NXT_VECTOR_EMBEDDED:
680Sigor@sysoev.ru         proto->free(pool, vector);
690Sigor@sysoev.ru         break;
700Sigor@sysoev.ru     }
710Sigor@sysoev.ru }
720Sigor@sysoev.ru 
730Sigor@sysoev.ru 
740Sigor@sysoev.ru void *
nxt_vector_add(nxt_vector_t * vector,const nxt_mem_proto_t * proto,void * pool)750Sigor@sysoev.ru nxt_vector_add(nxt_vector_t *vector, const nxt_mem_proto_t *proto, void *pool)
760Sigor@sysoev.ru {
770Sigor@sysoev.ru     void      *item, *start, *old;
780Sigor@sysoev.ru     size_t    size;
790Sigor@sysoev.ru     uint32_t  n;
800Sigor@sysoev.ru 
810Sigor@sysoev.ru     n = vector->avalaible;
820Sigor@sysoev.ru 
830Sigor@sysoev.ru     if (n == vector->items) {
840Sigor@sysoev.ru 
850Sigor@sysoev.ru         if (n < 16) {
860Sigor@sysoev.ru             /* Allocate new vector twice as much as current. */
870Sigor@sysoev.ru             n *= 2;
880Sigor@sysoev.ru 
890Sigor@sysoev.ru         } else {
900Sigor@sysoev.ru             /* Allocate new vector half as much as current. */
910Sigor@sysoev.ru             n += n / 2;
920Sigor@sysoev.ru         }
930Sigor@sysoev.ru 
940Sigor@sysoev.ru         size = n * vector->item_size;
950Sigor@sysoev.ru 
960Sigor@sysoev.ru         start = proto->alloc(pool, size);
970Sigor@sysoev.ru         if (nxt_slow_path(start == NULL)) {
980Sigor@sysoev.ru             return NULL;
990Sigor@sysoev.ru         }
1000Sigor@sysoev.ru 
1010Sigor@sysoev.ru         vector->avalaible = n;
1020Sigor@sysoev.ru         old = vector->start;
1030Sigor@sysoev.ru         vector->start = start;
1040Sigor@sysoev.ru 
1050Sigor@sysoev.ru         nxt_memcpy(start, old, size);
1060Sigor@sysoev.ru 
1070Sigor@sysoev.ru         if (vector->type == NXT_VECTOR_EMBEDDED) {
1080Sigor@sysoev.ru             vector->type = NXT_VECTOR_DESCRETE;
1090Sigor@sysoev.ru 
1100Sigor@sysoev.ru         } else {
1110Sigor@sysoev.ru             proto->free(pool, old);
1120Sigor@sysoev.ru         }
1130Sigor@sysoev.ru     }
1140Sigor@sysoev.ru 
115*98Svbart@nginx.com     item = nxt_pointer_to(vector->start, vector->item_size * vector->items);
1160Sigor@sysoev.ru 
1170Sigor@sysoev.ru     vector->items++;
1180Sigor@sysoev.ru 
1190Sigor@sysoev.ru     return item;
1200Sigor@sysoev.ru }
1210Sigor@sysoev.ru 
1220Sigor@sysoev.ru 
1230Sigor@sysoev.ru void *
nxt_vector_zero_add(nxt_vector_t * vector,const nxt_mem_proto_t * proto,void * pool)1240Sigor@sysoev.ru nxt_vector_zero_add(nxt_vector_t *vector, const nxt_mem_proto_t *proto,
1250Sigor@sysoev.ru     void *pool)
1260Sigor@sysoev.ru {
1270Sigor@sysoev.ru     void  *item;
1280Sigor@sysoev.ru 
1290Sigor@sysoev.ru     item = nxt_vector_add(vector, proto, pool);
1300Sigor@sysoev.ru 
1310Sigor@sysoev.ru     if (nxt_fast_path(item != NULL)) {
1320Sigor@sysoev.ru         nxt_memzero(item, vector->item_size);
1330Sigor@sysoev.ru     }
1340Sigor@sysoev.ru 
1350Sigor@sysoev.ru     return item;
1360Sigor@sysoev.ru }
1370Sigor@sysoev.ru 
1380Sigor@sysoev.ru 
1390Sigor@sysoev.ru void
nxt_vector_remove(nxt_vector_t * vector,void * item)1400Sigor@sysoev.ru nxt_vector_remove(nxt_vector_t *vector, void *item)
1410Sigor@sysoev.ru {
1420Sigor@sysoev.ru     u_char    *next, *last, *end;
1430Sigor@sysoev.ru     uint32_t  item_size;
1440Sigor@sysoev.ru 
1450Sigor@sysoev.ru     item_size = vector->item_size;
146*98Svbart@nginx.com     end = nxt_pointer_to(vector->start, item_size * vector->items);
1470Sigor@sysoev.ru     last = end - item_size;
1480Sigor@sysoev.ru 
1490Sigor@sysoev.ru     if (item != last) {
150*98Svbart@nginx.com         next = nxt_pointer_to(item, item_size);
1510Sigor@sysoev.ru 
1520Sigor@sysoev.ru         nxt_memmove(item, next, end - next);
1530Sigor@sysoev.ru     }
1540Sigor@sysoev.ru 
1550Sigor@sysoev.ru     vector->items--;
1560Sigor@sysoev.ru }
157