xref: /unit/src/nxt_array.c (revision 1563:d32bc428f46b)
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 *
nxt_array_create(nxt_mp_t * mp,nxt_uint_t n,size_t size)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
nxt_array_destroy(nxt_array_t * array)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 *
nxt_array_add(nxt_array_t * array)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 == 0) ? 4 : 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 *
nxt_array_zero_add(nxt_array_t * array)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
nxt_array_remove(nxt_array_t * array,void * elt)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 *
nxt_array_copy(nxt_mp_t * mp,nxt_array_t * dst,nxt_array_t * src)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