diff --git a/lib/librte_latencystats/rte_latencystats.c b/lib/librte_latencystats/rte_latencystats.c
index 5715549..b18c3ea 100644
--- a/lib/librte_latencystats/rte_latencystats.c
+++ b/lib/librte_latencystats/rte_latencystats.c
@@ -291,7 +291,9 @@ struct latency_stats_nameoff {
 "qid=%d\n", pid, qid);
 }
 }
-
+
+rte_metrics_unreg_values(latency_stats_index, NUM_LATENCY_STATS);
+
 /* free up the memzone */
 mz = rte_memzone_lookup(MZ_RTE_LATENCY_STATS);
 if (mz)
diff --git a/lib/librte_metrics/rte_metrics.c b/lib/librte_metrics/rte_metrics.c
index 99a96b6..704e5ae 100644
--- a/lib/librte_metrics/rte_metrics.c
+++ b/lib/librte_metrics/rte_metrics.c
@@ -12,6 +12,7 @@
 #include <rte_lcore.h>
 #include <rte_memzone.h>
 #include <rte_spinlock.h>
+#include <rte_bitmap.h>
 
 #define RTE_METRICS_MAX_METRICS 256
 #define RTE_METRICS_MEMZONE_NAME "RTE_METRICS"
@@ -28,10 +29,7 @@ struct rte_metrics_meta_s {
 uint64_t value[RTE_MAX_ETHPORTS];
 /** Used for global metrics */
 uint64_t global_value;
-/** Index of next root element (zero for none) */
-uint16_t idx_next_set;
-/** Index of next metric in set (zero for none) */
-uint16_t idx_next_stat;
+
 };
 
 /**
@@ -43,14 +41,12 @@ struct rte_metrics_meta_s {
  * processes is not guaranteed.
  */
 struct rte_metrics_data_s {
-/**   Index of last metadata entry with valid data.
- * This value is not valid if cnt_stats is zero.
- */
-uint16_t idx_last_set;
 /**   Number of metrics. */
 uint16_t cnt_stats;
 /** Metric data memory block. */
 struct rte_metrics_meta_s metadata[RTE_METRICS_MAX_METRICS];
+/** Metric data bitmap in use */
+struct rte_bitmap *bits;
 /** Metric data access lock */
 rte_spinlock_t lock;
 };
@@ -60,6 +56,7 @@ struct rte_metrics_data_s {
 {
 struct rte_metrics_data_s *stats;
 const struct rte_memzone *memzone;
+uint32_t bmp_size;
 
 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 return;
@@ -73,6 +70,24 @@ struct rte_metrics_data_s {
 rte_exit(EXIT_FAILURE, "Unable to allocate stats memzone\n");
 stats = memzone->addr;
 memset(stats, 0, sizeof(struct rte_metrics_data_s));
+
+bmp_size =
+rte_bitmap_get_memory_footprint(RTE_METRICS_MAX_METRICS);
+void *bmpmem = rte_malloc("metrics_bits", bmp_size,
+RTE_CACHE_LINE_SIZE);
+if (bmpmem == NULL) {
+rte_exit(EXIT_FAILURE, 
+"Failed to allocate vlan bitmap for device\n");
+}
+
+stats->bits = rte_bitmap_init(RTE_METRICS_MAX_METRICS,
+bmpmem, bmp_size);
+if (stats->bits == NULL) {
+rte_exit(EXIT_FAILURE, 
+"Failed to init vlan bitmap for bonded device \n");
+rte_free(bmpmem);
+}
+    
 rte_spinlock_init(&stats->lock);
 }
 
@@ -90,7 +105,7 @@ struct rte_metrics_data_s {
 struct rte_metrics_meta_s *entry = NULL;
 struct rte_metrics_data_s *stats;
 const struct rte_memzone *memzone;
-uint16_t idx_name;
+uint16_t idx_name,idx;
 uint16_t idx_base;
 
 /* Some sanity checks */
@@ -110,19 +125,36 @@ struct rte_metrics_data_s {
 
 rte_spinlock_lock(&stats->lock);
 
-/* Overwritten later if this is actually first set.. */
-stats->metadata[stats->idx_last_set].idx_next_set = stats->cnt_stats;
-
-stats->idx_last_set = idx_base = stats->cnt_stats;
-
-for (idx_name = 0; idx_name < cnt_names; idx_name++) {
-entry = &stats->metadata[idx_name + stats->cnt_stats];
-strlcpy(entry->name, names[idx_name], RTE_METRICS_MAX_NAME_LEN);
-memset(entry->value, 0, sizeof(entry->value));
-entry->idx_next_stat = idx_name + stats->cnt_stats + 1;
+    //search for a continuous array, fail if not enough
+for (idx_name = 0; idx_name < RTE_METRICS_MAX_METRICS; idx_name++)
+{
+if(!rte_bitmap_get(stats->bits,idx_name))
+{
+idx_base = idx_name;
+if(idx_base + cnt_names > RTE_METRICS_MAX_METRICS)
+return -ENOMEM;
+for(idx = idx_base; idx < idx_base+cnt_names; idx++)
+{
+if(rte_bitmap_get(stats->bits, idx))
+{
+break;
+}
+}
+if(idx == idx_base+cnt_names)
+{
+break;
+}
+idx_name = idx;
+}
 }
-entry->idx_next_stat = 0;
-entry->idx_next_set = 0;
+for(idx = idx_base; idx < idx_base+cnt_names; idx++)
+{
+rte_bitmap_set(stats->bits, idx);
+entry = &stats->metadata[idx];
+strlcpy(entry->name, names[idx-idx_base], RTE_METRICS_MAX_NAME_LEN);
+memset(entry->value, 0, sizeof(entry->value));
+entry->global_value = 0;
+    }
 stats->cnt_stats += cnt_names;
 
 rte_spinlock_unlock(&stats->lock);
@@ -142,7 +174,6 @@ struct rte_metrics_data_s {
 const uint64_t *values,
 uint32_t count)
 {
-struct rte_metrics_meta_s *entry;
 struct rte_metrics_data_s *stats;
 const struct rte_memzone *memzone;
 uint16_t idx_metric;
@@ -163,18 +194,14 @@ struct rte_metrics_data_s {
 
 rte_spinlock_lock(&stats->lock);
 
-if (key >= stats->cnt_stats) {
-rte_spinlock_unlock(&stats->lock);
-return -EINVAL;
-}
 idx_metric = key;
 cnt_setsize = 1;
-while (idx_metric < stats->cnt_stats) {
-entry = &stats->metadata[idx_metric];
-if (entry->idx_next_stat == 0)
-break;
-cnt_setsize++;
-idx_metric++;
+while (idx_metric < RTE_METRICS_MAX_METRICS) {
+if(rte_bitmap_get(stats->bits, idx_metric)){
+    cnt_setsize++;
+    idx_metric++;
+        }else
+            break;
 }
 /* Check update does not cross set border */
 if (count > cnt_setsize) {
@@ -199,12 +226,67 @@ struct rte_metrics_data_s {
 }
 
 int
+rte_metrics_unreg_values(uint16_t key, uint16_t count)
+{
+    struct rte_metrics_data_s *stats;
+    const struct rte_memzone *memzone;
+    uint16_t idx_metric;
+    uint16_t idx_value;
+uint16_t cnt_setsize;
+
+    /* Some sanity checks */
+    if (count < 1 )
+        return -EINVAL;
+
+    memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
+    if (memzone == NULL)
+        return -EIO;
+    stats = memzone->addr;
+
+    if (stats->cnt_stats < count)
+        return -EINVAL;
+
+    if (key >= RTE_METRICS_MAX_METRICS) {
+return -EINVAL;
+}
+    
+    rte_spinlock_lock(&stats->lock);
+    
+idx_metric = key;
+cnt_setsize = 1;
+while (idx_metric < RTE_METRICS_MAX_METRICS) {
+if(rte_bitmap_get(stats->bits,idx_metric)){
+    cnt_setsize++;
+    idx_metric++;
+        }else
+            break;
+}
+/* Check update does not cross set border */
+if (count > cnt_setsize) {
+rte_spinlock_unlock(&stats->lock);
+return -ERANGE;
+}
+
+
+for (idx_value = 0; idx_value < count; idx_value++) {
+idx_metric = key + idx_value;
+memset(stats->metadata[idx_metric].name, 0, RTE_METRICS_MAX_NAME_LEN) ;
+        rte_bitmap_clear(stats->bits, idx_metric);
+    }
+    stats->cnt_stats -= count;
+    rte_spinlock_unlock(&stats->lock);
+
+    return 0;
+}
+
+
+int
 rte_metrics_get_names(struct rte_metric_name *names,
 uint16_t capacity)
 {
 struct rte_metrics_data_s *stats;
 const struct rte_memzone *memzone;
-uint16_t idx_name;
+uint16_t idx_name, idx=0;
 int return_value;
 
 memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
@@ -219,10 +301,14 @@ struct rte_metrics_data_s {
 rte_spinlock_unlock(&stats->lock);
 return return_value;
 }
-for (idx_name = 0; idx_name < stats->cnt_stats; idx_name++)
-strlcpy(names[idx_name].name,
-stats->metadata[idx_name].name,
-RTE_METRICS_MAX_NAME_LEN);
+for (idx_name = 0;idx< stats->cnt_stats && idx_name < RTE_METRICS_MAX_METRICS; idx_name++)
+if(rte_bitmap_get(stats->bits,idx_name))
+{
+strlcpy(names[idx].name,
+stats->metadata[idx_name].name,
+RTE_METRICS_MAX_NAME_LEN);
+idx ++;
+}
 }
 return_value = stats->cnt_stats;
 rte_spinlock_unlock(&stats->lock);
@@ -237,7 +323,7 @@ struct rte_metrics_data_s {
 struct rte_metrics_meta_s *entry;
 struct rte_metrics_data_s *stats;
 const struct rte_memzone *memzone;
-uint16_t idx_name;
+uint16_t idx_name, idx=0;
 int return_value;
 
 if (port_id != RTE_METRICS_GLOBAL &&
@@ -257,22 +343,21 @@ struct rte_metrics_data_s {
 rte_spinlock_unlock(&stats->lock);
 return return_value;
 }
-if (port_id == RTE_METRICS_GLOBAL)
-for (idx_name = 0;
-idx_name < stats->cnt_stats;
-idx_name++) {
-entry = &stats->metadata[idx_name];
-values[idx_name].key = idx_name;
-values[idx_name].value = entry->global_value;
-}
-else
-for (idx_name = 0;
-idx_name < stats->cnt_stats;
-idx_name++) {
+
+for (idx_name = 0;idx< stats->cnt_stats &&
+idx_name < RTE_METRICS_MAX_METRICS;
+idx_name++) {
+if(rte_bitmap_get(stats->bits,idx_name))
+{
 entry = &stats->metadata[idx_name];
-values[idx_name].key = idx_name;
-values[idx_name].value = entry->value[port_id];
+values[idx].key = idx_name;
+if (port_id == RTE_METRICS_GLOBAL)
+values[idx].value = entry->global_value;
+else
+values[idx].value = entry->value[port_id];
+idx++;
 }
+}
 }
 return_value = stats->cnt_stats;
 rte_spinlock_unlock(&stats->lock);
diff --git a/lib/librte_metrics/rte_metrics.h b/lib/librte_metrics/rte_metrics.h
index 67a60fa..fb1859b 100644
--- a/lib/librte_metrics/rte_metrics.h
+++ b/lib/librte_metrics/rte_metrics.h
@@ -123,6 +123,27 @@ struct rte_metric_value {
 int rte_metrics_reg_names(const char * const *names, uint16_t cnt_names);
 
 /**
+ * Un-register set of metrics.
+ *
+ * Remove the metrics previously registerd
+ *
+ * @param key
+ *   Id of metrics to remove
+ *
+ * @param count
+ *   Number of metrics
+ *
+ * @return
+ *  - Zero: Success
+ *  - -EIO: Error, unable to access metrics shared memory
+ *    (rte_metrics_init() not called)
+ *  - -EINVAL: Error, invalid parameters
+ *  - -ERANGE: Error, oversized
+ */
+int
+rte_metrics_unreg_values(uint16_t key, uint16_t count);
+
+/**
  * Get metric name-key lookup table.
  *
  * @param names
