1
2 /*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7 #include <nxt_main.h>
8
9
10 nxt_vector_t *
nxt_vector_create(nxt_uint_t items,size_t item_size,const nxt_mem_proto_t * proto,void * pool)11 nxt_vector_create(nxt_uint_t items, size_t item_size,
12 const nxt_mem_proto_t *proto, void *pool)
13 {
14 nxt_vector_t *vector;
15
16 vector = proto->alloc(pool, sizeof(nxt_vector_t) + items * item_size);
17
18 if (nxt_fast_path(vector != NULL)) {
19 vector->start = nxt_pointer_to(vector, sizeof(nxt_vector_t));
20 vector->items = 0;
21 vector->item_size = item_size;
22 vector->avalaible = items;
23 vector->type = NXT_VECTOR_EMBEDDED;
24 }
25
26 return vector;
27 }
28
29
30 void *
nxt_vector_init(nxt_vector_t * vector,nxt_uint_t items,size_t item_size,const nxt_mem_proto_t * proto,void * pool)31 nxt_vector_init(nxt_vector_t *vector, nxt_uint_t items, size_t item_size,
32 const nxt_mem_proto_t *proto, void *pool)
33 {
34 vector->start = proto->alloc(pool, items * item_size);
35
36 if (nxt_fast_path(vector->start != NULL)) {
37 vector->items = 0;
38 vector->item_size = item_size;
39 vector->avalaible = items;
40 vector->type = NXT_VECTOR_INITED;
41 }
42
43 return vector->start;
44 }
45
46
47 void
nxt_vector_destroy(nxt_vector_t * vector,const nxt_mem_proto_t * proto,void * pool)48 nxt_vector_destroy(nxt_vector_t *vector, const nxt_mem_proto_t *proto,
49 void *pool)
50 {
51 switch (vector->type) {
52
53 case NXT_VECTOR_INITED:
54 proto->free(pool, vector->start);
55 #if (NXT_DEBUG)
56 vector->start = NULL;
57 vector->items = 0;
58 vector->avalaible = 0;
59 #endif
60 break;
61
62 case NXT_VECTOR_DESCRETE:
63 proto->free(pool, vector->start);
64
65 /* Fall through. */
66
67 case NXT_VECTOR_EMBEDDED:
68 proto->free(pool, vector);
69 break;
70 }
71 }
72
73
74 void *
nxt_vector_add(nxt_vector_t * vector,const nxt_mem_proto_t * proto,void * pool)75 nxt_vector_add(nxt_vector_t *vector, const nxt_mem_proto_t *proto, void *pool)
76 {
77 void *item, *start, *old;
78 size_t size;
79 uint32_t n;
80
81 n = vector->avalaible;
82
83 if (n == vector->items) {
84
85 if (n < 16) {
86 /* Allocate new vector twice as much as current. */
87 n *= 2;
88
89 } else {
90 /* Allocate new vector half as much as current. */
91 n += n / 2;
92 }
93
94 size = n * vector->item_size;
95
96 start = proto->alloc(pool, size);
97 if (nxt_slow_path(start == NULL)) {
98 return NULL;
99 }
100
101 vector->avalaible = n;
102 old = vector->start;
103 vector->start = start;
104
105 nxt_memcpy(start, old, size);
106
107 if (vector->type == NXT_VECTOR_EMBEDDED) {
108 vector->type = NXT_VECTOR_DESCRETE;
109
110 } else {
111 proto->free(pool, old);
112 }
113 }
114
115 item = nxt_pointer_to(vector->start, vector->item_size * vector->items);
116
117 vector->items++;
118
119 return item;
120 }
121
122
123 void *
nxt_vector_zero_add(nxt_vector_t * vector,const nxt_mem_proto_t * proto,void * pool)124 nxt_vector_zero_add(nxt_vector_t *vector, const nxt_mem_proto_t *proto,
125 void *pool)
126 {
127 void *item;
128
129 item = nxt_vector_add(vector, proto, pool);
130
131 if (nxt_fast_path(item != NULL)) {
132 nxt_memzero(item, vector->item_size);
133 }
134
135 return item;
136 }
137
138
139 void
nxt_vector_remove(nxt_vector_t * vector,void * item)140 nxt_vector_remove(nxt_vector_t *vector, void *item)
141 {
142 u_char *next, *last, *end;
143 uint32_t item_size;
144
145 item_size = vector->item_size;
146 end = nxt_pointer_to(vector->start, item_size * vector->items);
147 last = end - item_size;
148
149 if (item != last) {
150 next = nxt_pointer_to(item, item_size);
151
152 nxt_memmove(item, next, end - next);
153 }
154
155 vector->items--;
156 }
157