summaryrefslogtreecommitdiff
path: root/lib/vector.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2024-07-20 18:28:53 -0700
committerDonald Sharp <sharpd@nvidia.com>2024-07-31 08:08:53 -0400
commit0bf664527d003cb3670529f0609d51ce38bcf0ab (patch)
tree5f26efd0ef88e3adaeb25bf241b39b3020e8a35e /lib/vector.c
parent05e915984c641d59b4d4b0e83c1f301de4cba460 (diff)
lib: allow static/pre-initialized vectors
Use alloced=0 to indicate that the array used in a vector is not in fact dynamically allocated memory (yet). Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib/vector.c')
-rw-r--r--lib/vector.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/lib/vector.c b/lib/vector.c
index 16b45254cb..0636154960 100644
--- a/lib/vector.c
+++ b/lib/vector.c
@@ -24,29 +24,44 @@ vector vector_init(unsigned int size)
v->alloced = size;
v->active = 0;
v->count = 0;
+ v->dynamic = true;
v->index = XCALLOC(MTYPE_VECTOR_INDEX, sizeof(void *) * size);
return v;
}
void vector_free(vector v)
{
- XFREE(MTYPE_VECTOR_INDEX, v->index);
- XFREE(MTYPE_VECTOR, v);
+ if (v->alloced)
+ XFREE(MTYPE_VECTOR_INDEX, v->index);
+ if (v->dynamic)
+ XFREE(MTYPE_VECTOR, v);
}
-/* Check assigned index, and if it runs short double index pointer */
+/* resize vector to a minimum of num
+ * may resize larger to avoid excessive realloc overhead
+ */
void vector_ensure(vector v, unsigned int num)
{
+ unsigned int newsz;
+
if (v->alloced > num)
return;
- v->index = XREALLOC(MTYPE_VECTOR_INDEX, v->index,
- sizeof(void *) * (v->alloced * 2));
- memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
- v->alloced *= 2;
+ newsz = MAX(v->active * 2, num + 1);
+
+ if (!v->alloced && v->index) {
+ /* currently using global variable, not malloc'd memory */
+ void **orig_index = v->index;
- if (v->alloced <= num)
- vector_ensure(v, num);
+ v->index = XMALLOC(MTYPE_VECTOR_INDEX, sizeof(void *) * newsz);
+ memcpy(v->index, orig_index, v->active * sizeof(void *));
+ v->alloced = v->active;
+ } else
+ v->index = XREALLOC(MTYPE_VECTOR_INDEX, v->index,
+ sizeof(void *) * newsz);
+
+ memset(&v->index[v->alloced], 0, sizeof(void *) * (newsz - v->alloced));
+ v->alloced = newsz;
}
/* This function only returns next empty slot index. It dose not mean
@@ -124,7 +139,7 @@ void *vector_lookup_ensure(vector v, unsigned int i)
/* Unset value at specified index slot. */
void vector_unset(vector v, unsigned int i)
{
- if (i >= v->alloced)
+ if (i >= v->active)
return;
if (v->index[i])