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
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22 #include <zebra.h>
23
24 #include "vector.h"
25 #include "memory.h"
26
27 /* Initialize vector : allocate memory and return vector. */
28 vector
vector_init(unsigned int size)29 vector_init (unsigned int size)
30 {
31 vector v = XCALLOC (MTYPE_VECTOR, sizeof (struct _vector));
32
33 /* allocate at least one slot */
34 if (size == 0)
35 size = 1;
36
37 v->alloced = size;
38 v->active = 0;
39 v->index = XCALLOC (MTYPE_VECTOR_INDEX, sizeof (void *) * size);
40 return v;
41 }
42
43 void
vector_only_wrapper_free(vector v)44 vector_only_wrapper_free (vector v)
45 {
46 XFREE (MTYPE_VECTOR, v);
47 }
48
49 void
vector_only_index_free(void * index)50 vector_only_index_free (void *index)
51 {
52 XFREE (MTYPE_VECTOR_INDEX, index);
53 }
54
55 void
vector_free(vector v)56 vector_free (vector v)
57 {
58 XFREE (MTYPE_VECTOR_INDEX, v->index);
59 XFREE (MTYPE_VECTOR, v);
60 }
61
62 vector
vector_copy(vector v)63 vector_copy (vector v)
64 {
65 unsigned int size;
66 vector new = XCALLOC (MTYPE_VECTOR, sizeof (struct _vector));
67
68 new->active = v->active;
69 new->alloced = v->alloced;
70
71 size = sizeof (void *) * (v->alloced);
72 new->index = XCALLOC (MTYPE_VECTOR_INDEX, size);
73 memcpy (new->index, v->index, size);
74
75 return new;
76 }
77
78 /* Check assigned index, and if it runs short double index pointer */
79 void
vector_ensure(vector v,unsigned int num)80 vector_ensure (vector v, unsigned int num)
81 {
82 if (v->alloced > num)
83 return;
84
85 v->index = XREALLOC (MTYPE_VECTOR_INDEX,
86 v->index, sizeof (void *) * (v->alloced * 2));
87 memset (&v->index[v->alloced], 0, sizeof (void *) * v->alloced);
88 v->alloced *= 2;
89
90 if (v->alloced <= num)
91 vector_ensure (v, num);
92 }
93
94 /* This function only returns next empty slot index. It dose not mean
95 the slot's index memory is assigned, please call vector_ensure()
96 after calling this function. */
97 int
vector_empty_slot(vector v)98 vector_empty_slot (vector v)
99 {
100 unsigned int i;
101
102 if (v->active == 0)
103 return 0;
104
105 for (i = 0; i < v->active; i++)
106 if (v->index[i] == 0)
107 return i;
108
109 return i;
110 }
111
112 /* Set value to the smallest empty slot. */
113 int
vector_set(vector v,void * val)114 vector_set (vector v, void *val)
115 {
116 unsigned int i;
117
118 i = vector_empty_slot (v);
119 vector_ensure (v, i);
120
121 v->index[i] = val;
122
123 if (v->active <= i)
124 v->active = i + 1;
125
126 return i;
127 }
128
129 /* Set value to specified index slot. */
130 int
vector_set_index(vector v,unsigned int i,void * val)131 vector_set_index (vector v, unsigned int i, void *val)
132 {
133 vector_ensure (v, i);
134
135 v->index[i] = val;
136
137 if (v->active <= i)
138 v->active = i + 1;
139
140 return i;
141 }
142
143 /* Look up vector. */
144 void *
vector_lookup(vector v,unsigned int i)145 vector_lookup (vector v, unsigned int i)
146 {
147 if (i >= v->active)
148 return NULL;
149 return v->index[i];
150 }
151
152 /* Lookup vector, ensure it. */
153 void *
vector_lookup_ensure(vector v,unsigned int i)154 vector_lookup_ensure (vector v, unsigned int i)
155 {
156 vector_ensure (v, i);
157 return v->index[i];
158 }
159
160 /* Unset value at specified index slot. */
161 void
vector_unset(vector v,unsigned int i)162 vector_unset (vector v, unsigned int i)
163 {
164 if (i >= v->alloced)
165 return;
166
167 v->index[i] = NULL;
168
169 if (i + 1 == v->active)
170 {
171 v->active--;
172 while (i && v->index[--i] == NULL && v->active--)
173 ; /* Is this ugly ? */
174 }
175 }
176
177 /* Count the number of not emplty slot. */
178 unsigned int
vector_count(vector v)179 vector_count (vector v)
180 {
181 unsigned int i;
182 unsigned count = 0;
183
184 for (i = 0; i < v->active; i++)
185 if (v->index[i] != NULL)
186 count++;
187
188 return count;
189 }
190