diff options
| author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-10-12 18:47:09 +0200 | 
|---|---|---|
| committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-10-28 23:51:24 +0100 | 
| commit | b27b352e937dd0760da1e7fb05f9207be05702b8 (patch) | |
| tree | df0a1dc555ee1ada807e51260de918dcf6f53370 /src | |
| parent | 0a1400fc8311268d0a66bb20e0620e546e8d11c8 (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')
| -rw-r--r-- | src/stat_item.c | 71 | 
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) | 
