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