stats: avoid linear search for empty entry
Type: improvement
Change-Id: Ie4cdc6d8906da3d1cd18a8f1d7076283546d3003
Signed-off-by: Damjan Marion <damarion@cisco.com>
diff --git a/src/vlib/stats/init.c b/src/vlib/stats/init.c
index 3cfbd2d..2a7b6f5 100644
--- a/src/vlib/stats/init.c
+++ b/src/vlib/stats/init.c
@@ -98,6 +98,7 @@
/* Set up the name to counter-vector hash table */
sm->directory_vector = 0;
+ sm->dir_vector_first_free_elt = CLIB_U32_MAX;
shared_header->epoch = 1;
diff --git a/src/vlib/stats/stats.c b/src/vlib/stats/stats.c
index 9063fa3..cb29dda 100644
--- a/src/vlib/stats/stats.c
+++ b/src/vlib/stats/stats.c
@@ -106,20 +106,21 @@
{
vlib_stats_segment_t *sm = vlib_stats_get_segment ();
void *oldheap;
- u32 index = ~0;
- int i;
+ u32 index;
oldheap = clib_mem_set_heap (sm->heap);
- vec_foreach_index_backwards (i, sm->directory_vector)
- if (sm->directory_vector[i].type == STAT_DIR_TYPE_EMPTY)
- {
- index = i;
- break;
- }
- index = index == ~0 ? vec_len (sm->directory_vector) : index;
+ if (sm->dir_vector_first_free_elt != CLIB_U32_MAX)
+ {
+ index = sm->dir_vector_first_free_elt;
+ sm->dir_vector_first_free_elt = sm->directory_vector[index].index;
+ }
+ else
+ {
+ index = vec_len (sm->directory_vector);
+ vec_validate (sm->directory_vector, index);
+ }
- vec_validate (sm->directory_vector, index);
sm->directory_vector[index] = *e;
clib_mem_set_heap (oldheap);
@@ -183,6 +184,9 @@
memset (e, 0, sizeof (*e));
e->type = STAT_DIR_TYPE_EMPTY;
+
+ e->value = sm->dir_vector_first_free_elt;
+ sm->dir_vector_first_free_elt = entry_index;
}
static void
diff --git a/src/vlib/stats/stats.h b/src/vlib/stats/stats.h
index ef43510..09a9aef 100644
--- a/src/vlib/stats/stats.h
+++ b/src/vlib/stats/stats.h
@@ -75,6 +75,7 @@
/* statistics segment */
uword *directory_vector_by_name;
vlib_stats_entry_t *directory_vector;
+ u32 dir_vector_first_free_elt;
u8 **nodes;
/* Update interval */