Avoids reallocating and double String on truncate

This commit is contained in:
Itamar Haber 2016-04-25 01:41:29 -07:00 committed by antirez
parent d41bd233d5
commit 3816f16a53

View File

@ -1093,25 +1093,24 @@ int RM_StringTruncate(RedisModuleKey *key, size_t newlen) {
* doing anything. */ * doing anything. */
if (key->value == NULL && newlen == 0) return REDISMODULE_OK; if (key->value == NULL && newlen == 0) return REDISMODULE_OK;
/* Empty key: fill it with a zero-length key so that we can handle the
* resize with a common code path. */
if (key->value == NULL) { if (key->value == NULL) {
robj *emptyobj = createStringObject("",0); /* Empty key: create it with the new size. */
setKey(key->db,key->key,emptyobj); robj *o = createObject(OBJ_STRING,sdsnewlen(NULL, newlen));
key->value = emptyobj; setKey(key->db,key->key,o);
decrRefCount(emptyobj); key->value = o;
} decrRefCount(o);
} else {
/* Unshare and resize. */ /* Unshare and resize. */
key->value = dbUnshareStringValue(key->db, key->key, key->value); key->value = dbUnshareStringValue(key->db, key->key, key->value);
size_t curlen = sdslen(key->value->ptr); size_t curlen = sdslen(key->value->ptr);
if (newlen > curlen) { if (newlen > curlen) {
key->value->ptr = sdsgrowzero(key->value->ptr,newlen); key->value->ptr = sdsgrowzero(key->value->ptr,newlen);
} else if (newlen < curlen) { } else if (newlen < curlen) {
sdsrange(key->value->ptr,0,newlen-1); sdsrange(key->value->ptr,0,newlen-1);
/* If the string is too wasteful, reallocate it. */ /* If the string is too wasteful, reallocate it. */
if (sdslen(key->value->ptr) < sdsavail(key->value->ptr)) if (sdslen(key->value->ptr) < sdsavail(key->value->ptr))
key->value->ptr = sdsRemoveFreeSpace(key->value->ptr); key->value->ptr = sdsRemoveFreeSpace(key->value->ptr);
}
} }
return REDISMODULE_OK; return REDISMODULE_OK;
} }