+static void
+create_hash_index (u8 * name, u32 index)
+{
+ stat_segment_main_t *sm = &stat_segment_main;
+
+ /* Must be called in the context of the main heap */
+ ASSERT (clib_mem_get_heap () != sm->heap);
+
+ hash_set (sm->directory_vector_by_name, format (0, "%s%c", name, 0), index);
+}
+
+static u32
+vlib_stats_get_next_vector_index ()
+{
+ stat_segment_main_t *sm = &stat_segment_main;
+ u32 next_vector_index = vec_len (sm->directory_vector);
+
+ ssize_t i;
+ vec_foreach_index_backwards (i, sm->directory_vector)
+ {
+ if (sm->directory_vector[i].type == STAT_DIR_TYPE_EMPTY)
+ {
+ next_vector_index = i;
+ break;
+ }
+ }
+
+ return next_vector_index;
+}
+
+static u32
+vlib_stats_create_counter (stat_segment_directory_entry_t * e, void *oldheap)
+{
+ stat_segment_main_t *sm = &stat_segment_main;
+
+ ASSERT (clib_mem_get_heap () == sm->heap);
+
+ u32 index = vlib_stats_get_next_vector_index ();
+
+ clib_mem_set_heap (oldheap);
+ create_hash_index ((u8 *) e->name, index);
+ clib_mem_set_heap (sm->heap);
+
+ vec_validate (sm->directory_vector, index);
+ sm->directory_vector[index] = *e;
+
+ return index;
+}
+
+static void
+vlib_stats_delete_counter (u32 index, void *oldheap)
+{
+ stat_segment_main_t *sm = &stat_segment_main;
+ stat_segment_directory_entry_t *e;
+
+ ASSERT (clib_mem_get_heap () == sm->heap);
+
+ if (index > vec_len (sm->directory_vector))
+ return;
+
+ e = &sm->directory_vector[index];
+
+ clib_mem_set_heap (oldheap);
+ hash_unset (sm->directory_vector_by_name, &e->name);
+ clib_mem_set_heap (sm->heap);
+
+ memset (e, 0, sizeof (*e));
+ e->type = STAT_DIR_TYPE_EMPTY;
+}
+