/src/unit/src/nxt_array.c
Line | Count | Source (jump to first uncovered line) |
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 * |
11 | | nxt_array_create(nxt_mp_t *mp, nxt_uint_t n, size_t size) |
12 | 0 | { |
13 | 0 | nxt_array_t *array; |
14 | |
|
15 | 0 | array = nxt_mp_alloc(mp, sizeof(nxt_array_t) + n * size); |
16 | |
|
17 | 0 | if (nxt_slow_path(array == NULL)) { |
18 | 0 | return NULL; |
19 | 0 | } |
20 | | |
21 | 0 | array->elts = nxt_pointer_to(array, sizeof(nxt_array_t)); |
22 | 0 | array->nelts = 0; |
23 | 0 | array->size = size; |
24 | 0 | array->nalloc = n; |
25 | 0 | array->mem_pool = mp; |
26 | |
|
27 | 0 | return array; |
28 | 0 | } |
29 | | |
30 | | |
31 | | void |
32 | | nxt_array_destroy(nxt_array_t *array) |
33 | 0 | { |
34 | 0 | if (array->elts != nxt_pointer_to(array, sizeof(nxt_array_t))) { |
35 | 0 | nxt_mp_free(array->mem_pool, array->elts); |
36 | 0 | } |
37 | |
|
38 | 0 | nxt_mp_free(array->mem_pool, array); |
39 | 0 | } |
40 | | |
41 | | |
42 | | void * |
43 | | nxt_array_add(nxt_array_t *array) |
44 | 0 | { |
45 | 0 | void *p; |
46 | 0 | uint32_t nalloc, new_alloc; |
47 | |
|
48 | 0 | nalloc = array->nalloc; |
49 | |
|
50 | 0 | if (array->nelts == nalloc) { |
51 | |
|
52 | 0 | if (nalloc < 16) { |
53 | | /* Allocate new array twice larger than current. */ |
54 | 0 | new_alloc = (nalloc == 0) ? 4 : nalloc * 2; |
55 | |
|
56 | 0 | } else { |
57 | | /* Allocate new array 1.5 times larger than current. */ |
58 | 0 | new_alloc = nalloc + nalloc / 2; |
59 | 0 | } |
60 | |
|
61 | 0 | p = nxt_mp_alloc(array->mem_pool, array->size * new_alloc); |
62 | |
|
63 | 0 | if (nxt_slow_path(p == NULL)) { |
64 | 0 | return NULL; |
65 | 0 | } |
66 | | |
67 | 0 | nxt_memcpy(p, array->elts, array->size * nalloc); |
68 | |
|
69 | 0 | if (array->elts != nxt_pointer_to(array, sizeof(nxt_array_t))) { |
70 | 0 | nxt_mp_free(array->mem_pool, array->elts); |
71 | 0 | } |
72 | |
|
73 | 0 | array->elts = p; |
74 | 0 | array->nalloc = new_alloc; |
75 | 0 | } |
76 | | |
77 | 0 | p = nxt_pointer_to(array->elts, array->size * array->nelts); |
78 | 0 | array->nelts++; |
79 | |
|
80 | 0 | return p; |
81 | 0 | } |
82 | | |
83 | | |
84 | | void * |
85 | | nxt_array_zero_add(nxt_array_t *array) |
86 | 0 | { |
87 | 0 | void *p; |
88 | |
|
89 | 0 | p = nxt_array_add(array); |
90 | |
|
91 | 0 | if (nxt_fast_path(p != NULL)) { |
92 | 0 | nxt_memzero(p, array->size); |
93 | 0 | } |
94 | |
|
95 | 0 | return p; |
96 | 0 | } |
97 | | |
98 | | |
99 | | void |
100 | | nxt_array_remove(nxt_array_t *array, void *elt) |
101 | 0 | { |
102 | 0 | void *last; |
103 | |
|
104 | 0 | last = nxt_array_last(array); |
105 | |
|
106 | 0 | if (elt != last) { |
107 | 0 | nxt_memcpy(elt, last, array->size); |
108 | 0 | } |
109 | |
|
110 | 0 | array->nelts--; |
111 | 0 | } |
112 | | |
113 | | |
114 | | nxt_array_t * |
115 | | nxt_array_copy(nxt_mp_t *mp, nxt_array_t *dst, nxt_array_t *src) |
116 | 0 | { |
117 | 0 | void *data; |
118 | 0 | uint32_t i, size; |
119 | |
|
120 | 0 | size = src->size; |
121 | |
|
122 | 0 | if (dst == NULL) { |
123 | 0 | dst = nxt_array_create(mp, src->nelts, size); |
124 | 0 | if (nxt_slow_path(dst == NULL)) { |
125 | 0 | return NULL; |
126 | 0 | } |
127 | 0 | } |
128 | | |
129 | 0 | nxt_assert(size == dst->size); |
130 | |
|
131 | 0 | if (dst->nalloc >= src->nelts) { |
132 | 0 | nxt_memcpy(dst->elts, src->elts, src->nelts * size); |
133 | |
|
134 | 0 | } else { |
135 | 0 | nxt_memcpy(dst->elts, src->elts, dst->nelts * size); |
136 | |
|
137 | 0 | for (i = dst->nelts; i < src->nelts; i++) { |
138 | 0 | data = nxt_array_add(dst); |
139 | 0 | if (nxt_slow_path(data == NULL)) { |
140 | 0 | return NULL; |
141 | 0 | } |
142 | | |
143 | 0 | nxt_memcpy(data, src->elts + (i * size), size); |
144 | 0 | } |
145 | 0 | } |
146 | | |
147 | 0 | dst->nelts = src->nelts; |
148 | |
|
149 | 0 | return dst; |
150 | 0 | } |