From a1df899d35f646ae16a3c1b7f1fc317477587e37 Mon Sep 17 00:00:00 2001 From: Jan Friesse Date: Thu, 12 Jan 2012 17:55:53 +0100 Subject: [PATCH] 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 Reviewed-by: Steven Dake --- exec/icmap.c | 68 ++++++++++++++++++++++++++++++++++++++-- include/corosync/icmap.h | 20 ++++++++++++ 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/exec/icmap.c b/exec/icmap.c index fb34eef1..4fd8d66b 100644 --- a/exec/icmap.c +++ b/exec/icmap.c @@ -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; diff --git a/include/corosync/icmap.h b/include/corosync/icmap.h index 896800b4..d7f64619 100644 --- a/include/corosync/icmap.h +++ b/include/corosync/icmap.h @@ -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 */ -- 2.39.5