diff options
author | swamp0407 <swamp0407@gmail.com> | 2020-11-17 19:03:05 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-17 12:03:05 +0200 |
commit | ea7cf737a1ff65524994ce6731eb9320891aa946 (patch) | |
tree | f6e491ee1f41765e916597c1d7719717da20353e /src/t_hash.c | |
parent | 9812e88959a37ed4aa95bb4d3fb55c56dc49a768 (diff) | |
download | redis-ea7cf737a1ff65524994ce6731eb9320891aa946.tar.gz |
Add COPY command (#7953)
Syntax:
COPY <key> <new-key> [DB <dest-db>] [REPLACE]
No support for module keys yet.
Co-authored-by: tmgauss
Co-authored-by: Itamar Haber <itamar@redislabs.com>
Co-authored-by: Oran Agra <oran@redislabs.com>
Diffstat (limited to 'src/t_hash.c')
-rw-r--r-- | src/t_hash.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/t_hash.c b/src/t_hash.c index 89193a41e..5c844ce30 100644 --- a/src/t_hash.c +++ b/src/t_hash.c @@ -504,6 +504,60 @@ void hashTypeConvert(robj *o, int enc) { } } +/* This is a helper function for the COPY command. + * Duplicate a hash object, with the guarantee that the returned object + * has the same encoding as the original one. + * + * The resulting object always has refcount set to 1 */ +robj *hashTypeDup(robj *o) { + robj *hobj; + hashTypeIterator *hi; + + 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; + } else if(o->encoding == OBJ_ENCODING_HT){ + hi = hashTypeInitIterator(o); + while (hashTypeNext(hi) != C_ERR) { + sds field, value; + sds newfield, newvalue; + /* Extract a field-value pair from an original hash object.*/ + field = hashTypeCurrentFromHashTable(hi, OBJ_HASH_KEY); + value = hashTypeCurrentFromHashTable(hi, OBJ_HASH_VALUE); + newfield = sdsdup(field); + newvalue = sdsdup(value); + + /* Add a field-value pair to a new hash object. */ + dictAdd(hobj->ptr,newfield,newvalue); + } + hashTypeReleaseIterator(hi); + } else { + serverPanic("Unknown hash encoding"); + } + return hobj; +} + /*----------------------------------------------------------------------------- * Hash type commands *----------------------------------------------------------------------------*/ |