summaryrefslogtreecommitdiff
path: root/src/t_hash.c
diff options
context:
space:
mode:
authorswamp0407 <swamp0407@gmail.com>2020-11-17 19:03:05 +0900
committerGitHub <noreply@github.com>2020-11-17 12:03:05 +0200
commitea7cf737a1ff65524994ce6731eb9320891aa946 (patch)
treef6e491ee1f41765e916597c1d7719717da20353e /src/t_hash.c
parent9812e88959a37ed4aa95bb4d3fb55c56dc49a768 (diff)
downloadredis-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.c54
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
*----------------------------------------------------------------------------*/