summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohit Agrawal <moagrawa@redhat.com>2020-07-25 11:28:43 +0530
committerMOHIT AGRAWAL <moagrawa@redhat.com>2020-07-31 06:06:03 +0000
commitdbff4ecfc18d4d4ad357e2f53806a6caf69d2b65 (patch)
tree41c18e03c3950474e82cf3f3597cdf044d6f7165
parent3204091c850a92f492c8f89099c1ecebb502d01f (diff)
dict: optimize dict_serialized_length_lk function
To return the length of searlized dictionary the function iterates full dictionary and access every key value member of the dictionary.Instead of iterating full dictionary introduce a variable totkvlen at dictionary to save the key value length at the time of storing key/value pair in the dictionary. Change-Id: Ie8cfdea1cc335bce51f59179281df3c89afab68b Fixes: #1395 Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
-rw-r--r--libglusterfs/src/dict.c47
-rw-r--r--libglusterfs/src/glusterfs/dict.h4
2 files changed, 12 insertions, 39 deletions
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c
index f53d26ece4d..917737a943e 100644
--- a/libglusterfs/src/dict.c
+++ b/libglusterfs/src/dict.c
@@ -98,6 +98,7 @@ get_new_dict_full(int size_hint)
}
dict->free_pair.key = NULL;
+ dict->totkvlen = 0;
LOCK_INIT(&dict->lock);
return dict;
@@ -410,6 +411,7 @@ dict_set_lk(dict_t *this, char *key, const int key_len, data_t *value,
if (pair) {
data_t *unref_data = pair->value;
pair->value = data_ref(value);
+ this->totkvlen += (value->len - unref_data->len);
data_unref(unref_data);
if (key_free)
GF_FREE(key);
@@ -445,6 +447,7 @@ dict_set_lk(dict_t *this, char *key, const int key_len, data_t *value,
}
pair->key_hash = key_hash;
pair->value = data_ref(value);
+ this->totkvlen += (keylen + 1 + value->len);
/* If the divisor is 1, the modulo is always 0,
* in such case avoid hash calculation.
@@ -642,6 +645,7 @@ dict_deln(dict_t *this, char *key, const int keylen)
else
this->members[hashval] = pair->hash_next;
+ this->totkvlen -= pair->value->len;
data_unref(pair->value);
if (pair->prev)
@@ -652,6 +656,7 @@ dict_deln(dict_t *this, char *key, const int keylen)
if (pair->next)
pair->next->prev = pair->prev;
+ this->totkvlen -= (strlen(pair->key) + 1);
GF_FREE(pair->key);
if (pair == &this->free_pair) {
this->free_pair.key = NULL;
@@ -701,6 +706,7 @@ dict_destroy(dict_t *this)
prev = pair;
}
+ this->totkvlen = 0;
if (this->members != &this->members_internal) {
mem_put(this->members);
}
@@ -2175,7 +2181,7 @@ _dict_modify_flag(dict_t *this, char *key, int flag, int op)
strcpy(pair->key, key);
pair->key_hash = hash;
pair->value = data_ref(data);
-
+ this->totkvlen += (strlen(key) + 1 + data->len);
hashval = hash % this->hash_size;
pair->hash_next = this->members[hashval];
this->members[hashval] = pair;
@@ -2901,8 +2907,7 @@ dict_serialized_length_lk(dict_t *this)
{
int ret = -EINVAL;
int count = this->count;
- int len = DICT_HDR_LEN;
- data_pair_t *pair = this->members_list;
+ const int keyhdrlen = DICT_DATA_HDR_KEY_LEN + DICT_DATA_HDR_VAL_LEN;
if (count < 0) {
gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_COUNT_LESS_THAN_ZERO,
@@ -2910,41 +2915,7 @@ dict_serialized_length_lk(dict_t *this)
goto out;
}
- while (count) {
- if (!pair) {
- gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_PAIRS_LESS_THAN_COUNT,
- NULL);
- goto out;
- }
-
- len += DICT_DATA_HDR_KEY_LEN + DICT_DATA_HDR_VAL_LEN;
-
- if (!pair->key) {
- gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_NULL_PTR, NULL);
- goto out;
- }
-
- len += strlen(pair->key) + 1 /* for '\0' */;
-
- if (!pair->value) {
- gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_NULL_PTR, NULL);
- goto out;
- }
-
- if (pair->value->len < 0) {
- gf_smsg("dict", GF_LOG_ERROR, EINVAL,
- LG_MSG_VALUE_LENGTH_LESS_THAN_ZERO, "len=%d",
- pair->value->len, NULL);
- goto out;
- }
-
- len += pair->value->len;
-
- pair = pair->next;
- count--;
- }
-
- ret = len;
+ ret = DICT_HDR_LEN + this->totkvlen + (count * keyhdrlen);
out:
return ret;
}
diff --git a/libglusterfs/src/glusterfs/dict.h b/libglusterfs/src/glusterfs/dict.h
index ce1c2100276..d4bf9b4f1a7 100644
--- a/libglusterfs/src/glusterfs/dict.h
+++ b/libglusterfs/src/glusterfs/dict.h
@@ -98,7 +98,7 @@ struct _data {
char *data;
gf_atomic_t refcount;
gf_dict_data_type_t data_type;
- int32_t len;
+ uint32_t len;
gf_boolean_t is_static;
};
@@ -122,6 +122,8 @@ struct _dict {
gf_lock_t lock;
data_pair_t *members_internal;
data_pair_t free_pair;
+ /* Variable to store total keylen + value->len */
+ uint32_t totkvlen;
};
typedef gf_boolean_t (*dict_match_t)(dict_t *d, char *k, data_t *v, void *data);