icmap: Add fast version of inc and dec operation

Biggest difference between fast and standard inc/dec operation is in
fast that fast doesn't do malloc/memcpy, but also it means that tracking
events doesn't have old value set.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Steven Dake <sdake@redhat.com>
This commit is contained in:
Jan Friesse 2012-01-12 17:55:53 +01:00
parent 601684d2f6
commit a1df899d35
2 changed files with 86 additions and 2 deletions

View File

@ -172,7 +172,10 @@ static void icmap_map_free_cb(uint32_t event,
{
struct icmap_item *item = (struct icmap_item *)old_value;
if (item != NULL) {
/*
* value == old_value -> fast_adjust_int was used, don't free data
*/
if (item != NULL && value != old_value) {
free(item->key_name);
free(item);
}
@ -681,6 +684,54 @@ cs_error_t icmap_adjust_int(
return (err);
}
cs_error_t icmap_fast_adjust_int(
const char *key_name,
int32_t step)
{
struct icmap_item *item;
cs_error_t err = CS_OK;
if (key_name == NULL) {
return (CS_ERR_INVALID_PARAM);
}
item = qb_map_get(icmap_map, key_name);
if (item == NULL) {
return (CS_ERR_NOT_EXIST);
}
switch (item->type) {
case ICMAP_VALUETYPE_INT8:
case ICMAP_VALUETYPE_UINT8:
*(uint8_t *)item->value += step;
break;
case ICMAP_VALUETYPE_INT16:
case ICMAP_VALUETYPE_UINT16:
*(uint16_t *)item->value += step;
break;
case ICMAP_VALUETYPE_INT32:
case ICMAP_VALUETYPE_UINT32:
*(uint32_t *)item->value += step;
break;
case ICMAP_VALUETYPE_INT64:
case ICMAP_VALUETYPE_UINT64:
*(uint64_t *)item->value += step;
break;
case ICMAP_VALUETYPE_FLOAT:
case ICMAP_VALUETYPE_DOUBLE:
case ICMAP_VALUETYPE_STRING:
case ICMAP_VALUETYPE_BINARY:
err = CS_ERR_INVALID_PARAM;
break;
}
if (err == CS_OK) {
qb_map_put(icmap_map, item->key_name, item);
}
return (err);
}
cs_error_t icmap_inc(const char *key_name)
{
return (icmap_adjust_int(key_name, 1));
@ -691,6 +742,16 @@ cs_error_t icmap_dec(const char *key_name)
return (icmap_adjust_int(key_name, -1));
}
cs_error_t icmap_fast_inc(const char *key_name)
{
return (icmap_fast_adjust_int(key_name, 1));
}
cs_error_t icmap_fast_dec(const char *key_name)
{
return (icmap_fast_adjust_int(key_name, -1));
}
icmap_iter_t icmap_iter_init(const char *prefix)
{
return (qb_map_pref_iter_create(icmap_map, prefix));
@ -742,7 +803,10 @@ static void icmap_notify_fn(uint32_t event, char *key, void *old_value, void *va
memset(&new_val, 0, sizeof(new_val));
}
if (old_item != NULL) {
/*
* old_item == new_item if fast functions are used -> don't fill old value
*/
if (old_item != NULL && old_item != new_item) {
old_val.type = old_item->type;
old_val.len = old_item->value_len;
old_val.data = old_item->value;

View File

@ -188,6 +188,14 @@ extern cs_error_t icmap_get_string(const char *key_name, char **str);
*/
extern cs_error_t icmap_adjust_int(const char *key_name, int32_t step);
/*
* Defined only for [u]int* values. It adds step to current value. Difference
* between this function and icmap_adjust_int is given in fact, that in
* tracking callback, old value is undefined, but whole process is done
* without malloc/memcpy.
*/
extern cs_error_t icmap_fast_adjust_int(const char *key_name, int32_t step);
/*
* Increase stored value by one
*/
@ -198,6 +206,18 @@ extern cs_error_t icmap_inc(const char *key_name);
*/
extern cs_error_t icmap_dec(const char *key_name);
/*
* Increase stored value by one. Difference between this function and icmap_inc
* is same as between icmap_adjust_int and icmap_fast_adjust_int.
*/
extern cs_error_t icmap_fast_inc(const char *key_name);
/*
* Decrease stored value by one. Difference between this function and icmap_dec
* is same as between icmap_adjust_int and icmap_fast_adjust_int.
*/
extern cs_error_t icmap_fast_dec(const char *key_name);
/*
* Initialize iterator with given prefix
*/