From b27b352e937dd0760da1e7fb05f9207be05702b8 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 12 Oct 2015 18:47:09 +0200 Subject: 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 --- src/stat_item.c | 71 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 24 deletions(-) (limited to 'src/stat_item.c') 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 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) -- cgit v1.2.3