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. */
28vector
29vector_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
43void
44vector_only_wrapper_free (vector v)
45{
46  XFREE (MTYPE_VECTOR, v);
47}
48
49void
50vector_only_index_free (void *index)
51{
52  XFREE (MTYPE_VECTOR_INDEX, index);
53}
54
55void
56vector_free (vector v)
57{
58  XFREE (MTYPE_VECTOR_INDEX, v->index);
59  XFREE (MTYPE_VECTOR, v);
60}
61
62vector
63vector_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 */
79void
80vector_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. */
97int
98vector_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. */
113int
114vector_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. */
130int
131vector_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.  */
144void *
145vector_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. */
153void *
154vector_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. */
161void
162vector_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. */
178unsigned int
179vector_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