Skip to content

Commit d1fb17c

Browse files
authored
RESTORE with REPLACE option implementation (#1743)
1 parent 42b21ca commit d1fb17c

15 files changed

+144
-29
lines changed

hbase-formatter.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@
255255
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="true"/>
256256
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
257257
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
258-
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
258+
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
259259
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
260260
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
261261
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>

src/main/java/redis/clients/jedis/BinaryClient.java

+4
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,10 @@ public void restore(final byte[] key, final int ttl, final byte[] serializedValu
997997
sendCommand(RESTORE, key, toByteArray(ttl), serializedValue);
998998
}
999999

1000+
public void restoreReplace(final byte[] key, final int ttl, final byte[] serializedValue) {
1001+
sendCommand(RESTORE, key, toByteArray(ttl), serializedValue, Keyword.REPLACE.raw);
1002+
}
1003+
10001004
public void pexpire(final byte[] key, final long milliseconds) {
10011005
sendCommand(PEXPIRE, key, toByteArray(milliseconds));
10021006
}

src/main/java/redis/clients/jedis/BinaryJedis.java

+7
Original file line numberDiff line numberDiff line change
@@ -3441,6 +3441,13 @@ public String restore(final byte[] key, final int ttl, final byte[] serializedVa
34413441
return client.getStatusCodeReply();
34423442
}
34433443

3444+
@Override
3445+
public String restoreReplace(final byte[] key, final int ttl, final byte[] serializedValue) {
3446+
checkIsInMultiOrPipeline();
3447+
client.restoreReplace(key, ttl, serializedValue);
3448+
return client.getStatusCodeReply();
3449+
}
3450+
34443451
/**
34453452
* Set a timeout on the specified key. After the timeout the key will be automatically deleted by
34463453
* the server. A key with an associated timeout is said to be volatile in Redis terminology.

src/main/java/redis/clients/jedis/BinaryShardedJedis.java

+6
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ public String restore(final byte[] key, final int ttl, final byte[] serializedVa
9696
return j.restore(key, ttl, serializedValue);
9797
}
9898

99+
@Override
100+
public String restoreReplace(final byte[] key, final int ttl, final byte[] serializedValue) {
101+
Jedis j = getShard(key);
102+
return j.restoreReplace(key, ttl, serializedValue);
103+
}
104+
99105
@Override
100106
public Long expire(final byte[] key, final int seconds) {
101107
Jedis j = getShard(key);

src/main/java/redis/clients/jedis/Client.java

+7
Original file line numberDiff line numberDiff line change
@@ -839,14 +839,21 @@ public void sentinel(final String... args) {
839839
sentinel(SafeEncoder.encodeMany(args));
840840
}
841841

842+
@Override
842843
public void dump(final String key) {
843844
dump(SafeEncoder.encode(key));
844845
}
845846

847+
@Override
846848
public void restore(final String key, final int ttl, final byte[] serializedValue) {
847849
restore(SafeEncoder.encode(key), ttl, serializedValue);
848850
}
849851

852+
@Override
853+
public void restoreReplace(final String key, final int ttl, final byte[] serializedValue) {
854+
restoreReplace(SafeEncoder.encode(key), ttl, serializedValue);
855+
}
856+
850857
public void pexpire(final String key, final long milliseconds) {
851858
pexpire(SafeEncoder.encode(key), milliseconds);
852859
}

src/main/java/redis/clients/jedis/Jedis.java

+7
Original file line numberDiff line numberDiff line change
@@ -3110,6 +3110,13 @@ public String restore(final String key, final int ttl, final byte[] serializedVa
31103110
return client.getStatusCodeReply();
31113111
}
31123112

3113+
@Override
3114+
public String restoreReplace(final String key, final int ttl, final byte[] serializedValue) {
3115+
checkIsInMultiOrPipeline();
3116+
client.restoreReplace(key, ttl, serializedValue);
3117+
return client.getStatusCodeReply();
3118+
}
3119+
31133120
@Override
31143121
public Long pexpire(final String key, final long milliseconds) {
31153122
checkIsInMultiOrPipeline();

src/main/java/redis/clients/jedis/PipelineBase.java

+16
Original file line numberDiff line numberDiff line change
@@ -1389,11 +1389,13 @@ public Response<Long> bitcount(final byte[] key, final long start, final long en
13891389
return getResponse(BuilderFactory.LONG);
13901390
}
13911391

1392+
@Override
13921393
public Response<byte[]> dump(final String key) {
13931394
getClient(key).dump(key);
13941395
return getResponse(BuilderFactory.BYTE_ARRAY);
13951396
}
13961397

1398+
@Override
13971399
public Response<byte[]> dump(final byte[] key) {
13981400
getClient(key).dump(key);
13991401
return getResponse(BuilderFactory.BYTE_ARRAY);
@@ -1473,16 +1475,30 @@ public Response<Long> pttl(final byte[] key) {
14731475
return getResponse(BuilderFactory.LONG);
14741476
}
14751477

1478+
@Override
14761479
public Response<String> restore(final String key, final int ttl, final byte[] serializedValue) {
14771480
getClient(key).restore(key, ttl, serializedValue);
14781481
return getResponse(BuilderFactory.STRING);
14791482
}
14801483

1484+
@Override
14811485
public Response<String> restore(final byte[] key, final int ttl, final byte[] serializedValue) {
14821486
getClient(key).restore(key, ttl, serializedValue);
14831487
return getResponse(BuilderFactory.STRING);
14841488
}
14851489

1490+
@Override
1491+
public Response<String> restoreReplace(final String key, final int ttl, final byte[] serializedValue) {
1492+
getClient(key).restoreReplace(key, ttl, serializedValue);
1493+
return getResponse(BuilderFactory.STRING);
1494+
}
1495+
1496+
@Override
1497+
public Response<String> restoreReplace(final byte[] key, final int ttl, final byte[] serializedValue) {
1498+
getClient(key).restoreReplace(key, ttl, serializedValue);
1499+
return getResponse(BuilderFactory.STRING);
1500+
}
1501+
14861502
public Response<Double> incrByFloat(final String key, final double increment) {
14871503
getClient(key).incrByFloat(key, increment);
14881504
return getResponse(BuilderFactory.DOUBLE);

src/main/java/redis/clients/jedis/Protocol.java

+31-26
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919

2020
public final class Protocol {
2121

22-
private static final String ASK_RESPONSE = "ASK";
23-
private static final String MOVED_RESPONSE = "MOVED";
24-
private static final String CLUSTERDOWN_RESPONSE = "CLUSTERDOWN";
25-
private static final String BUSY_RESPONSE = "BUSY";
26-
private static final String NOSCRIPT_RESPONSE = "NOSCRIPT";
22+
private static final String ASK_PREFIX = "ASK ";
23+
private static final String MOVED_PREFIX = "MOVED ";
24+
private static final String CLUSTERDOWN_PREFIX = "CLUSTERDOWN ";
25+
private static final String BUSY_PREFIX = "BUSY ";
26+
private static final String NOSCRIPT_PREFIX = "NOSCRIPT ";
2727

2828
public static final String DEFAULT_HOST = "localhost";
2929
public static final int DEFAULT_PORT = 6379;
@@ -113,19 +113,19 @@ private static void processError(final RedisInputStream is) {
113113
String message = is.readLine();
114114
// TODO: I'm not sure if this is the best way to do this.
115115
// Maybe Read only first 5 bytes instead?
116-
if (message.startsWith(MOVED_RESPONSE)) {
116+
if (message.startsWith(MOVED_PREFIX)) {
117117
String[] movedInfo = parseTargetHostAndSlot(message);
118118
throw new JedisMovedDataException(message, new HostAndPort(movedInfo[1],
119119
Integer.parseInt(movedInfo[2])), Integer.parseInt(movedInfo[0]));
120-
} else if (message.startsWith(ASK_RESPONSE)) {
120+
} else if (message.startsWith(ASK_PREFIX)) {
121121
String[] askInfo = parseTargetHostAndSlot(message);
122122
throw new JedisAskDataException(message, new HostAndPort(askInfo[1],
123123
Integer.parseInt(askInfo[2])), Integer.parseInt(askInfo[0]));
124-
} else if (message.startsWith(CLUSTERDOWN_RESPONSE)) {
124+
} else if (message.startsWith(CLUSTERDOWN_PREFIX)) {
125125
throw new JedisClusterException(message);
126-
} else if (message.startsWith(BUSY_RESPONSE)) {
126+
} else if (message.startsWith(BUSY_PREFIX)) {
127127
throw new JedisBusyException(message);
128-
} else if (message.startsWith(NOSCRIPT_RESPONSE) ) {
128+
} else if (message.startsWith(NOSCRIPT_PREFIX) ) {
129129
throw new JedisNoScriptException(message);
130130
}
131131
throw new JedisDataException(message);
@@ -242,21 +242,22 @@ public static final byte[] toByteArray(final double value) {
242242
}
243243

244244
public static enum Command implements ProtocolCommand {
245-
PING, SET, GET, QUIT, EXISTS, DEL, UNLINK, TYPE, FLUSHDB, KEYS, RANDOMKEY, RENAME, RENAMENX, RENAMEX,
246-
DBSIZE, EXPIRE, EXPIREAT, TTL, SELECT, MOVE, FLUSHALL, GETSET, MGET, SETNX, SETEX, MSET, MSETNX,
247-
DECRBY, DECR, INCRBY, INCR, APPEND, SUBSTR, HSET, HGET, HSETNX, HMSET, HMGET, HINCRBY, HEXISTS,
248-
HDEL, HLEN, HKEYS, HVALS, HGETALL, RPUSH, LPUSH, LLEN, LRANGE, LTRIM, LINDEX, LSET, LREM, LPOP, RPOP,
249-
RPOPLPUSH, SADD, SMEMBERS, SREM, SPOP, SMOVE, SCARD, SISMEMBER, SINTER, SINTERSTORE, SUNION,
250-
SUNIONSTORE, SDIFF, SDIFFSTORE, SRANDMEMBER, ZADD, ZRANGE, ZREM, ZINCRBY, ZRANK, ZREVRANK,
251-
ZREVRANGE, ZCARD, ZSCORE, MULTI, DISCARD, EXEC, WATCH, UNWATCH, SORT, BLPOP, BRPOP, AUTH,
252-
SUBSCRIBE, PUBLISH, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBSUB, ZCOUNT, ZRANGEBYSCORE,
253-
ZREVRANGEBYSCORE, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZUNIONSTORE, ZINTERSTORE, ZLEXCOUNT,
254-
ZRANGEBYLEX, ZREVRANGEBYLEX, ZREMRANGEBYLEX, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, SHUTDOWN,
255-
INFO, MONITOR, SLAVEOF, CONFIG, STRLEN, SYNC, LPUSHX, PERSIST, RPUSHX, ECHO, LINSERT, DEBUG, BRPOPLPUSH,
256-
SETBIT, GETBIT, BITPOS, SETRANGE, GETRANGE, EVAL, EVALSHA, SCRIPT, SLOWLOG, OBJECT, BITCOUNT, BITOP,
257-
SENTINEL, DUMP, RESTORE, PEXPIRE, PEXPIREAT, PTTL, INCRBYFLOAT, PSETEX, CLIENT, TIME, MIGRATE, HINCRBYFLOAT,
258-
SCAN, HSCAN, SSCAN, ZSCAN, WAIT, CLUSTER, ASKING, PFADD, PFCOUNT, PFMERGE, READONLY, GEOADD, GEODIST,
259-
GEOHASH, GEOPOS, GEORADIUS, GEORADIUSBYMEMBER, MODULE, BITFIELD, HSTRLEN, TOUCH, SWAPDB;
245+
PING, SET, GET, QUIT, EXISTS, DEL, UNLINK, TYPE, FLUSHDB, KEYS, RANDOMKEY, RENAME, RENAMENX,
246+
RENAMEX, DBSIZE, EXPIRE, EXPIREAT, TTL, SELECT, MOVE, FLUSHALL, GETSET, MGET, SETNX, SETEX,
247+
MSET, MSETNX, DECRBY, DECR, INCRBY, INCR, APPEND, SUBSTR, HSET, HGET, HSETNX, HMSET, HMGET,
248+
HINCRBY, HEXISTS, HDEL, HLEN, HKEYS, HVALS, HGETALL, RPUSH, LPUSH, LLEN, LRANGE, LTRIM, LINDEX,
249+
LSET, LREM, LPOP, RPOP, RPOPLPUSH, SADD, SMEMBERS, SREM, SPOP, SMOVE, SCARD, SISMEMBER, SINTER,
250+
SINTERSTORE, SUNION, SUNIONSTORE, SDIFF, SDIFFSTORE, SRANDMEMBER, ZADD, ZRANGE, ZREM, ZINCRBY,
251+
ZRANK, ZREVRANK, ZREVRANGE, ZCARD, ZSCORE, MULTI, DISCARD, EXEC, WATCH, UNWATCH, SORT, BLPOP,
252+
BRPOP, AUTH, SUBSCRIBE, PUBLISH, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBSUB, ZCOUNT,
253+
ZRANGEBYSCORE, ZREVRANGEBYSCORE, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZUNIONSTORE, ZINTERSTORE,
254+
ZLEXCOUNT, ZRANGEBYLEX, ZREVRANGEBYLEX, ZREMRANGEBYLEX, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE,
255+
SHUTDOWN, INFO, MONITOR, SLAVEOF, CONFIG, STRLEN, SYNC, LPUSHX, PERSIST, RPUSHX, ECHO, LINSERT,
256+
DEBUG, BRPOPLPUSH, SETBIT, GETBIT, BITPOS, SETRANGE, GETRANGE, EVAL, EVALSHA, SCRIPT, SLOWLOG,
257+
OBJECT, BITCOUNT, BITOP, SENTINEL, DUMP, RESTORE, PEXPIRE, PEXPIREAT, PTTL, INCRBYFLOAT,
258+
PSETEX, CLIENT, TIME, MIGRATE, HINCRBYFLOAT, SCAN, HSCAN, SSCAN, ZSCAN, WAIT, CLUSTER, ASKING,
259+
PFADD, PFCOUNT, PFMERGE, READONLY, GEOADD, GEODIST, GEOHASH, GEOPOS, GEORADIUS,
260+
GEORADIUSBYMEMBER, MODULE, BITFIELD, HSTRLEN, TOUCH, SWAPDB;
260261

261262
private final byte[] raw;
262263

@@ -271,7 +272,11 @@ public byte[] getRaw() {
271272
}
272273

273274
public static enum Keyword {
274-
AGGREGATE, ALPHA, ASC, BY, DESC, GET, LIMIT, MESSAGE, NO, NOSORT, PMESSAGE, PSUBSCRIBE, PUNSUBSCRIBE, OK, ONE, QUEUED, SET, STORE, SUBSCRIBE, UNSUBSCRIBE, WEIGHTS, WITHSCORES, RESETSTAT, REWRITE, RESET, FLUSH, EXISTS, LOAD, KILL, LEN, REFCOUNT, ENCODING, IDLETIME, GETNAME, SETNAME, LIST, MATCH, COUNT, PING, PONG, UNLOAD;
275+
AGGREGATE, ALPHA, ASC, BY, DESC, GET, LIMIT, MESSAGE, NO, NOSORT, PMESSAGE, PSUBSCRIBE,
276+
PUNSUBSCRIBE, OK, ONE, QUEUED, SET, STORE, SUBSCRIBE, UNSUBSCRIBE, WEIGHTS, WITHSCORES,
277+
RESETSTAT, REWRITE, RESET, FLUSH, EXISTS, LOAD, KILL, LEN, REFCOUNT, ENCODING, IDLETIME,
278+
GETNAME, SETNAME, LIST, MATCH, COUNT, PING, PONG, UNLOAD, REPLACE;
279+
275280
public final byte[] raw;
276281

277282
Keyword() {

src/main/java/redis/clients/jedis/ShardedJedis.java

+6
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ public String restore(final String key, final int ttl, final byte[] serializedVa
8282
return j.restore(key, ttl, serializedValue);
8383
}
8484

85+
@Override
86+
public String restoreReplace(final String key, final int ttl, final byte[] serializedValue) {
87+
Jedis j = getShard(key);
88+
return j.restoreReplace(key, ttl, serializedValue);
89+
}
90+
8591
@Override
8692
public Long expire(final String key, final int seconds) {
8793
Jedis j = getShard(key);

src/main/java/redis/clients/jedis/commands/BinaryJedisCommands.java

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public interface BinaryJedisCommands {
3131

3232
String restore(byte[] key, int ttl, byte[] serializedValue);
3333

34+
String restoreReplace(byte[] key, int ttl, byte[] serializedValue);
35+
3436
Long expire(byte[] key, int seconds);
3537

3638
Long pexpire(byte[] key, long milliseconds);

src/main/java/redis/clients/jedis/commands/BinaryRedisPipeline.java

+6
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,12 @@ Response<Set<byte[]>> zrevrangeByLex(byte[] key, byte[] max, byte[] min,
247247

248248
Response<Long> pfcount(byte[] key);
249249

250+
Response<byte[]> dump(byte[] key);
251+
252+
Response<String> restore(byte[] key, int ttl, byte[] serializedValue);
253+
254+
Response<String> restoreReplace(byte[] key, int ttl, byte[] serializedValue);
255+
250256
// Geo Commands
251257

252258
Response<Long> geoadd(byte[] key, double longitude, double latitude, byte[] member);

src/main/java/redis/clients/jedis/commands/Commands.java

+6
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,12 @@ void zrevrangeByScoreWithScores(String key, String max, String min,
307307

308308
void bitop(BitOP op, String destKey, String... srcKeys);
309309

310+
void dump(String key);
311+
312+
void restore(String key, int ttl, byte[] serializedValue);
313+
314+
void restoreReplace(String key, int ttl, byte[] serializedValue);
315+
310316
void scan(String cursor, ScanParams params);
311317

312318
void hscan(String key, String cursor, ScanParams params);

src/main/java/redis/clients/jedis/commands/JedisCommands.java

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public interface JedisCommands {
3030

3131
String restore(String key, int ttl, byte[] serializedValue);
3232

33+
String restoreReplace(String key, int ttl, byte[] serializedValue);
34+
3335
Long expire(String key, int seconds);
3436

3537
Long pexpire(String key, long milliseconds);

src/main/java/redis/clients/jedis/commands/RedisPipeline.java

+6
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,12 @@ Response<Set<String>> zrevrangeByLex(String key, String max, String min,
243243

244244
Response<Long> hstrlen(String key, String field);
245245

246+
Response<byte[]> dump(String key);
247+
248+
Response<String> restore(String key, int ttl, byte[] serializedValue);
249+
250+
Response<String> restoreReplace(String key, int ttl, byte[] serializedValue);
251+
246252
// Geo Commands
247253

248254
Response<Long> geoadd(String key, double longitude, double latitude, String member);

src/test/java/redis/clients/jedis/tests/commands/AllKindOfValuesCommandsTest.java

+37-2
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,25 @@
66
import static org.junit.Assert.assertTrue;
77
import static org.junit.Assert.assertNotNull;
88
import static org.junit.Assert.assertNull;
9+
import static org.junit.Assert.fail;
910
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
1011
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START_BINARY;
1112
import static redis.clients.jedis.params.SetParams.setParams;
1213

1314
import java.util.Arrays;
15+
import java.util.HashMap;
1416
import java.util.HashSet;
17+
import java.util.Map;
1518
import java.util.Set;
1619

1720
import org.junit.Test;
21+
import redis.clients.jedis.Jedis;
1822

1923
import redis.clients.jedis.Protocol.Keyword;
2024
import redis.clients.jedis.ScanParams;
2125
import redis.clients.jedis.ScanResult;
2226
import redis.clients.jedis.util.SafeEncoder;
27+
import redis.clients.jedis.exceptions.JedisDataException;
2328

2429
public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
2530
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
@@ -609,10 +614,40 @@ public void echo() {
609614

610615
@Test
611616
public void dumpAndRestore() {
612-
jedis.set("foo1", "bar1");
617+
jedis.set("foo1", "bar");
613618
byte[] sv = jedis.dump("foo1");
614619
jedis.restore("foo2", 0, sv);
615-
assertTrue(jedis.exists("foo2"));
620+
assertEquals("bar", jedis.get("foo2"));
621+
}
622+
623+
@Test
624+
public void restoreReplace() {
625+
// take a separate instance
626+
Jedis jedis2 = new Jedis(hnp.getHost(), 6380, 500);
627+
jedis2.auth("foobared");
628+
jedis2.flushAll();
629+
630+
jedis2.set("foo", "bar");
631+
632+
Map<String, String> map = new HashMap<String, String>();
633+
map.put("a", "A");
634+
map.put("b", "B");
635+
636+
jedis.hset("from", map);
637+
byte[] serialized = jedis.dump("from");
638+
639+
try {
640+
jedis2.restore("foo", 0, serialized);
641+
fail("Simple restore on a existing key should fail");
642+
} catch(JedisDataException e) {
643+
// should be here
644+
}
645+
assertEquals("bar", jedis2.get("foo"));
646+
647+
jedis2.restoreReplace("foo", 0, serialized);
648+
assertEquals(map, jedis2.hgetAll("foo"));
649+
650+
jedis2.close();
616651
}
617652

618653
@Test

0 commit comments

Comments
 (0)