xref: /unit/src/nxt_array.c (revision 1489)
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