diff options
Diffstat (limited to 'libglusterfs/src/dict.c')
| -rw-r--r-- | libglusterfs/src/dict.c | 216 |
1 files changed, 169 insertions, 47 deletions
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index c290e0d62..3b7ddce5e 100644 --- a/libglusterfs/src/dict.c +++ b/libglusterfs/src/dict.c @@ -14,6 +14,7 @@ #include <stdio.h> #include <inttypes.h> #include <limits.h> +#include <fnmatch.h> #ifndef _CONFIG_H #define _CONFIG_H @@ -208,7 +209,7 @@ _dict_lookup (dict_t *this, char *key) } int32_t -dict_lookup (dict_t *this, char *key, data_pair_t **data) +dict_lookup (dict_t *this, char *key, data_t **data) { if (!this || !key || !data) { gf_log_callingfn ("dict", GF_LOG_WARNING, @@ -216,22 +217,22 @@ dict_lookup (dict_t *this, char *key, data_pair_t **data) return -1; } + data_pair_t *tmp = NULL; LOCK (&this->lock); { - *data = _dict_lookup (this, key); + tmp = _dict_lookup (this, key); } UNLOCK (&this->lock); - if (*data) - return 0; - else + + if (!tmp) return -1; + *data = tmp->value; + return 0; } static int32_t -_dict_set (dict_t *this, - char *key, - data_t *value) +_dict_set (dict_t *this, char *key, data_t *value, gf_boolean_t replace) { int hashval; data_pair_t *pair; @@ -250,17 +251,22 @@ _dict_set (dict_t *this, tmp = SuperFastHash (key, strlen (key)); hashval = (tmp % this->hash_size); - pair = _dict_lookup (this, key); - if (pair) { - data_t *unref_data = pair->value; - pair->value = data_ref (value); - data_unref (unref_data); - if (key_free) - GF_FREE (key); - /* Indicates duplicate key */ - return 0; + /* Search for a existing key if 'replace' is asked for */ + if (replace) { + pair = _dict_lookup (this, key); + + if (pair) { + data_t *unref_data = pair->value; + pair->value = data_ref (value); + data_unref (unref_data); + if (key_free) + GF_FREE (key); + /* Indicates duplicate key */ + return 0; + } } + if (this->free_pair_in_use) { pair = mem_get0 (THIS->ctx->dict_pair_pool); if (!pair) { @@ -325,7 +331,28 @@ dict_set (dict_t *this, LOCK (&this->lock); - ret = _dict_set (this, key, value); + ret = _dict_set (this, key, value, 1); + + UNLOCK (&this->lock); + + return ret; +} + + +int32_t +dict_add (dict_t *this, char *key, data_t *value) +{ + int32_t ret; + + if (!this || !value) { + gf_log_callingfn ("dict", GF_LOG_WARNING, + "!this || !value for key=%s", key); + return -1; + } + + LOCK (&this->lock); + + ret = _dict_set (this, key, value, 0); UNLOCK (&this->lock); @@ -869,7 +896,7 @@ data_to_int32 (data_t *data) int16_t data_to_int16 (data_t *data) { - int16_t value = 0; + int16_t value = 0; if (!data) { gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL"); @@ -883,16 +910,16 @@ data_to_int16 (data_t *data) memcpy (str, data->data, data->len); str[data->len] = '\0'; - errno = 0; - value = strtol (str, NULL, 0); + errno = 0; + value = strtol (str, NULL, 0); - if ((SHRT_MAX > value) || (SHRT_MIN < value)) { - errno = ERANGE; + if ((value > SHRT_MAX) || (value < SHRT_MIN)) { + errno = ERANGE; gf_log_callingfn ("dict", GF_LOG_WARNING, - "Error in data conversion: " - "detected overflow"); + "Error in data conversion: " + "detected overflow"); return -1; - } + } return (int16_t)value; } @@ -901,7 +928,7 @@ data_to_int16 (data_t *data) int8_t data_to_int8 (data_t *data) { - int32_t value = 0; + int8_t value = 0; if (!data) { gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL"); @@ -915,16 +942,16 @@ data_to_int8 (data_t *data) memcpy (str, data->data, data->len); str[data->len] = '\0'; - errno = 0; - value = strtol (str, NULL, 0); + errno = 0; + value = strtol (str, NULL, 0); - if ((SCHAR_MAX > value) || (SCHAR_MIN < value)) { - errno = ERANGE; + if ((value > SCHAR_MAX) || (value < SCHAR_MIN)) { + errno = ERANGE; gf_log_callingfn ("dict", GF_LOG_WARNING, - "Error in data conversion: " - "detected overflow"); + "Error in data conversion: " + "detected overflow"); return -1; - } + } return (int8_t)value; } @@ -1051,47 +1078,141 @@ data_to_bin (data_t *data) return data->data; } -void +int +dict_null_foreach_fn (dict_t *d, char *k, + data_t *v, void *tmp) +{ + return 0; +} + +int dict_foreach (dict_t *dict, - void (*fn)(dict_t *this, - char *key, - data_t *value, - void *data), + int (*fn)(dict_t *this, + char *key, + data_t *value, + void *data), void *data) { if (!dict) { gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL"); - return; + return -1; } - data_pair_t *pairs = dict->members_list; - data_pair_t *next = NULL; + int ret = -1; + data_pair_t *pairs = NULL; + data_pair_t *next = NULL; + pairs = dict->members_list; while (pairs) { next = pairs->next; - fn (dict, pairs->key, pairs->value, data); + ret = fn (dict, pairs->key, pairs->value, data); + if (ret == -1) + return -1; pairs = next; } + + return 0; +} + +/* return values: + -1 = failure, + 0 = no matches found, + +n = n number of matches +*/ +int +dict_foreach_fnmatch (dict_t *dict, char *pattern, + int (*fn)(dict_t *this, + char *key, + data_t *value, + void *data), + void *data) +{ + if (!dict) { + gf_log_callingfn ("dict", GF_LOG_WARNING, + "dict is NULL"); + return 0; + } + + int ret = -1; + int count = 0; + data_pair_t *pairs = NULL; + data_pair_t *next = NULL; + + pairs = dict->members_list; + while (pairs) { + next = pairs->next; + if (!fnmatch (pattern, pairs->key, 0)) { + ret = fn (dict, pairs->key, pairs->value, data); + if (ret == -1) + return -1; + count++; + } + pairs = next; + } + + return count; } -static void +/** + * dict_keys_join - pack the keys of the dictionary in a buffer. + * + * @value : buffer in which the keys will be packed (can be NULL) + * @size : size of the buffer which is sent (can be 0, in which case buffer + * is not packed but only length is returned) + * @dict : dictionary of which all the keys will be packed + * @filter_fn : keys matched in filter_fn() is counted. + * + * @return : @length of string after joining keys. + * + */ + +int +dict_keys_join (void *value, int size, dict_t *dict, + int (*filter_fn)(char *k)) +{ + int len = 0; + data_pair_t *pairs = NULL; + data_pair_t *next = NULL; + + pairs = dict->members_list; + while (pairs) { + next = pairs->next; + + if (filter_fn && filter_fn (pairs->key)){ + pairs = next; + continue; + } + + if (value && (size > len)) + strncpy (value + len, pairs->key, size - len); + + len += (strlen (pairs->key) + 1); + + pairs = next; + } + + return len; +} + +static int _copy (dict_t *unused, char *key, data_t *value, void *newdict) { - dict_set ((dict_t *)newdict, key, (value)); + return dict_set ((dict_t *)newdict, key, (value)); } -static void +static int _remove (dict_t *dict, char *key, data_t *value, void *unused) { dict_del ((dict_t *)dict, key); + return 0; } @@ -2455,6 +2576,7 @@ dict_unserialize (char *orig_buf, int32_t size, dict_t **fill) "available (%lu) < required (%lu)", (long)(orig_buf + size), (long)(buf + vallen)); + goto out; } value = get_new_data (); value->len = vallen; @@ -2462,7 +2584,7 @@ dict_unserialize (char *orig_buf, int32_t size, dict_t **fill) value->is_static = 0; buf += vallen; - dict_set (*fill, key, value); + dict_add (*fill, key, value); } ret = 0; |
