Line data Source code
1 : /* Generic vector interface routine
2 : * Copyright (C) 1997 Kunihiro Ishiguro
3 : *
4 : * This file is part of GNU Zebra.
5 : *
6 : * GNU Zebra is free software; you can redistribute it and/or modify it
7 : * under the terms of the GNU General Public License as published by the
8 : * Free Software Foundation; either version 2, or (at your option) any
9 : * later version.
10 : *
11 : * GNU Zebra is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License along
17 : * with this program; see the file COPYING; if not, write to the Free Software
18 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 : */
20 :
21 : #include <zebra.h>
22 :
23 : #include "vector.h"
24 : #include "memory.h"
25 :
26 11 : DEFINE_MTYPE_STATIC(LIB, VECTOR, "Vector");
27 11 : DEFINE_MTYPE_STATIC(LIB, VECTOR_INDEX, "Vector index");
28 :
29 : /* Initialize vector : allocate memory and return vector. */
30 91739 : vector vector_init(unsigned int size)
31 : {
32 91739 : vector v = XCALLOC(MTYPE_VECTOR, sizeof(struct _vector));
33 :
34 : /* allocate at least one slot */
35 91739 : if (size == 0)
36 : size = 1;
37 :
38 91739 : v->alloced = size;
39 91739 : v->active = 0;
40 91739 : v->count = 0;
41 91739 : v->index = XCALLOC(MTYPE_VECTOR_INDEX, sizeof(void *) * size);
42 91739 : return v;
43 : }
44 :
45 56965 : void vector_free(vector v)
46 : {
47 56965 : XFREE(MTYPE_VECTOR_INDEX, v->index);
48 56965 : XFREE(MTYPE_VECTOR, v);
49 56965 : }
50 :
51 0 : vector vector_copy(vector v)
52 : {
53 0 : unsigned int size;
54 0 : vector new = XCALLOC(MTYPE_VECTOR, sizeof(struct _vector));
55 :
56 0 : new->active = v->active;
57 0 : new->alloced = v->alloced;
58 0 : new->count = v->count;
59 :
60 0 : size = sizeof(void *) * (v->alloced);
61 0 : new->index = XCALLOC(MTYPE_VECTOR_INDEX, size);
62 0 : memcpy(new->index, v->index, size);
63 :
64 0 : return new;
65 : }
66 :
67 : /* Check assigned index, and if it runs short double index pointer */
68 181174 : void vector_ensure(vector v, unsigned int num)
69 : {
70 181182 : if (v->alloced > num)
71 : return;
72 :
73 29428 : v->index = XREALLOC(MTYPE_VECTOR_INDEX, v->index,
74 : sizeof(void *) * (v->alloced * 2));
75 29428 : memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
76 29428 : v->alloced *= 2;
77 :
78 29428 : if (v->alloced <= num)
79 : vector_ensure(v, num);
80 : }
81 :
82 : /* This function only returns next empty slot index. It dose not mean
83 : the slot's index memory is assigned, please call vector_ensure()
84 : after calling this function. */
85 180788 : int vector_empty_slot(vector v)
86 : {
87 180788 : unsigned int i;
88 :
89 180788 : if (v->active == v->count)
90 177105 : return v->active;
91 :
92 3683 : if (v->active == 0)
93 : return 0;
94 :
95 30 : for (i = 0; i < v->active; i++)
96 15 : if (v->index[i] == 0)
97 0 : return i;
98 :
99 15 : return i;
100 : }
101 :
102 : /* Set value to the smallest empty slot. */
103 180788 : int vector_set(vector v, void *val)
104 : {
105 180788 : unsigned int i;
106 :
107 180788 : i = vector_empty_slot(v);
108 180788 : vector_ensure(v, i);
109 :
110 180788 : if (v->index[i])
111 0 : v->count--;
112 180788 : if (val)
113 180788 : v->count++;
114 180788 : v->index[i] = val;
115 :
116 180788 : if (v->active <= i)
117 180788 : v->active = i + 1;
118 :
119 180788 : return i;
120 : }
121 :
122 : /* Set value to specified index slot. */
123 386 : int vector_set_index(vector v, unsigned int i, void *val)
124 : {
125 386 : vector_ensure(v, i);
126 :
127 386 : if (v->index[i])
128 0 : v->count--;
129 386 : if (val)
130 386 : v->count++;
131 386 : v->index[i] = val;
132 :
133 386 : if (v->active <= i)
134 287 : v->active = i + 1;
135 :
136 386 : return i;
137 : }
138 :
139 : /* Look up vector. */
140 6613 : void *vector_lookup(vector v, unsigned int i)
141 : {
142 6613 : if (i >= v->active)
143 : return NULL;
144 6613 : return v->index[i];
145 : }
146 :
147 : /* Lookup vector, ensure it. */
148 0 : void *vector_lookup_ensure(vector v, unsigned int i)
149 : {
150 0 : vector_ensure(v, i);
151 0 : return v->index[i];
152 : }
153 :
154 : /* Unset value at specified index slot. */
155 27634 : void vector_unset(vector v, unsigned int i)
156 : {
157 27634 : if (i >= v->alloced)
158 : return;
159 :
160 27634 : if (v->index[i])
161 27611 : v->count--;
162 :
163 27634 : v->index[i] = NULL;
164 :
165 27634 : if (i + 1 == v->active) {
166 4864 : v->active--;
167 27634 : while (i && v->index[--i] == NULL && v->active--)
168 : ; /* Is this ugly ? */
169 : }
170 : }
171 :
172 0 : void vector_remove(vector v, unsigned int ix)
173 : {
174 0 : if (ix >= v->active)
175 : return;
176 :
177 0 : if (v->index[ix])
178 0 : v->count--;
179 :
180 0 : int n = (--v->active) - ix;
181 :
182 0 : memmove(&v->index[ix], &v->index[ix + 1], n * sizeof(void *));
183 0 : v->index[v->active] = NULL;
184 : }
185 :
186 89 : void vector_compact(vector v)
187 : {
188 250 : for (unsigned int i = 0; i < vector_active(v); ++i) {
189 161 : if (vector_slot(v, i) == NULL) {
190 0 : vector_remove(v, i);
191 0 : --i;
192 : }
193 : }
194 89 : }
195 :
196 0 : void vector_unset_value(vector v, void *val)
197 : {
198 0 : size_t i;
199 :
200 0 : for (i = 0; i < v->active; i++)
201 0 : if (v->index[i] == val) {
202 0 : v->index[i] = NULL;
203 0 : v->count--;
204 0 : break;
205 : }
206 :
207 0 : if (i + 1 == v->active)
208 0 : do
209 0 : v->active--;
210 0 : while (i && v->index[--i] == NULL);
211 0 : }
212 :
213 0 : void vector_to_array(vector v, void ***dest, int *argc)
214 : {
215 0 : *dest = XCALLOC(MTYPE_TMP, sizeof(void *) * v->active);
216 0 : memcpy(*dest, v->index, sizeof(void *) * v->active);
217 0 : *argc = v->active;
218 0 : }
219 :
220 89 : vector array_to_vector(void **src, int argc)
221 : {
222 89 : vector v = vector_init(VECTOR_MIN_SIZE);
223 :
224 273 : for (int i = 0; i < argc; i++)
225 184 : vector_set_index(v, i, src[i]);
226 89 : return v;
227 : }
|