1/*
2 * generic vector interface routine
3 * Copyright (C) 1997 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING.  If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "vector.h"
26#include "memory.h"
27
28/* Initialize vector : allocate memory and return vector. */
29vector
30vector_init (unsigned int size)
31{
32  vector v = XCALLOC (MTYPE_VECTOR, sizeof (struct _vector));
33
34  /* allocate at least one slot */
35  if (size == 0)
36    size = 1;
37
38  v->alloced = size;
39  v->max = 0;
40  v->index = XCALLOC (MTYPE_VECTOR_INDEX, sizeof (void *) * size);
41  return v;
42}
43
44void
45vector_only_wrapper_free (vector v)
46{
47  XFREE (MTYPE_VECTOR, v);
48}
49
50void
51vector_only_index_free (void *index)
52{
53  XFREE (MTYPE_VECTOR_INDEX, index);
54}
55
56void
57vector_free (vector v)
58{
59  XFREE (MTYPE_VECTOR_INDEX, v->index);
60  XFREE (MTYPE_VECTOR, v);
61}
62
63vector
64vector_copy (vector v)
65{
66  unsigned int size;
67  vector new = XCALLOC (MTYPE_VECTOR, sizeof (struct _vector));
68
69  new->max = v->max;
70  new->alloced = v->alloced;
71
72  size = sizeof (void *) * (v->alloced);
73  new->index = XCALLOC (MTYPE_VECTOR_INDEX, size);
74  memcpy (new->index, v->index, size);
75
76  return new;
77}
78
79/* Check assigned index, and if it runs short double index pointer */
80void
81vector_ensure (vector v, unsigned int num)
82{
83  if (v->alloced > num)
84    return;
85
86  v->index = XREALLOC (MTYPE_VECTOR_INDEX,
87		       v->index, sizeof (void *) * (v->alloced * 2));
88  memset (&v->index[v->alloced], 0, sizeof (void *) * v->alloced);
89  v->alloced *= 2;
90
91  if (v->alloced <= num)
92    vector_ensure (v, num);
93}
94
95/* This function only returns next empty slot index.  It dose not mean
96   the slot's index memory is assigned, please call vector_ensure()
97   after calling this function. */
98int
99vector_empty_slot (vector v)
100{
101  unsigned int i;
102
103  if (v->max == 0)
104    return 0;
105
106  for (i = 0; i < v->max; i++)
107    if (v->index[i] == 0)
108      return i;
109
110  return i;
111}
112
113/* Set value to the smallest empty slot. */
114int
115vector_set (vector v, void *val)
116{
117  unsigned int i;
118
119  i = vector_empty_slot (v);
120  vector_ensure (v, i);
121
122  v->index[i] = val;
123
124  if (v->max <= i)
125    v->max = i + 1;
126
127  return i;
128}
129
130/* Set value to specified index slot. */
131int
132vector_set_index (vector v, unsigned int i, void *val)
133{
134  vector_ensure (v, i);
135
136  v->index[i] = val;
137
138  if (v->max <= i)
139    v->max = i + 1;
140
141  return i;
142}
143
144/* Lookup vector, ensure it. */
145void *
146vector_lookup_index (vector v, unsigned int i)
147{
148  vector_ensure (v, i);
149  return v->index[i];
150}
151
152/* Unset value at specified index slot. */
153void
154vector_unset (vector v, unsigned int i)
155{
156  if (i >= v->alloced)
157    return;
158
159  v->index[i] = NULL;
160
161  if (i + 1 == v->max)
162    {
163      v->max--;
164      while (i && v->index[--i] == NULL && v->max--)
165	;				/* Is this ugly ? */
166    }
167}
168
169/* Count the number of not emplty slot. */
170unsigned int
171vector_count (vector v)
172{
173  unsigned int i;
174  unsigned count = 0;
175
176  for (i = 0; i < v->max; i++)
177    if (v->index[i] != NULL)
178      count++;
179
180  return count;
181}
182