summaryrefslogtreecommitdiff
path: root/src/t_hash.c
diff options
context:
space:
mode:
authorkmy2001 <jerrykang026@gmail.com>2022-08-14 19:53:40 +0800
committerGitHub <noreply@github.com>2022-08-14 14:53:40 +0300
commiteef2d8303d7be6be50ea3b1e45f375765933da9b (patch)
tree1393899840b2eae6e3ad6a63fdd9b0fabb27dc90 /src/t_hash.c
parentc5ff163d53f1e9c1b647c4bf413386015ac4be71 (diff)
downloadredis-eef2d8303d7be6be50ea3b1e45f375765933da9b.tar.gz
Optimization in t_hash.c: Avoid looking for a same field twice by using dictAddRaw() instead of dictFind() and dictAdd() (#11110)
Before this change in hashTypeSet() function, we first use dictFind() to look for the field and if it does not exist, we use dictAdd() to add it. In dictAdd() function the dictionary will look for the field again and I think this is meaningless as we already know that the field does not exist. An optimization is to use dictAddRaw() instead of dictFind() and dictAdd(). If we use dictAddRaw(), a new entry will be added when the field does not exist, and what we should do then is just set the value of that entry, and set its key to 'sdsdup(field)' in the case that 'HASH_SET_TAKE_FIELD' flag wasn't set.
Diffstat (limited to 'src/t_hash.c')
-rw-r--r--src/t_hash.c36
1 files changed, 16 insertions, 20 deletions
diff --git a/src/t_hash.c b/src/t_hash.c
index 7aec270aa..63447a4c1 100644
--- a/src/t_hash.c
+++ b/src/t_hash.c
@@ -227,31 +227,27 @@ int hashTypeSet(robj *o, sds field, sds value, int flags) {
if (hashTypeLength(o) > server.hash_max_listpack_entries)
hashTypeConvert(o, OBJ_ENCODING_HT);
} else if (o->encoding == OBJ_ENCODING_HT) {
- dictEntry *de = dictFind(o->ptr,field);
- if (de) {
- sdsfree(dictGetVal(de));
- if (flags & HASH_SET_TAKE_VALUE) {
- dictGetVal(de) = value;
- value = NULL;
- } else {
- dictGetVal(de) = sdsdup(value);
- }
- update = 1;
+ dict *ht = o->ptr;
+ dictEntry *de, *existing;
+ sds v;
+ if (flags & HASH_SET_TAKE_VALUE) {
+ v = value;
+ value = NULL;
} else {
- sds f,v;
+ v = sdsdup(value);
+ }
+ de = dictAddRaw(ht, field, &existing);
+ if (de) {
+ dictSetVal(ht, de, v);
if (flags & HASH_SET_TAKE_FIELD) {
- f = field;
field = NULL;
} else {
- f = sdsdup(field);
- }
- if (flags & HASH_SET_TAKE_VALUE) {
- v = value;
- value = NULL;
- } else {
- v = sdsdup(value);
+ dictSetKey(ht, de, sdsdup(field));
}
- dictAdd(o->ptr,f,v);
+ } else {
+ sdsfree(dictGetVal(existing));
+ dictSetVal(ht, existing, v);
+ update = 1;
}
} else {
serverPanic("Unknown hash encoding");