Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RESTORE with REPLACE option implementation #1743

Merged
merged 1 commit into from
Jun 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion hbase-formatter.xml
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/redis/clients/jedis/BinaryClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,10 @@ public void restore(final byte[] key, final int ttl, final byte[] serializedValu
sendCommand(RESTORE, key, toByteArray(ttl), serializedValue);
}

public void restoreReplace(final byte[] key, final int ttl, final byte[] serializedValue) {
sendCommand(RESTORE, key, toByteArray(ttl), serializedValue, Keyword.REPLACE.raw);
}

public void pexpire(final byte[] key, final long milliseconds) {
sendCommand(PEXPIRE, key, toByteArray(milliseconds));
}
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/redis/clients/jedis/BinaryJedis.java
Original file line number Diff line number Diff line change
Expand Up @@ -3441,6 +3441,13 @@ public String restore(final byte[] key, final int ttl, final byte[] serializedVa
return client.getStatusCodeReply();
}

@Override
public String restoreReplace(final byte[] key, final int ttl, final byte[] serializedValue) {
checkIsInMultiOrPipeline();
client.restoreReplace(key, ttl, serializedValue);
return client.getStatusCodeReply();
}

/**
* Set a timeout on the specified key. After the timeout the key will be automatically deleted by
* the server. A key with an associated timeout is said to be volatile in Redis terminology.
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/redis/clients/jedis/BinaryShardedJedis.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ public String restore(final byte[] key, final int ttl, final byte[] serializedVa
return j.restore(key, ttl, serializedValue);
}

@Override
public String restoreReplace(final byte[] key, final int ttl, final byte[] serializedValue) {
Jedis j = getShard(key);
return j.restoreReplace(key, ttl, serializedValue);
}

@Override
public Long expire(final byte[] key, final int seconds) {
Jedis j = getShard(key);
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/redis/clients/jedis/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -839,14 +839,21 @@ public void sentinel(final String... args) {
sentinel(SafeEncoder.encodeMany(args));
}

@Override
public void dump(final String key) {
dump(SafeEncoder.encode(key));
}

@Override
public void restore(final String key, final int ttl, final byte[] serializedValue) {
restore(SafeEncoder.encode(key), ttl, serializedValue);
}

@Override
public void restoreReplace(final String key, final int ttl, final byte[] serializedValue) {
restoreReplace(SafeEncoder.encode(key), ttl, serializedValue);
}

public void pexpire(final String key, final long milliseconds) {
pexpire(SafeEncoder.encode(key), milliseconds);
}
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/redis/clients/jedis/Jedis.java
Original file line number Diff line number Diff line change
Expand Up @@ -3110,6 +3110,13 @@ public String restore(final String key, final int ttl, final byte[] serializedVa
return client.getStatusCodeReply();
}

@Override
public String restoreReplace(final String key, final int ttl, final byte[] serializedValue) {
checkIsInMultiOrPipeline();
client.restoreReplace(key, ttl, serializedValue);
return client.getStatusCodeReply();
}

@Override
public Long pexpire(final String key, final long milliseconds) {
checkIsInMultiOrPipeline();
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/redis/clients/jedis/PipelineBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -1389,11 +1389,13 @@ public Response<Long> bitcount(final byte[] key, final long start, final long en
return getResponse(BuilderFactory.LONG);
}

@Override
public Response<byte[]> dump(final String key) {
getClient(key).dump(key);
return getResponse(BuilderFactory.BYTE_ARRAY);
}

@Override
public Response<byte[]> dump(final byte[] key) {
getClient(key).dump(key);
return getResponse(BuilderFactory.BYTE_ARRAY);
Expand Down Expand Up @@ -1473,16 +1475,30 @@ public Response<Long> pttl(final byte[] key) {
return getResponse(BuilderFactory.LONG);
}

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

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

@Override
public Response<String> restoreReplace(final String key, final int ttl, final byte[] serializedValue) {
getClient(key).restoreReplace(key, ttl, serializedValue);
return getResponse(BuilderFactory.STRING);
}

@Override
public Response<String> restoreReplace(final byte[] key, final int ttl, final byte[] serializedValue) {
getClient(key).restoreReplace(key, ttl, serializedValue);
return getResponse(BuilderFactory.STRING);
}

public Response<Double> incrByFloat(final String key, final double increment) {
getClient(key).incrByFloat(key, increment);
return getResponse(BuilderFactory.DOUBLE);
Expand Down
57 changes: 31 additions & 26 deletions src/main/java/redis/clients/jedis/Protocol.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@

public final class Protocol {

private static final String ASK_RESPONSE = "ASK";
private static final String MOVED_RESPONSE = "MOVED";
private static final String CLUSTERDOWN_RESPONSE = "CLUSTERDOWN";
private static final String BUSY_RESPONSE = "BUSY";
private static final String NOSCRIPT_RESPONSE = "NOSCRIPT";
private static final String ASK_PREFIX = "ASK ";
private static final String MOVED_PREFIX = "MOVED ";
private static final String CLUSTERDOWN_PREFIX = "CLUSTERDOWN ";
private static final String BUSY_PREFIX = "BUSY ";
private static final String NOSCRIPT_PREFIX = "NOSCRIPT ";

public static final String DEFAULT_HOST = "localhost";
public static final int DEFAULT_PORT = 6379;
Expand Down Expand Up @@ -113,19 +113,19 @@ private static void processError(final RedisInputStream is) {
String message = is.readLine();
// TODO: I'm not sure if this is the best way to do this.
// Maybe Read only first 5 bytes instead?
if (message.startsWith(MOVED_RESPONSE)) {
if (message.startsWith(MOVED_PREFIX)) {
String[] movedInfo = parseTargetHostAndSlot(message);
throw new JedisMovedDataException(message, new HostAndPort(movedInfo[1],
Integer.parseInt(movedInfo[2])), Integer.parseInt(movedInfo[0]));
} else if (message.startsWith(ASK_RESPONSE)) {
} else if (message.startsWith(ASK_PREFIX)) {
String[] askInfo = parseTargetHostAndSlot(message);
throw new JedisAskDataException(message, new HostAndPort(askInfo[1],
Integer.parseInt(askInfo[2])), Integer.parseInt(askInfo[0]));
} else if (message.startsWith(CLUSTERDOWN_RESPONSE)) {
} else if (message.startsWith(CLUSTERDOWN_PREFIX)) {
throw new JedisClusterException(message);
} else if (message.startsWith(BUSY_RESPONSE)) {
} else if (message.startsWith(BUSY_PREFIX)) {
throw new JedisBusyException(message);
} else if (message.startsWith(NOSCRIPT_RESPONSE) ) {
} else if (message.startsWith(NOSCRIPT_PREFIX) ) {
throw new JedisNoScriptException(message);
}
throw new JedisDataException(message);
Expand Down Expand Up @@ -242,21 +242,22 @@ public static final byte[] toByteArray(final double value) {
}

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

private final byte[] raw;

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

public static enum Keyword {
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;
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, REPLACE;

public final byte[] raw;

Keyword() {
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/redis/clients/jedis/ShardedJedis.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ public String restore(final String key, final int ttl, final byte[] serializedVa
return j.restore(key, ttl, serializedValue);
}

@Override
public String restoreReplace(final String key, final int ttl, final byte[] serializedValue) {
Jedis j = getShard(key);
return j.restoreReplace(key, ttl, serializedValue);
}

@Override
public Long expire(final String key, final int seconds) {
Jedis j = getShard(key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public interface BinaryJedisCommands {

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

String restoreReplace(byte[] key, int ttl, byte[] serializedValue);

Long expire(byte[] key, int seconds);

Long pexpire(byte[] key, long milliseconds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,12 @@ Response<Set<byte[]>> zrevrangeByLex(byte[] key, byte[] max, byte[] min,

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

Response<byte[]> dump(byte[] key);

Response<String> restore(byte[] key, int ttl, byte[] serializedValue);

Response<String> restoreReplace(byte[] key, int ttl, byte[] serializedValue);

// Geo Commands

Response<Long> geoadd(byte[] key, double longitude, double latitude, byte[] member);
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/redis/clients/jedis/commands/Commands.java
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,12 @@ void zrevrangeByScoreWithScores(String key, String max, String min,

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

void dump(String key);

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

void restoreReplace(String key, int ttl, byte[] serializedValue);

void scan(String cursor, ScanParams params);

void hscan(String key, String cursor, ScanParams params);
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/redis/clients/jedis/commands/JedisCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public interface JedisCommands {

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

String restoreReplace(String key, int ttl, byte[] serializedValue);

Long expire(String key, int seconds);

Long pexpire(String key, long milliseconds);
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/redis/clients/jedis/commands/RedisPipeline.java
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,12 @@ Response<Set<String>> zrevrangeByLex(String key, String max, String min,

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

Response<byte[]> dump(String key);

Response<String> restore(String key, int ttl, byte[] serializedValue);

Response<String> restoreReplace(String key, int ttl, byte[] serializedValue);

// Geo Commands

Response<Long> geoadd(String key, double longitude, double latitude, String member);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START_BINARY;
import static redis.clients.jedis.params.SetParams.setParams;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.junit.Test;
import redis.clients.jedis.Jedis;

import redis.clients.jedis.Protocol.Keyword;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.util.SafeEncoder;
import redis.clients.jedis.exceptions.JedisDataException;

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

@Test
public void dumpAndRestore() {
jedis.set("foo1", "bar1");
jedis.set("foo1", "bar");
byte[] sv = jedis.dump("foo1");
jedis.restore("foo2", 0, sv);
assertTrue(jedis.exists("foo2"));
assertEquals("bar", jedis.get("foo2"));
}

@Test
public void restoreReplace() {
// take a separate instance
Jedis jedis2 = new Jedis(hnp.getHost(), 6380, 500);
jedis2.auth("foobared");
jedis2.flushAll();

jedis2.set("foo", "bar");

Map<String, String> map = new HashMap<String, String>();
map.put("a", "A");
map.put("b", "B");

jedis.hset("from", map);
byte[] serialized = jedis.dump("from");

try {
jedis2.restore("foo", 0, serialized);
fail("Simple restore on a existing key should fail");
} catch(JedisDataException e) {
// should be here
}
assertEquals("bar", jedis2.get("foo"));

jedis2.restoreReplace("foo", 0, serialized);
assertEquals(map, jedis2.hgetAll("foo"));

jedis2.close();
}

@Test
Expand Down