From c0f45bf12e34121bdf5c117e215586d2b92c4aec Mon Sep 17 00:00:00 2001 From: sundb Date: Wed, 25 Nov 2020 03:40:58 +0800 Subject: [PATCH] Avoid excessive malloc and free in copyCommand robj creation (#8067) Avoid multiple conditional judgments Avoid allocating robj->ptr when we're gonna replace it right after. --- src/t_hash.c | 27 +++++++++------------------ src/t_list.c | 5 ++--- src/t_set.c | 24 +++++++----------------- src/t_zset.c | 24 ++++++------------------ 4 files changed, 24 insertions(+), 56 deletions(-) diff --git a/src/t_hash.c b/src/t_hash.c index 5c844ce30..f3fde87aa 100644 --- a/src/t_hash.c +++ b/src/t_hash.c @@ -515,29 +515,17 @@ robj *hashTypeDup(robj *o) { serverAssert(o->type == OBJ_HASH); - switch (o->encoding) { - case OBJ_ENCODING_ZIPLIST: - hobj = createHashObject(); - break; - case OBJ_ENCODING_HT: - hobj = createHashObject(); - hashTypeConvert(hobj, OBJ_ENCODING_HT); - dict *d = o->ptr; - dictExpand(hobj->ptr, dictSize(d)); - break; - default: - serverPanic("Wrong encoding."); - break; - } - if(o->encoding == OBJ_ENCODING_ZIPLIST){ unsigned char *zl = o->ptr; size_t sz = ziplistBlobLen(zl); unsigned char *new_zl = zmalloc(sz); memcpy(new_zl, zl, sz); - zfree(hobj->ptr); - hobj->ptr = new_zl; + hobj = createObject(OBJ_HASH, new_zl); + hobj->encoding = OBJ_ENCODING_ZIPLIST; } else if(o->encoding == OBJ_ENCODING_HT){ + dict *d = dictCreate(&hashDictType, NULL); + dictExpand(d, dictSize((const dict*)o->ptr)); + hi = hashTypeInitIterator(o); while (hashTypeNext(hi) != C_ERR) { sds field, value; @@ -549,9 +537,12 @@ robj *hashTypeDup(robj *o) { newvalue = sdsdup(value); /* Add a field-value pair to a new hash object. */ - dictAdd(hobj->ptr,newfield,newvalue); + dictAdd(d,newfield,newvalue); } hashTypeReleaseIterator(hi); + + hobj = createObject(OBJ_HASH, d); + hobj->encoding = OBJ_ENCODING_HT; } else { serverPanic("Unknown hash encoding"); } diff --git a/src/t_list.c b/src/t_list.c index ce1472d93..acabe7be2 100644 --- a/src/t_list.c +++ b/src/t_list.c @@ -202,14 +202,13 @@ robj *listTypeDup(robj *o) { switch (o->encoding) { case OBJ_ENCODING_QUICKLIST: - lobj = createQuicklistObject(); + lobj = createObject(OBJ_LIST, quicklistDup(o->ptr)); + lobj->encoding = OBJ_ENCODING_QUICKLIST; break; default: serverPanic("Wrong encoding."); break; } - zfree(lobj->ptr); - lobj->ptr = quicklistDup(o->ptr); return lobj; } diff --git a/src/t_set.c b/src/t_set.c index cb4c5002f..b2da14cd5 100644 --- a/src/t_set.c +++ b/src/t_set.c @@ -275,27 +275,17 @@ robj *setTypeDup(robj *o) { serverAssert(o->type == OBJ_SET); /* Create a new set object that have the same encoding as the original object's encoding */ - switch (o->encoding) { - case OBJ_ENCODING_INTSET: - set = createIntsetObject(); - break; - case OBJ_ENCODING_HT: - set = createSetObject(); - dict *d = o->ptr; - dictExpand(set->ptr, dictSize(d)); - break; - default: - serverPanic("Wrong encoding."); - break; - } - if (set->encoding == OBJ_ENCODING_INTSET) { + if (o->encoding == OBJ_ENCODING_INTSET) { intset *is = o->ptr; size_t size = intsetBlobLen(is); intset *newis = zmalloc(size); memcpy(newis,is,size); - zfree(set->ptr); - set->ptr = newis; - } else if (set->encoding == OBJ_ENCODING_HT) { + set = createObject(OBJ_SET, newis); + set->encoding = OBJ_ENCODING_INTSET; + } else if (o->encoding == OBJ_ENCODING_HT) { + set = createSetObject(); + dict *d = o->ptr; + dictExpand(set->ptr, dictSize(d)); si = setTypeInitIterator(o); while (setTypeNext(si, &elesds, &intobj) != -1) { setTypeAdd(set, elesds); diff --git a/src/t_zset.c b/src/t_zset.c index 1f5f00a62..a6ce20132 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -1567,30 +1567,18 @@ robj *zsetDup(robj *o) { serverAssert(o->type == OBJ_ZSET); /* Create a new sorted set object that have the same encoding as the original object's encoding */ - switch (o->encoding) { - case OBJ_ENCODING_ZIPLIST: - zobj = createZsetZiplistObject(); - break; - case OBJ_ENCODING_SKIPLIST: - zobj = createZsetObject(); - zs = o->ptr; - new_zs = zobj->ptr; - dictExpand(new_zs->dict,dictSize(zs->dict)); - break; - default: - serverPanic("Wrong encoding."); - break; - } - if (zobj->encoding == OBJ_ENCODING_ZIPLIST) { + if (o->encoding == OBJ_ENCODING_ZIPLIST) { unsigned char *zl = o->ptr; size_t sz = ziplistBlobLen(zl); unsigned char *new_zl = zmalloc(sz); memcpy(new_zl, zl, sz); - zfree(zobj->ptr); - zobj->ptr = new_zl; - } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { + zobj = createObject(OBJ_ZSET, new_zl); + zobj->encoding = OBJ_ENCODING_ZIPLIST; + } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { + zobj = createZsetObject(); zs = o->ptr; new_zs = zobj->ptr; + dictExpand(new_zs->dict,dictSize(zs->dict)); zskiplist *zsl = zs->zsl; zskiplistNode *ln; sds ele;