Просмотр исходного кода

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>
Jan Friesse 14 лет назад
Родитель
Сommit
a1df899d35
2 измененных файлов с 86 добавлено и 2 удалено
  1. 66 2
      exec/icmap.c
  2. 20 0
      include/corosync/icmap.h

+ 66 - 2
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;

+ 20 - 0
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
  */