diff --git a/src/ctrip_swap.h b/src/ctrip_swap.h index 4a38d570a7c..e2dafd37360 100644 --- a/src/ctrip_swap.h +++ b/src/ctrip_swap.h @@ -315,7 +315,7 @@ int getKeyRequestsBitField(int dbid, struct redisCommand *cmd, robj **argv, int int getKeyRequestsMemory(int dbid, struct redisCommand *cmd, robj **argv, int argc, struct getKeyRequestsResult *result); -int getKeyRequestsMemory(int dbid, struct redisCommand *cmd, robj **argv, int argc, struct getKeyRequestsResult *result); +int getKeyRequestsMove(int dbid, struct redisCommand *cmd, robj **argv, int argc, struct getKeyRequestsResult *result); #define GET_KEYREQUESTS_RESULT_INIT { {{0}}, NULL, NULL, 0, MAX_KEYREQUESTS_BUFFER} diff --git a/src/ctrip_swap_cmd.c b/src/ctrip_swap_cmd.c index 96ca1c27c44..e1b35e22454 100644 --- a/src/ctrip_swap_cmd.c +++ b/src/ctrip_swap_cmd.c @@ -1308,6 +1308,13 @@ int getKeyRequestsMemory(int dbid, struct redisCommand *cmd, robj **argv, } } +int getKeyRequestsMove(int dbid, struct redisCommand *cmd, robj **argv, + int argc, struct getKeyRequestsResult *result) { + UNUSED(argc); + getKeyRequestsSingleKey(result,argv[1],cmd->intention,cmd->intention_flags,cmd->flags | CMD_SWAP_DATATYPE_KEYSPACE,dbid); + return 0; +} + #ifdef REDIS_TEST void rewriteResetClientCommandCString(client *c, int argc, ...) { diff --git a/src/db.c b/src/db.c index 67ba7195bb9..c2ae051850c 100644 --- a/src/db.c +++ b/src/db.c @@ -1318,12 +1318,20 @@ void moveCommand(client *c) { } expire = getExpire(c->db,c->argv[1]); - /* Return zero if the key already exists in the target DB */ - if (lookupKeyWrite(dst,c->argv[1]) != NULL) { + /* Return zero if the key or meta already exist in the target DB */ + if (lookupKeyWrite(dst,c->argv[1]) != NULL || lookupMeta(dst, c->argv[1]) != NULL) { addReply(c,shared.czero); return; } + dbAdd(dst,c->argv[1],o); + + objectMeta *om = lookupMeta(src, c->argv[1]); + if (om != NULL) { + objectMeta *dst_om = dupObjectMeta(om); + dbAddMeta(dst,c->argv[1],dst_om); + } + if (expire != -1) setExpire(c,dst,c->argv[1],expire); incrRefCount(o); diff --git a/src/server.c b/src/server.c index 6422e21f292..d80039b3d79 100644 --- a/src/server.c +++ b/src/server.c @@ -660,8 +660,8 @@ struct redisCommand redisCommandTable[] = { 0,NULL,getKeyRequestsGlobal,SWAP_NOP,0,0,0,0,0,0,0}, {"move",moveCommand,3, - "write fast @keyspace", - 0,NULL,NULL,SWAP_NOP,0,1,1,1,0,0,0}, + "write fast @keyspace @swap_keyspace", + 0,NULL,getKeyRequestsMove,SWAP_IN,SWAP_IN_DEL,1,1,1,0,0,0}, {"copy",copyCommand,-3, "write use-memory @keyspace @swap_keyspace", diff --git a/tests/swap/unit/bitmap.tcl b/tests/swap/unit/bitmap.tcl index 75ed0fdd891..4acced46c8b 100644 --- a/tests/swap/unit/bitmap.tcl +++ b/tests/swap/unit/bitmap.tcl @@ -749,6 +749,26 @@ start_server { r flushdb } + test {bitmap move} { + r flushdb + build_cold_data mybitmap1 + build_pure_hot_data mybitmap2 + + r move mybitmap1 10 + r move mybitmap2 10 + assert_equal [r dbsize] 0 + + r select 10 + assert_equal [r dbsize] 2 + assert [bitmap_object_is_pure_hot r mybitmap1] + assert [bitmap_object_is_pure_hot r mybitmap2] + + check_mybitmap_is_right mybitmap1 $notextend + check_mybitmap_is_right mybitmap2 $notextend + + r flushdb + } + }