xref: /unit/src/nxt_vector.c (revision 98:4077decf847b)
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