summaryrefslogtreecommitdiffstats
path: root/src/stat_item.c
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2015-10-12 18:47:09 +0200
committerJacob Erlbeck <jerlbeck@sysmocom.de>2015-10-28 23:51:24 +0100
commitb27b352e937dd0760da1e7fb05f9207be05702b8 (patch)
treedf0a1dc555ee1ada807e51260de918dcf6f53370 /src/stat_item.c
parent0a1400fc8311268d0a66bb20e0620e546e8d11c8 (diff)
stats: Use a global index for stat item values
Currently each stat item has a separate index value which basically counts each single value added to the item and which can be used by a reporter to get all new values that have not been reported yet. The drawback is, that such an index must be stored for each stat item. This commit introduces a global index which is incremented for each new stat item value. This index is then stored together with the item value. So a single stored index per reporter is sufficient to make sure that only new values are reported. Sponsored-by: On-Waves ehf
Diffstat (limited to 'src/stat_item.c')
-rw-r--r--src/stat_item.c71
1 files changed, 47 insertions, 24 deletions
diff --git a/src/stat_item.c b/src/stat_item.c
index 7b169ea0..1e283d48 100644
--- a/src/stat_item.c
+++ b/src/stat_item.c
@@ -38,6 +38,7 @@
#include <osmocom/core/stat_item.h>
static LLIST_HEAD(stat_item_groups);
+static int32_t global_value_id = 0;
static void *tall_stat_item_ctx;
@@ -74,7 +75,8 @@ struct stat_item_group *stat_item_group_alloc(void *ctx,
for (item_idx = 0; item_idx < desc->num_items; item_idx++) {
unsigned int size;
size = sizeof(struct stat_item) +
- sizeof(int32_t) * desc->item_desc[item_idx].num_values;
+ sizeof(struct stat_item_value) *
+ desc->item_desc[item_idx].num_values;
/* Align to pointer size */
size = (size + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
@@ -101,8 +103,10 @@ struct stat_item_group *stat_item_group_alloc(void *ctx,
item->last_value_index = -1;
item->desc = &desc->item_desc[item_idx];
- for (i = 0; i <= item->last_offs; i++)
- item->values[i] = desc->item_desc[item_idx].default_value;
+ for (i = 0; i <= item->last_offs; i++) {
+ item->values[i].value = desc->item_desc[item_idx].default_value;
+ item->values[i].id = STAT_ITEM_NOVALUE_ID;
+ }
}
llist_add(&group->list, &stat_item_groups);
@@ -123,49 +127,68 @@ void stat_item_set(struct stat_item *item, int32_t value)
if (item->last_offs >= item->desc->num_values)
item->last_offs = 0;
- item->last_value_index += 1;
+ global_value_id += 1;
+ if (global_value_id == STAT_ITEM_NOVALUE_ID)
+ global_value_id += 1;
- item->values[item->last_offs] = value;
+ item->values[item->last_offs].value = value;
+ item->values[item->last_offs].id = global_value_id;
}
int stat_item_get_next(const struct stat_item *item, int32_t *next_idx,
int32_t *value)
{
- int32_t delta = item->last_value_index + 1 - *next_idx;
- int n_values = 0;
+ const struct stat_item_value *next_value;
+ const struct stat_item_value *item_value = NULL;
+ int idx_delta;
int next_offs;
- if (delta == 0)
- /* All items have been read */
- return 0;
+ next_offs = item->last_offs;
+ next_value = &item->values[next_offs];
- if (delta < 0 || delta > item->desc->num_values) {
- n_values = delta - item->desc->num_values;
- delta = item->desc->num_values;
+ while (next_value->id - *next_idx >= 0 &&
+ next_value->id != STAT_ITEM_NOVALUE_ID)
+ {
+ item_value = next_value;
+
+ next_offs -= 1;
+ if (next_offs < 0)
+ next_offs = item->desc->num_values - 1;
+ if (next_offs == item->last_offs)
+ break;
+ next_value = &item->values[next_offs];
}
- next_offs = item->last_offs + 1 - delta;
- if (next_offs < 0)
- next_offs += item->desc->num_values;
+ if (!item_value)
+ /* All items have been read */
+ return 0;
- *value = item->values[next_offs];
+ *value = item_value->value;
- n_values += 1;
- delta -= 1;
- *next_idx = item->last_value_index + 1 - delta;
+ idx_delta = item_value->id + 1 - *next_idx;
- return n_values;
+ *next_idx = item_value->id + 1;
+
+ return idx_delta;
}
-/*! \brief Skip all values and update idx accordingly */
+/*! \brief Skip all values of this item and update idx accordingly */
int stat_item_discard(const struct stat_item *item, int32_t *idx)
{
- int discarded = item->last_value_index + 1 - *idx;
- *idx = item->last_value_index + 1;
+ int discarded = item->values[item->last_offs].id + 1 - *idx;
+ *idx = item->values[item->last_offs].id + 1;
return discarded;
}
+/*! \brief Skip all values of all items and update idx accordingly */
+int stat_item_discard_all(int32_t *idx)
+{
+ int discarded = global_value_id + 1 - *idx;
+ *idx = global_value_id + 1;
+
+ return discarded;
+}
/*! \brief Initialize the stat item module */
int stat_item_init(void *tall_ctx)