Merge branch 'master' into support-sorted-set-with-lex
Conflicts: src/main/java/redis/clients/jedis/BinaryShardedJedis.java src/main/java/redis/clients/jedis/Jedis.java src/main/java/redis/clients/jedis/Protocol.java src/test/java/redis/clients/jedis/tests/commands/SortedSetCommandsTest.java
This commit is contained in:
53
Makefile
53
Makefile
@@ -153,6 +153,42 @@ cluster-enabled yes
|
|||||||
cluster-config-file /tmp/redis_cluster_node3.conf
|
cluster-config-file /tmp/redis_cluster_node3.conf
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define REDIS_CLUSTER_NODE4_CONF
|
||||||
|
daemonize yes
|
||||||
|
port 7382
|
||||||
|
cluster-node-timeout 50
|
||||||
|
pidfile /tmp/redis_cluster_node4.pid
|
||||||
|
logfile /tmp/redis_cluster_node4.log
|
||||||
|
save ""
|
||||||
|
appendonly no
|
||||||
|
cluster-enabled yes
|
||||||
|
cluster-config-file /tmp/redis_cluster_node4.conf
|
||||||
|
endef
|
||||||
|
|
||||||
|
define REDIS_CLUSTER_NODE5_CONF
|
||||||
|
daemonize yes
|
||||||
|
port 7383
|
||||||
|
cluster-node-timeout 5000
|
||||||
|
pidfile /tmp/redis_cluster_node5.pid
|
||||||
|
logfile /tmp/redis_cluster_node5.log
|
||||||
|
save ""
|
||||||
|
appendonly no
|
||||||
|
cluster-enabled yes
|
||||||
|
cluster-config-file /tmp/redis_cluster_node5.conf
|
||||||
|
endef
|
||||||
|
|
||||||
|
define REDIS_CLUSTER_NODE6_CONF
|
||||||
|
daemonize yes
|
||||||
|
port 7384
|
||||||
|
cluster-node-timeout 5000
|
||||||
|
pidfile /tmp/redis_cluster_node6.pid
|
||||||
|
logfile /tmp/redis_cluster_node6.log
|
||||||
|
save ""
|
||||||
|
appendonly no
|
||||||
|
cluster-enabled yes
|
||||||
|
cluster-config-file /tmp/redis_cluster_node6.conf
|
||||||
|
endef
|
||||||
|
|
||||||
export REDIS1_CONF
|
export REDIS1_CONF
|
||||||
export REDIS2_CONF
|
export REDIS2_CONF
|
||||||
export REDIS3_CONF
|
export REDIS3_CONF
|
||||||
@@ -166,6 +202,9 @@ export REDIS_SENTINEL3
|
|||||||
export REDIS_CLUSTER_NODE1_CONF
|
export REDIS_CLUSTER_NODE1_CONF
|
||||||
export REDIS_CLUSTER_NODE2_CONF
|
export REDIS_CLUSTER_NODE2_CONF
|
||||||
export REDIS_CLUSTER_NODE3_CONF
|
export REDIS_CLUSTER_NODE3_CONF
|
||||||
|
export REDIS_CLUSTER_NODE4_CONF
|
||||||
|
export REDIS_CLUSTER_NODE5_CONF
|
||||||
|
export REDIS_CLUSTER_NODE6_CONF
|
||||||
|
|
||||||
start: cleanup
|
start: cleanup
|
||||||
echo "$$REDIS1_CONF" | redis-server -
|
echo "$$REDIS1_CONF" | redis-server -
|
||||||
@@ -183,6 +222,9 @@ start: cleanup
|
|||||||
echo "$$REDIS_CLUSTER_NODE1_CONF" | redis-server -
|
echo "$$REDIS_CLUSTER_NODE1_CONF" | redis-server -
|
||||||
echo "$$REDIS_CLUSTER_NODE2_CONF" | redis-server -
|
echo "$$REDIS_CLUSTER_NODE2_CONF" | redis-server -
|
||||||
echo "$$REDIS_CLUSTER_NODE3_CONF" | redis-server -
|
echo "$$REDIS_CLUSTER_NODE3_CONF" | redis-server -
|
||||||
|
echo "$$REDIS_CLUSTER_NODE4_CONF" | redis-server -
|
||||||
|
echo "$$REDIS_CLUSTER_NODE5_CONF" | redis-server -
|
||||||
|
echo "$$REDIS_CLUSTER_NODE6_CONF" | redis-server -
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
- rm -vf /tmp/redis_cluster_node*.conf 2>/dev/null
|
- rm -vf /tmp/redis_cluster_node*.conf 2>/dev/null
|
||||||
@@ -202,12 +244,18 @@ stop:
|
|||||||
kill `cat /tmp/redis_cluster_node1.pid` || true
|
kill `cat /tmp/redis_cluster_node1.pid` || true
|
||||||
kill `cat /tmp/redis_cluster_node2.pid` || true
|
kill `cat /tmp/redis_cluster_node2.pid` || true
|
||||||
kill `cat /tmp/redis_cluster_node3.pid` || true
|
kill `cat /tmp/redis_cluster_node3.pid` || true
|
||||||
|
kill `cat /tmp/redis_cluster_node4.pid` || true
|
||||||
|
kill `cat /tmp/redis_cluster_node5.pid` || true
|
||||||
|
kill `cat /tmp/redis_cluster_node6.pid` || true
|
||||||
rm -f /tmp/sentinel1.conf
|
rm -f /tmp/sentinel1.conf
|
||||||
rm -f /tmp/sentinel2.conf
|
rm -f /tmp/sentinel2.conf
|
||||||
rm -f /tmp/sentinel3.conf
|
rm -f /tmp/sentinel3.conf
|
||||||
rm -f /tmp/redis_cluster_node1.conf
|
rm -f /tmp/redis_cluster_node1.conf
|
||||||
rm -f /tmp/redis_cluster_node2.conf
|
rm -f /tmp/redis_cluster_node2.conf
|
||||||
rm -f /tmp/redis_cluster_node3.conf
|
rm -f /tmp/redis_cluster_node3.conf
|
||||||
|
rm -f /tmp/redis_cluster_node4.conf
|
||||||
|
rm -f /tmp/redis_cluster_node5.conf
|
||||||
|
rm -f /tmp/redis_cluster_node6.conf
|
||||||
|
|
||||||
test:
|
test:
|
||||||
make start
|
make start
|
||||||
@@ -215,6 +263,11 @@ test:
|
|||||||
mvn -Dtest=${TEST} clean compile test
|
mvn -Dtest=${TEST} clean compile test
|
||||||
make stop
|
make stop
|
||||||
|
|
||||||
|
package:
|
||||||
|
make start
|
||||||
|
mvn clean package
|
||||||
|
make stop
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
make start
|
make start
|
||||||
mvn clean deploy
|
mvn clean deploy
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ Redis cluster [specification](http://redis.io/topics/cluster-spec) (still under
|
|||||||
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
|
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
|
||||||
//Jedis Cluster will attempt to discover cluster nodes automatically
|
//Jedis Cluster will attempt to discover cluster nodes automatically
|
||||||
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7379));
|
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7379));
|
||||||
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
JedisCluster jc = new JedisCluster(jedisClusterNodes);
|
||||||
jc.set("foo", "bar");
|
jc.set("foo", "bar");
|
||||||
String value = jc.get("foo");
|
String value = jc.get("foo");
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ apply plugin: 'maven'
|
|||||||
apply plugin: 'eclipse'
|
apply plugin: 'eclipse'
|
||||||
|
|
||||||
group = 'com.googlecode.jedis'
|
group = 'com.googlecode.jedis'
|
||||||
archiveBaseName = 'jedis'
|
archivesBaseName = 'jedis'
|
||||||
version = '1.5.0'
|
version = '1.5.0'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
4
pom.xml
4
pom.xml
@@ -9,7 +9,7 @@
|
|||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<groupId>redis.clients</groupId>
|
<groupId>redis.clients</groupId>
|
||||||
<artifactId>jedis</artifactId>
|
<artifactId>jedis</artifactId>
|
||||||
<version>2.5.0-SNAPSHOT</version>
|
<version>2.5.3-SNAPSHOT</version>
|
||||||
<name>Jedis</name>
|
<name>Jedis</name>
|
||||||
<description>Jedis is a blazingly small and sane Redis java client.</description>
|
<description>Jedis is a blazingly small and sane Redis java client.</description>
|
||||||
<url>https://github.com/xetorthio/jedis</url>
|
<url>https://github.com/xetorthio/jedis</url>
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<redis-hosts>localhost:6379,localhost:6380,localhost:6381,localhost:6382,localhost:6383,localhost:6384,localhost:6385</redis-hosts>
|
<redis-hosts>localhost:6379,localhost:6380,localhost:6381,localhost:6382,localhost:6383,localhost:6384,localhost:6385</redis-hosts>
|
||||||
<sentinel-hosts>localhost:26379,localhost:26380,localhost:26381</sentinel-hosts>
|
<sentinel-hosts>localhost:26379,localhost:26380,localhost:26381</sentinel-hosts>
|
||||||
<cluster-hosts>localhost:7379,localhost:7380,localhost:7381</cluster-hosts>
|
<cluster-hosts>localhost:7379,localhost:7380,localhost:7381,localhost:7382,localhost:7383,localhost:7384,localhost:7385</cluster-hosts>
|
||||||
<github.global.server>github</github.global.server>
|
<github.global.server>github</github.global.server>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package redis.clients.jedis;
|
package redis.clients.jedis;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pipelined responses for all of the low level, non key related commands
|
* Pipelined responses for all of the low level, non key related commands
|
||||||
*/
|
*/
|
||||||
@@ -25,6 +27,8 @@ public interface BasicRedisPipeline {
|
|||||||
|
|
||||||
Response<String> info();
|
Response<String> info();
|
||||||
|
|
||||||
|
Response<List<String>> time();
|
||||||
|
|
||||||
Response<Long> dbSize();
|
Response<Long> dbSize();
|
||||||
|
|
||||||
Response<String> shutdown();
|
Response<String> shutdown();
|
||||||
|
|||||||
@@ -1,17 +1,8 @@
|
|||||||
package redis.clients.jedis;
|
package redis.clients.jedis;
|
||||||
|
|
||||||
import static redis.clients.jedis.Protocol.toByteArray;
|
import redis.clients.jedis.Protocol.Command;
|
||||||
import static redis.clients.jedis.Protocol.Command.*;
|
import redis.clients.jedis.Protocol.Keyword;
|
||||||
import static redis.clients.jedis.Protocol.Keyword.ENCODING;
|
import redis.clients.util.SafeEncoder;
|
||||||
import static redis.clients.jedis.Protocol.Keyword.IDLETIME;
|
|
||||||
import static redis.clients.jedis.Protocol.Keyword.LEN;
|
|
||||||
import static redis.clients.jedis.Protocol.Keyword.LIMIT;
|
|
||||||
import static redis.clients.jedis.Protocol.Keyword.NO;
|
|
||||||
import static redis.clients.jedis.Protocol.Keyword.ONE;
|
|
||||||
import static redis.clients.jedis.Protocol.Keyword.REFCOUNT;
|
|
||||||
import static redis.clients.jedis.Protocol.Keyword.RESET;
|
|
||||||
import static redis.clients.jedis.Protocol.Keyword.STORE;
|
|
||||||
import static redis.clients.jedis.Protocol.Keyword.WITHSCORES;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -19,9 +10,14 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import redis.clients.jedis.Protocol.Command;
|
import static redis.clients.jedis.Protocol.Command.*;
|
||||||
import redis.clients.jedis.Protocol.Keyword;
|
import static redis.clients.jedis.Protocol.Command.EXISTS;
|
||||||
import redis.clients.util.SafeEncoder;
|
import static redis.clients.jedis.Protocol.Command.PSUBSCRIBE;
|
||||||
|
import static redis.clients.jedis.Protocol.Command.PUNSUBSCRIBE;
|
||||||
|
import static redis.clients.jedis.Protocol.Command.SUBSCRIBE;
|
||||||
|
import static redis.clients.jedis.Protocol.Command.UNSUBSCRIBE;
|
||||||
|
import static redis.clients.jedis.Protocol.Keyword.*;
|
||||||
|
import static redis.clients.jedis.Protocol.toByteArray;
|
||||||
|
|
||||||
public class BinaryClient extends Connection {
|
public class BinaryClient extends Connection {
|
||||||
public enum LIST_POSITION {
|
public enum LIST_POSITION {
|
||||||
@@ -204,6 +200,10 @@ public class BinaryClient extends Connection {
|
|||||||
sendCommand(INCRBY, key, toByteArray(integer));
|
sendCommand(INCRBY, key, toByteArray(integer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void incrByFloat(final byte[] key, final double value) {
|
||||||
|
sendCommand(INCRBYFLOAT, key, toByteArray(value));
|
||||||
|
}
|
||||||
|
|
||||||
public void incr(final byte[] key) {
|
public void incr(final byte[] key) {
|
||||||
sendCommand(INCR, key);
|
sendCommand(INCR, key);
|
||||||
}
|
}
|
||||||
@@ -950,6 +950,14 @@ public class BinaryClient extends Connection {
|
|||||||
sendCommand(GETBIT, key, toByteArray(offset));
|
sendCommand(GETBIT, key, toByteArray(offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void bitpos(final byte[] key, final boolean value, final BitPosParams params) {
|
||||||
|
final List<byte[]> args = new ArrayList<byte[]>();
|
||||||
|
args.add(key);
|
||||||
|
args.add(toByteArray(value));
|
||||||
|
args.addAll(params.getParams());
|
||||||
|
sendCommand(BITPOS, args.toArray(new byte[args.size()][]));
|
||||||
|
}
|
||||||
|
|
||||||
public void setrange(byte[] key, long offset, byte[] value) {
|
public void setrange(byte[] key, long offset, byte[] value) {
|
||||||
sendCommand(SETRANGE, key, toByteArray(offset), value);
|
sendCommand(SETRANGE, key, toByteArray(offset), value);
|
||||||
}
|
}
|
||||||
@@ -975,9 +983,6 @@ public class BinaryClient extends Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void resetState() {
|
public void resetState() {
|
||||||
if (isInMulti())
|
|
||||||
discard();
|
|
||||||
|
|
||||||
if (isInWatch())
|
if (isInWatch())
|
||||||
unwatch();
|
unwatch();
|
||||||
}
|
}
|
||||||
@@ -1111,7 +1116,7 @@ public class BinaryClient extends Connection {
|
|||||||
sendCommand(RESTORE, key, toByteArray(ttl), serializedValue);
|
sendCommand(RESTORE, key, toByteArray(ttl), serializedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pexpire(final byte[] key, final int milliseconds) {
|
public void pexpire(final byte[] key, final long milliseconds) {
|
||||||
sendCommand(PEXPIRE, key, toByteArray(milliseconds));
|
sendCommand(PEXPIRE, key, toByteArray(milliseconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1123,10 +1128,6 @@ public class BinaryClient extends Connection {
|
|||||||
sendCommand(PTTL, key);
|
sendCommand(PTTL, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void incrByFloat(final byte[] key, final double increment) {
|
|
||||||
sendCommand(INCRBYFLOAT, key, toByteArray(increment));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void psetex(final byte[] key, final int milliseconds,
|
public void psetex(final byte[] key, final int milliseconds,
|
||||||
final byte[] value) {
|
final byte[] value) {
|
||||||
sendCommand(PSETEX, key, toByteArray(milliseconds), value);
|
sendCommand(PSETEX, key, toByteArray(milliseconds), value);
|
||||||
@@ -1176,61 +1177,6 @@ public class BinaryClient extends Connection {
|
|||||||
sendCommand(HINCRBYFLOAT, key, field, toByteArray(increment));
|
sendCommand(HINCRBYFLOAT, key, field, toByteArray(increment));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public void scan(int cursor, final ScanParams params) {
|
|
||||||
final List<byte[]> args = new ArrayList<byte[]>();
|
|
||||||
args.add(toByteArray(cursor));
|
|
||||||
args.addAll(params.getParams());
|
|
||||||
sendCommand(SCAN, args.toArray(new byte[args.size()][]));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public void hscan(final byte[] key, int cursor, final ScanParams params) {
|
|
||||||
final List<byte[]> args = new ArrayList<byte[]>();
|
|
||||||
args.add(key);
|
|
||||||
args.add(toByteArray(cursor));
|
|
||||||
args.addAll(params.getParams());
|
|
||||||
sendCommand(HSCAN, args.toArray(new byte[args.size()][]));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public void sscan(final byte[] key, int cursor, final ScanParams params) {
|
|
||||||
final List<byte[]> args = new ArrayList<byte[]>();
|
|
||||||
args.add(key);
|
|
||||||
args.add(toByteArray(cursor));
|
|
||||||
args.addAll(params.getParams());
|
|
||||||
sendCommand(SSCAN, args.toArray(new byte[args.size()][]));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public void zscan(final byte[] key, int cursor, final ScanParams params) {
|
|
||||||
final List<byte[]> args = new ArrayList<byte[]>();
|
|
||||||
args.add(key);
|
|
||||||
args.add(toByteArray(cursor));
|
|
||||||
args.addAll(params.getParams());
|
|
||||||
sendCommand(ZSCAN, args.toArray(new byte[args.size()][]));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void scan(final byte[] cursor, final ScanParams params) {
|
public void scan(final byte[] cursor, final ScanParams params) {
|
||||||
final List<byte[]> args = new ArrayList<byte[]>();
|
final List<byte[]> args = new ArrayList<byte[]>();
|
||||||
args.add(cursor);
|
args.add(cursor);
|
||||||
@@ -1273,4 +1219,20 @@ public class BinaryClient extends Connection {
|
|||||||
public void asking() {
|
public void asking() {
|
||||||
sendCommand(Command.ASKING);
|
sendCommand(Command.ASKING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void pfadd(final byte[] key, final byte[]... elements) {
|
||||||
|
sendCommand(PFADD, joinParameters(key, elements));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pfcount(final byte[] key) {
|
||||||
|
sendCommand(PFCOUNT, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pfcount(final byte[]...keys) {
|
||||||
|
sendCommand(PFCOUNT, keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pfmerge(final byte[] destkey, final byte[]... sourcekeys) {
|
||||||
|
sendCommand(PFMERGE, joinParameters(destkey, sourcekeys));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import static redis.clients.jedis.Protocol.toByteArray;
|
|||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.AbstractMap;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -22,6 +23,8 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
|
|||||||
MultiKeyBinaryCommands, AdvancedBinaryJedisCommands,
|
MultiKeyBinaryCommands, AdvancedBinaryJedisCommands,
|
||||||
BinaryScriptingCommands, Closeable {
|
BinaryScriptingCommands, Closeable {
|
||||||
protected Client client = null;
|
protected Client client = null;
|
||||||
|
protected Transaction transaction = null;
|
||||||
|
protected Pipeline pipeline = null;
|
||||||
|
|
||||||
public BinaryJedis(final String host) {
|
public BinaryJedis(final String host) {
|
||||||
URI uri = URI.create(host);
|
URI uri = URI.create(host);
|
||||||
@@ -633,6 +636,37 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
|
|||||||
return client.getIntegerReply();
|
return client.getIntegerReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INCRBYFLOAT work just like {@link #incrBy(byte[]) INCRBY} but increments
|
||||||
|
* by floats instead of integers.
|
||||||
|
* <p>
|
||||||
|
* INCRBYFLOAT commands are limited to double precision floating point
|
||||||
|
* values.
|
||||||
|
* <p>
|
||||||
|
* Note: this is actually a string operation, that is, in Redis there are
|
||||||
|
* not "double" types. Simply the string stored at the key is parsed as a
|
||||||
|
* base double precision floating point value, incremented, and then
|
||||||
|
* converted back as a string. There is no DECRYBYFLOAT but providing a
|
||||||
|
* negative value will work as expected.
|
||||||
|
* <p>
|
||||||
|
* Time complexity: O(1)
|
||||||
|
*
|
||||||
|
* @see #incr(byte[])
|
||||||
|
* @see #decr(byte[])
|
||||||
|
* @see #decrBy(byte[], long)
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param integer
|
||||||
|
* @return Integer reply, this commands will reply with the new value of key
|
||||||
|
* after the increment.
|
||||||
|
*/
|
||||||
|
public Double incrByFloat(final byte[] key, final double integer) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.incrByFloat(key, integer);
|
||||||
|
String dval = client.getBulkReply();
|
||||||
|
return (dval != null ? new Double(dval) : null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increment the number stored at key by one. If the key does not exist or
|
* Increment the number stored at key by one. If the key does not exist or
|
||||||
* contains a value of a wrong type, set the key to the value of "0" before
|
* contains a value of a wrong type, set the key to the value of "0" before
|
||||||
@@ -825,6 +859,33 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
|
|||||||
return client.getIntegerReply();
|
return client.getIntegerReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the number stored at field in the hash at key by a double
|
||||||
|
* precision floating point value. If key does not exist, a new key holding
|
||||||
|
* a hash is created. If field does not exist or holds a string, the value
|
||||||
|
* is set to 0 before applying the operation. Since the value argument is
|
||||||
|
* signed you can use this command to perform both increments and
|
||||||
|
* decrements.
|
||||||
|
* <p>
|
||||||
|
* The range of values supported by HINCRBYFLOAT is limited to double
|
||||||
|
* precision floating point values.
|
||||||
|
* <p>
|
||||||
|
* <b>Time complexity:</b> O(1)
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param field
|
||||||
|
* @param value
|
||||||
|
* @return Double precision floating point reply The new value at field
|
||||||
|
* after the increment operation.
|
||||||
|
*/
|
||||||
|
public Double hincrByFloat(final byte[] key, final byte[] field,
|
||||||
|
final double value) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.hincrByFloat(key, field, value);
|
||||||
|
final String dval = client.getBulkReply();
|
||||||
|
return (dval != null ? new Double(dval) : null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for existence of a specified field in a hash.
|
* Test for existence of a specified field in a hash.
|
||||||
*
|
*
|
||||||
@@ -1694,7 +1755,9 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
|
|||||||
|
|
||||||
public Transaction multi() {
|
public Transaction multi() {
|
||||||
client.multi();
|
client.multi();
|
||||||
return new Transaction(client);
|
client.getOne(); // expected OK
|
||||||
|
transaction = new Transaction(client);
|
||||||
|
return transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@@ -1707,9 +1770,10 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
|
|||||||
public List<Object> multi(final TransactionBlock jedisTransaction) {
|
public List<Object> multi(final TransactionBlock jedisTransaction) {
|
||||||
List<Object> results = null;
|
List<Object> results = null;
|
||||||
jedisTransaction.setClient(client);
|
jedisTransaction.setClient(client);
|
||||||
client.multi();
|
client.multi();
|
||||||
jedisTransaction.execute();
|
client.getOne(); // expected OK
|
||||||
results = jedisTransaction.exec();
|
jedisTransaction.execute();
|
||||||
|
results = jedisTransaction.exec();
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1729,8 +1793,24 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void resetState() {
|
public void resetState() {
|
||||||
client.resetState();
|
if (client.isConnected()) {
|
||||||
client.getAll();
|
if (transaction != null) {
|
||||||
|
transaction.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pipeline != null) {
|
||||||
|
pipeline.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client.isInWatch()) {
|
||||||
|
unwatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
client.resetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction = null;
|
||||||
|
pipeline = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String watch(final byte[]... keys) {
|
public String watch(final byte[]... keys) {
|
||||||
@@ -1744,7 +1824,7 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2146,7 +2226,7 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Pipeline pipelined() {
|
public Pipeline pipelined() {
|
||||||
Pipeline pipeline = new Pipeline();
|
pipeline = new Pipeline();
|
||||||
pipeline.setClient(client);
|
pipeline.setClient(client);
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
@@ -3155,6 +3235,16 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
|
|||||||
return client.getIntegerReply() == 1;
|
return client.getIntegerReply() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long bitpos(final byte[] key, final boolean value) {
|
||||||
|
return bitpos(key, value, new BitPosParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long bitpos(final byte[] key, final boolean value,
|
||||||
|
final BitPosParams params) {
|
||||||
|
client.bitpos(key, value, params);
|
||||||
|
return client.getIntegerReply();
|
||||||
|
}
|
||||||
|
|
||||||
public Long setrange(byte[] key, long offset, byte[] value) {
|
public Long setrange(byte[] key, long offset, byte[] value) {
|
||||||
client.setrange(key, offset, value);
|
client.setrange(key, offset, value);
|
||||||
return client.getIntegerReply();
|
return client.getIntegerReply();
|
||||||
@@ -3343,7 +3433,7 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
|
|||||||
return client.getStatusCodeReply();
|
return client.getStatusCodeReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long pexpire(final byte[] key, final int milliseconds) {
|
public Long pexpire(final byte[] key, final long milliseconds) {
|
||||||
checkIsInMulti();
|
checkIsInMulti();
|
||||||
client.pexpire(key, milliseconds);
|
client.pexpire(key, milliseconds);
|
||||||
return client.getIntegerReply();
|
return client.getIntegerReply();
|
||||||
@@ -3361,13 +3451,6 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
|
|||||||
return client.getIntegerReply();
|
return client.getIntegerReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double incrByFloat(final byte[] key, final double increment) {
|
|
||||||
checkIsInMulti();
|
|
||||||
client.incrByFloat(key, increment);
|
|
||||||
String relpy = client.getBulkReply();
|
|
||||||
return (relpy != null ? new Double(relpy) : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String psetex(final byte[] key, final int milliseconds,
|
public String psetex(final byte[] key, final int milliseconds,
|
||||||
final byte[] value) {
|
final byte[] value) {
|
||||||
checkIsInMulti();
|
checkIsInMulti();
|
||||||
@@ -3425,14 +3508,6 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
|
|||||||
return client.getStatusCodeReply();
|
return client.getStatusCodeReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double hincrByFloat(final byte[] key, final byte[] field,
|
|
||||||
double increment) {
|
|
||||||
checkIsInMulti();
|
|
||||||
client.hincrByFloat(key, field, increment);
|
|
||||||
String relpy = client.getBulkReply();
|
|
||||||
return (relpy != null ? new Double(relpy) : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Syncrhonous replication of Redis as described here:
|
* Syncrhonous replication of Redis as described here:
|
||||||
* http://antirez.com/news/66
|
* http://antirez.com/news/66
|
||||||
@@ -3446,4 +3521,99 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
|
|||||||
return client.getIntegerReply();
|
return client.getIntegerReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long pfadd(final byte[] key, final byte[]... elements) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.pfadd(key, elements);
|
||||||
|
return client.getIntegerReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long pfcount(final byte[] key) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.pfcount(key);
|
||||||
|
return client.getIntegerReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String pfmerge(final byte[] destkey, final byte[]... sourcekeys) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.pfmerge(destkey, sourcekeys);
|
||||||
|
return client.getStatusCodeReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long pfcount(byte[]... keys) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.pfcount(keys);
|
||||||
|
return client.getIntegerReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScanResult<byte[]> scan(final byte[] cursor) {
|
||||||
|
return scan(cursor, new ScanParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScanResult<byte[]> scan(final byte[] cursor, final ScanParams params) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.scan(cursor, params);
|
||||||
|
List<Object> result = client.getObjectMultiBulkReply();
|
||||||
|
byte[] newcursor = (byte[]) result.get(0);
|
||||||
|
List<byte[]> rawResults = (List<byte[]>) result.get(1);
|
||||||
|
return new ScanResult<byte[]>(newcursor, rawResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScanResult<Map.Entry<byte[], byte[]>> hscan(final byte[] key,
|
||||||
|
final byte[] cursor) {
|
||||||
|
return hscan(key, cursor, new ScanParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScanResult<Map.Entry<byte[], byte[]>> hscan(final byte[] key,
|
||||||
|
final byte[] cursor, final ScanParams params) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.hscan(key, cursor, params);
|
||||||
|
List<Object> result = client.getObjectMultiBulkReply();
|
||||||
|
byte[] newcursor = (byte[]) result.get(0);
|
||||||
|
List<Map.Entry<byte[], byte[]>> results = new ArrayList<Map.Entry<byte[], byte[]>>();
|
||||||
|
List<byte[]> rawResults = (List<byte[]>) result.get(1);
|
||||||
|
Iterator<byte[]> iterator = rawResults.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
results.add(new AbstractMap.SimpleEntry<byte[], byte[]>(iterator
|
||||||
|
.next(), iterator.next()));
|
||||||
|
}
|
||||||
|
return new ScanResult<Map.Entry<byte[], byte[]>>(newcursor, results);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScanResult<byte[]> sscan(final byte[] key, final byte[] cursor) {
|
||||||
|
return sscan(key, cursor, new ScanParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScanResult<byte[]> sscan(final byte[] key, final byte[] cursor,
|
||||||
|
final ScanParams params) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.sscan(key, cursor, params);
|
||||||
|
List<Object> result = client.getObjectMultiBulkReply();
|
||||||
|
byte[] newcursor = (byte[]) result.get(0);
|
||||||
|
List<byte[]> rawResults = (List<byte[]>) result.get(1);
|
||||||
|
return new ScanResult<byte[]>(newcursor, rawResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScanResult<Tuple> zscan(final byte[] key, final byte[] cursor) {
|
||||||
|
return zscan(key, cursor, new ScanParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScanResult<Tuple> zscan(final byte[] key, final byte[] cursor,
|
||||||
|
final ScanParams params) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.zscan(key, cursor, params);
|
||||||
|
List<Object> result = client.getObjectMultiBulkReply();
|
||||||
|
byte[] newcursor = (byte[]) result.get(0);
|
||||||
|
List<Tuple> results = new ArrayList<Tuple>();
|
||||||
|
List<byte[]> rawResults = (List<byte[]>) result.get(1);
|
||||||
|
Iterator<byte[]> iterator = rawResults.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
results.add(new Tuple(iterator.next(), Double.valueOf(SafeEncoder
|
||||||
|
.encode(iterator.next()))));
|
||||||
|
}
|
||||||
|
return new ScanResult<Tuple>(newcursor, results);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ public interface BinaryJedisCommands {
|
|||||||
|
|
||||||
Long incrBy(byte[] key, long integer);
|
Long incrBy(byte[] key, long integer);
|
||||||
|
|
||||||
|
Double incrByFloat(byte[] key, double value);
|
||||||
|
|
||||||
Long incr(byte[] key);
|
Long incr(byte[] key);
|
||||||
|
|
||||||
Long append(byte[] key, byte[] value);
|
Long append(byte[] key, byte[] value);
|
||||||
@@ -65,6 +67,8 @@ public interface BinaryJedisCommands {
|
|||||||
|
|
||||||
Long hincrBy(byte[] key, byte[] field, long value);
|
Long hincrBy(byte[] key, byte[] field, long value);
|
||||||
|
|
||||||
|
Double hincrByFloat(byte[] key, byte[] field, double value);
|
||||||
|
|
||||||
Boolean hexists(byte[] key, byte[] field);
|
Boolean hexists(byte[] key, byte[] field);
|
||||||
|
|
||||||
Long hdel(byte[] key, byte[]... field);
|
Long hdel(byte[] key, byte[]... field);
|
||||||
@@ -111,6 +115,8 @@ public interface BinaryJedisCommands {
|
|||||||
|
|
||||||
byte[] srandmember(byte[] key);
|
byte[] srandmember(byte[] key);
|
||||||
|
|
||||||
|
List<byte[]> srandmember(final byte[] key, final int count);
|
||||||
|
|
||||||
Long strlen(byte[] key);
|
Long strlen(byte[] key);
|
||||||
|
|
||||||
Long zadd(byte[] key, double score, byte[] member);
|
Long zadd(byte[] key, double score, byte[] member);
|
||||||
@@ -220,4 +226,8 @@ public interface BinaryJedisCommands {
|
|||||||
Long bitcount(final byte[] key);
|
Long bitcount(final byte[] key);
|
||||||
|
|
||||||
Long bitcount(final byte[] key, long start, long end);
|
Long bitcount(final byte[] key, long start, long end);
|
||||||
|
|
||||||
|
Long pfadd(final byte[] key, final byte[]... elements);
|
||||||
|
|
||||||
|
long pfcount(final byte[] key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public interface BinaryRedisPipeline {
|
|||||||
|
|
||||||
Response<byte[]> getSet(byte[] key, byte[] value);
|
Response<byte[]> getSet(byte[] key, byte[] value);
|
||||||
|
|
||||||
Response<Long> getrange(byte[] key, long startOffset, long endOffset);
|
Response<byte[]> getrange(byte[] key, long startOffset, long endOffset);
|
||||||
|
|
||||||
Response<Long> hdel(byte[] key, byte[]... field);
|
Response<Long> hdel(byte[] key, byte[]... field);
|
||||||
|
|
||||||
@@ -219,4 +219,8 @@ public interface BinaryRedisPipeline {
|
|||||||
Response<Long> bitcount(byte[] key);
|
Response<Long> bitcount(byte[] key);
|
||||||
|
|
||||||
Response<Long> bitcount(byte[] key, long start, long end);
|
Response<Long> bitcount(byte[] key, long start, long end);
|
||||||
|
|
||||||
|
Response<Long> pfadd(final byte[] key, final byte[]... elements);
|
||||||
|
|
||||||
|
Response<Long> pfcount(final byte[] key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,6 +110,11 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
|
|||||||
return j.incrBy(key, integer);
|
return j.incrBy(key, integer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Double incrByFloat(byte[] key, double integer) {
|
||||||
|
Jedis j = getShard(key);
|
||||||
|
return j.incrByFloat(key, integer);
|
||||||
|
}
|
||||||
|
|
||||||
public Long incr(byte[] key) {
|
public Long incr(byte[] key) {
|
||||||
Jedis j = getShard(key);
|
Jedis j = getShard(key);
|
||||||
return j.incr(key);
|
return j.incr(key);
|
||||||
@@ -155,6 +160,11 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
|
|||||||
return j.hincrBy(key, field, value);
|
return j.hincrBy(key, field, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Double hincrByFloat(byte[] key, byte[] field, double value) {
|
||||||
|
Jedis j = getShard(key);
|
||||||
|
return j.hincrByFloat(key, field, value);
|
||||||
|
}
|
||||||
|
|
||||||
public Boolean hexists(byte[] key, byte[] field) {
|
public Boolean hexists(byte[] key, byte[] field) {
|
||||||
Jedis j = getShard(key);
|
Jedis j = getShard(key);
|
||||||
return j.hexists(key, field);
|
return j.hexists(key, field);
|
||||||
@@ -290,6 +300,12 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
|
|||||||
return j.srandmember(key);
|
return j.srandmember(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List srandmember(byte[] key, int count) {
|
||||||
|
Jedis j = getShard(key);
|
||||||
|
return j.srandmember(key, count);
|
||||||
|
}
|
||||||
|
|
||||||
public Long zadd(byte[] key, double score, byte[] member) {
|
public Long zadd(byte[] key, double score, byte[] member) {
|
||||||
Jedis j = getShard(key);
|
Jedis j = getShard(key);
|
||||||
return j.zadd(key, score, member);
|
return j.zadd(key, score, member);
|
||||||
@@ -595,4 +611,16 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
|
|||||||
return j.bitcount(key, start, end);
|
return j.bitcount(key, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long pfadd(final byte[] key, final byte[]... elements) {
|
||||||
|
Jedis j = getShard(key);
|
||||||
|
return j.pfadd(key, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long pfcount(final byte[] key) {
|
||||||
|
Jedis j = getShard(key);
|
||||||
|
return j.pfcount(key);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
27
src/main/java/redis/clients/jedis/BitPosParams.java
Normal file
27
src/main/java/redis/clients/jedis/BitPosParams.java
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package redis.clients.jedis;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BitPosParams {
|
||||||
|
private List<byte[]> params = new ArrayList<byte[]>();
|
||||||
|
|
||||||
|
protected BitPosParams() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitPosParams(long start) {
|
||||||
|
params.add(Protocol.toByteArray(start));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitPosParams(long start, long end) {
|
||||||
|
this(start);
|
||||||
|
|
||||||
|
params.add(Protocol.toByteArray(end));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<byte[]> getParams() {
|
||||||
|
return Collections.unmodifiableCollection(params);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import redis.clients.util.JedisByteHashMap;
|
||||||
import redis.clients.util.SafeEncoder;
|
import redis.clients.util.SafeEncoder;
|
||||||
|
|
||||||
public class BuilderFactory {
|
public class BuilderFactory {
|
||||||
@@ -104,6 +105,26 @@ public class BuilderFactory {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static final Builder<Map<String, String>> PUBSUB_NUMSUB_MAP = new Builder<Map<String, String>>() {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Map<String, String> build(Object data) {
|
||||||
|
final List<Object> flatHash = (List<Object>) data;
|
||||||
|
final Map<String, String> hash = new HashMap<String, String>();
|
||||||
|
final Iterator<Object> iterator = flatHash.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
hash.put(SafeEncoder.encode((byte[]) iterator.next()),
|
||||||
|
String.valueOf((Long) iterator.next()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "PUBSUB_NUMSUB_MAP<String, String>";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
public static final Builder<Set<String>> STRING_SET = new Builder<Set<String>>() {
|
public static final Builder<Set<String>> STRING_SET = new Builder<Set<String>>() {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Set<String> build(Object data) {
|
public Set<String> build(Object data) {
|
||||||
@@ -170,7 +191,7 @@ public class BuilderFactory {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Map<byte[], byte[]> build(Object data) {
|
public Map<byte[], byte[]> build(Object data) {
|
||||||
final List<byte[]> flatHash = (List<byte[]>) data;
|
final List<byte[]> flatHash = (List<byte[]>) data;
|
||||||
final Map<byte[], byte[]> hash = new HashMap<byte[], byte[]>();
|
final Map<byte[], byte[]> hash = new JedisByteHashMap();
|
||||||
final Iterator<byte[]> iterator = flatHash.iterator();
|
final Iterator<byte[]> iterator = flatHash.iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
hash.put(iterator.next(), iterator.next());
|
hash.put(iterator.next(), iterator.next());
|
||||||
|
|||||||
@@ -647,6 +647,9 @@ public class Client extends BinaryClient implements Commands {
|
|||||||
getbit(SafeEncoder.encode(key), offset);
|
getbit(SafeEncoder.encode(key), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void bitpos(final String key, final boolean value, final BitPosParams params) {
|
||||||
|
bitpos(SafeEncoder.encode(key), value, params);
|
||||||
|
}
|
||||||
public void setrange(String key, long offset, String value) {
|
public void setrange(String key, long offset, String value) {
|
||||||
setrange(SafeEncoder.encode(key), offset, SafeEncoder.encode(value));
|
setrange(SafeEncoder.encode(key), offset, SafeEncoder.encode(value));
|
||||||
}
|
}
|
||||||
@@ -795,7 +798,7 @@ public class Client extends BinaryClient implements Commands {
|
|||||||
restore(SafeEncoder.encode(key), ttl, serializedValue);
|
restore(SafeEncoder.encode(key), ttl, serializedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pexpire(final String key, final int milliseconds) {
|
public void pexpire(final String key, final long milliseconds) {
|
||||||
pexpire(SafeEncoder.encode(key), milliseconds);
|
pexpire(SafeEncoder.encode(key), milliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -851,36 +854,6 @@ public class Client extends BinaryClient implements Commands {
|
|||||||
increment);
|
increment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public void hscan(final String key, int cursor, final ScanParams params) {
|
|
||||||
hscan(SafeEncoder.encode(key), cursor, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public void sscan(final String key, int cursor, final ScanParams params) {
|
|
||||||
sscan(SafeEncoder.encode(key), cursor, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public void zscan(final String key, int cursor, final ScanParams params) {
|
|
||||||
zscan(SafeEncoder.encode(key), cursor, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void scan(final String cursor, final ScanParams params) {
|
public void scan(final String cursor, final ScanParams params) {
|
||||||
scan(SafeEncoder.encode(cursor), params);
|
scan(SafeEncoder.encode(cursor), params);
|
||||||
}
|
}
|
||||||
@@ -969,4 +942,60 @@ public class Client extends BinaryClient implements Commands {
|
|||||||
cluster(Protocol.CLUSTER_SETSLOT, String.valueOf(slot),
|
cluster(Protocol.CLUSTER_SETSLOT, String.valueOf(slot),
|
||||||
Protocol.CLUSTER_SETSLOT_IMPORTING, nodeId);
|
Protocol.CLUSTER_SETSLOT_IMPORTING, nodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void pfadd(String key, final String... elements) {
|
||||||
|
pfadd(SafeEncoder.encode(key), SafeEncoder.encodeMany(elements));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pfcount(final String key) {
|
||||||
|
pfcount(SafeEncoder.encode(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pfcount(final String...keys) {
|
||||||
|
pfcount(SafeEncoder.encodeMany(keys));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pfmerge(final String destkey, final String... sourcekeys) {
|
||||||
|
pfmerge(SafeEncoder.encode(destkey), SafeEncoder.encodeMany(sourcekeys));
|
||||||
|
}
|
||||||
|
public void clusterSetSlotStable(final int slot) {
|
||||||
|
cluster(Protocol.CLUSTER_SETSLOT, String.valueOf(slot),
|
||||||
|
Protocol.CLUSTER_SETSLOT_STABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clusterForget(final String nodeId) {
|
||||||
|
cluster(Protocol.CLUSTER_FORGET, nodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clusterFlushSlots() {
|
||||||
|
cluster(Protocol.CLUSTER_FLUSHSLOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clusterKeySlot(final String key) {
|
||||||
|
cluster(Protocol.CLUSTER_KEYSLOT, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clusterCountKeysInSlot(final int slot) {
|
||||||
|
cluster(Protocol.CLUSTER_COUNTKEYINSLOT, String.valueOf(slot));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clusterSaveConfig() {
|
||||||
|
cluster(Protocol.CLUSTER_SAVECONFIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clusterReplicate(final String nodeId) {
|
||||||
|
cluster(Protocol.CLUSTER_REPLICATE, nodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clusterSlaves(final String nodeId) {
|
||||||
|
cluster(Protocol.CLUSTER_SLAVES, nodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clusterFailover() {
|
||||||
|
cluster(Protocol.CLUSTER_FAILOVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clusterSlots() {
|
||||||
|
cluster(Protocol.CLUSTER_SLOTS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,4 +20,24 @@ public interface ClusterCommands {
|
|||||||
String clusterSetSlotMigrating(final int slot, final String nodeId);
|
String clusterSetSlotMigrating(final int slot, final String nodeId);
|
||||||
|
|
||||||
String clusterSetSlotImporting(final int slot, final String nodeId);
|
String clusterSetSlotImporting(final int slot, final String nodeId);
|
||||||
|
|
||||||
|
String clusterSetSlotStable(final int slot);
|
||||||
|
|
||||||
|
String clusterForget(final String nodeId);
|
||||||
|
|
||||||
|
String clusterFlushSlots();
|
||||||
|
|
||||||
|
Long clusterKeySlot(final String key);
|
||||||
|
|
||||||
|
Long clusterCountKeysInSlot(final int slot);
|
||||||
|
|
||||||
|
String clusterSaveConfig();
|
||||||
|
|
||||||
|
String clusterReplicate(final String nodeId);
|
||||||
|
|
||||||
|
List<String> clusterSlaves(final String nodeId);
|
||||||
|
|
||||||
|
String clusterFailover();
|
||||||
|
|
||||||
|
List<Object> clusterSlots();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ public interface Commands {
|
|||||||
|
|
||||||
public void incrBy(final String key, final long integer);
|
public void incrBy(final String key, final long integer);
|
||||||
|
|
||||||
|
public void incrByFloat(final String key, final double value);
|
||||||
|
|
||||||
public void incr(final String key);
|
public void incr(final String key);
|
||||||
|
|
||||||
public void append(final String key, final String value);
|
public void append(final String key, final String value);
|
||||||
@@ -79,6 +81,8 @@ public interface Commands {
|
|||||||
|
|
||||||
public void hincrBy(final String key, final String field, final long value);
|
public void hincrBy(final String key, final String field, final long value);
|
||||||
|
|
||||||
|
public void hincrByFloat(final String key, final String field, final double value);
|
||||||
|
|
||||||
public void hexists(final String key, final String field);
|
public void hexists(final String key, final String field);
|
||||||
|
|
||||||
public void hdel(final String key, final String... fields);
|
public void hdel(final String key, final String... fields);
|
||||||
@@ -297,38 +301,6 @@ public interface Commands {
|
|||||||
|
|
||||||
public void bitop(BitOP op, final String destKey, String... srcKeys);
|
public void bitop(BitOP op, final String destKey, String... srcKeys);
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public void scan(int cursor, final ScanParams params);
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public void hscan(final String key, int cursor, final ScanParams params);
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public void sscan(final String key, int cursor, final ScanParams params);
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public void zscan(final String key, int cursor, final ScanParams params);
|
|
||||||
|
|
||||||
public void scan(final String cursor, final ScanParams params);
|
public void scan(final String cursor, final ScanParams params);
|
||||||
|
|
||||||
public void hscan(final String key, final String cursor, final ScanParams params);
|
public void hscan(final String key, final String cursor, final ScanParams params);
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import java.util.List;
|
|||||||
import redis.clients.jedis.Protocol.Command;
|
import redis.clients.jedis.Protocol.Command;
|
||||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||||
import redis.clients.jedis.exceptions.JedisDataException;
|
import redis.clients.jedis.exceptions.JedisDataException;
|
||||||
import redis.clients.jedis.exceptions.JedisException;
|
|
||||||
import redis.clients.util.RedisInputStream;
|
import redis.clients.util.RedisInputStream;
|
||||||
import redis.clients.util.RedisOutputStream;
|
import redis.clients.util.RedisOutputStream;
|
||||||
import redis.clients.util.SafeEncoder;
|
import redis.clients.util.SafeEncoder;
|
||||||
@@ -22,9 +21,10 @@ public class Connection implements Closeable {
|
|||||||
private Socket socket;
|
private Socket socket;
|
||||||
private RedisOutputStream outputStream;
|
private RedisOutputStream outputStream;
|
||||||
private RedisInputStream inputStream;
|
private RedisInputStream inputStream;
|
||||||
private int pipelinedCommands = 0;
|
|
||||||
private int timeout = Protocol.DEFAULT_TIMEOUT;
|
private int timeout = Protocol.DEFAULT_TIMEOUT;
|
||||||
|
|
||||||
|
private boolean broken = false;
|
||||||
|
|
||||||
public Socket getSocket() {
|
public Socket getSocket() {
|
||||||
return socket;
|
return socket;
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,8 @@ public class Connection implements Closeable {
|
|||||||
socket.setKeepAlive(true);
|
socket.setKeepAlive(true);
|
||||||
socket.setSoTimeout(0);
|
socket.setSoTimeout(0);
|
||||||
} catch (SocketException ex) {
|
} catch (SocketException ex) {
|
||||||
throw new JedisException(ex);
|
broken = true;
|
||||||
|
throw new JedisConnectionException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +55,8 @@ public class Connection implements Closeable {
|
|||||||
socket.setSoTimeout(timeout);
|
socket.setSoTimeout(timeout);
|
||||||
socket.setKeepAlive(false);
|
socket.setKeepAlive(false);
|
||||||
} catch (SocketException ex) {
|
} catch (SocketException ex) {
|
||||||
throw new JedisException(ex);
|
broken = true;
|
||||||
|
throw new JedisConnectionException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,14 +65,6 @@ public class Connection implements Closeable {
|
|||||||
this.host = host;
|
this.host = host;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void flush() {
|
|
||||||
try {
|
|
||||||
outputStream.flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new JedisConnectionException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Connection sendCommand(final Command cmd, final String... args) {
|
protected Connection sendCommand(final Command cmd, final String... args) {
|
||||||
final byte[][] bargs = new byte[args.length][];
|
final byte[][] bargs = new byte[args.length][];
|
||||||
for (int i = 0; i < args.length; i++) {
|
for (int i = 0; i < args.length; i++) {
|
||||||
@@ -80,17 +74,27 @@ public class Connection implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Connection sendCommand(final Command cmd, final byte[]... args) {
|
protected Connection sendCommand(final Command cmd, final byte[]... args) {
|
||||||
connect();
|
try {
|
||||||
Protocol.sendCommand(outputStream, cmd, args);
|
connect();
|
||||||
pipelinedCommands++;
|
Protocol.sendCommand(outputStream, cmd, args);
|
||||||
return this;
|
return this;
|
||||||
|
} catch (JedisConnectionException ex) {
|
||||||
|
// Any other exceptions related to connection?
|
||||||
|
broken = true;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Connection sendCommand(final Command cmd) {
|
protected Connection sendCommand(final Command cmd) {
|
||||||
connect();
|
try {
|
||||||
Protocol.sendCommand(outputStream, cmd, new byte[0][]);
|
connect();
|
||||||
pipelinedCommands++;
|
Protocol.sendCommand(outputStream, cmd, new byte[0][]);
|
||||||
return this;
|
return this;
|
||||||
|
} catch (JedisConnectionException ex) {
|
||||||
|
// Any other exceptions related to connection?
|
||||||
|
broken = true;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Connection(final String host, final int port) {
|
public Connection(final String host, final int port) {
|
||||||
@@ -139,6 +143,7 @@ public class Connection implements Closeable {
|
|||||||
outputStream = new RedisOutputStream(socket.getOutputStream());
|
outputStream = new RedisOutputStream(socket.getOutputStream());
|
||||||
inputStream = new RedisInputStream(socket.getInputStream());
|
inputStream = new RedisInputStream(socket.getInputStream());
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
|
broken = true;
|
||||||
throw new JedisConnectionException(ex);
|
throw new JedisConnectionException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,7 +152,7 @@ public class Connection implements Closeable {
|
|||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
disconnect();
|
disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
if (isConnected()) {
|
if (isConnected()) {
|
||||||
@@ -158,6 +163,7 @@ public class Connection implements Closeable {
|
|||||||
socket.close();
|
socket.close();
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
|
broken = true;
|
||||||
throw new JedisConnectionException(ex);
|
throw new JedisConnectionException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,8 +177,7 @@ public class Connection implements Closeable {
|
|||||||
|
|
||||||
protected String getStatusCodeReply() {
|
protected String getStatusCodeReply() {
|
||||||
flush();
|
flush();
|
||||||
pipelinedCommands--;
|
final byte[] resp = (byte[]) readProtocolWithCheckingBroken();
|
||||||
final byte[] resp = (byte[]) Protocol.read(inputStream);
|
|
||||||
if (null == resp) {
|
if (null == resp) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
@@ -191,14 +196,12 @@ public class Connection implements Closeable {
|
|||||||
|
|
||||||
public byte[] getBinaryBulkReply() {
|
public byte[] getBinaryBulkReply() {
|
||||||
flush();
|
flush();
|
||||||
pipelinedCommands--;
|
return (byte[]) readProtocolWithCheckingBroken();
|
||||||
return (byte[]) Protocol.read(inputStream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getIntegerReply() {
|
public Long getIntegerReply() {
|
||||||
flush();
|
flush();
|
||||||
pipelinedCommands--;
|
return (Long) readProtocolWithCheckingBroken();
|
||||||
return (Long) Protocol.read(inputStream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getMultiBulkReply() {
|
public List<String> getMultiBulkReply() {
|
||||||
@@ -208,53 +211,62 @@ public class Connection implements Closeable {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public List<byte[]> getBinaryMultiBulkReply() {
|
public List<byte[]> getBinaryMultiBulkReply() {
|
||||||
flush();
|
flush();
|
||||||
pipelinedCommands--;
|
return (List<byte[]>) readProtocolWithCheckingBroken();
|
||||||
return (List<byte[]>) Protocol.read(inputStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetPipelinedCount() {
|
|
||||||
pipelinedCommands = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public List<Object> getRawObjectMultiBulkReply() {
|
public List<Object> getRawObjectMultiBulkReply() {
|
||||||
return (List<Object>) Protocol.read(inputStream);
|
return (List<Object>) readProtocolWithCheckingBroken();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Object> getObjectMultiBulkReply() {
|
public List<Object> getObjectMultiBulkReply() {
|
||||||
flush();
|
flush();
|
||||||
pipelinedCommands--;
|
return getRawObjectMultiBulkReply();
|
||||||
return getRawObjectMultiBulkReply();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public List<Long> getIntegerMultiBulkReply() {
|
public List<Long> getIntegerMultiBulkReply() {
|
||||||
flush();
|
flush();
|
||||||
pipelinedCommands--;
|
return (List<Long>) Protocol.read(inputStream);
|
||||||
return (List<Long>) Protocol.read(inputStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Object> getAll() {
|
|
||||||
return getAll(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Object> getAll(int except) {
|
|
||||||
List<Object> all = new ArrayList<Object>();
|
|
||||||
flush();
|
|
||||||
while (pipelinedCommands > except) {
|
|
||||||
try {
|
|
||||||
all.add(Protocol.read(inputStream));
|
|
||||||
} catch (JedisDataException e) {
|
|
||||||
all.add(e);
|
|
||||||
}
|
|
||||||
pipelinedCommands--;
|
|
||||||
}
|
|
||||||
return all;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getOne() {
|
public Object getOne() {
|
||||||
flush();
|
flush();
|
||||||
pipelinedCommands--;
|
return readProtocolWithCheckingBroken();
|
||||||
return Protocol.read(inputStream);
|
}
|
||||||
|
|
||||||
|
public boolean isBroken() {
|
||||||
|
return broken;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void flush() {
|
||||||
|
try {
|
||||||
|
outputStream.flush();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
broken = true;
|
||||||
|
throw new JedisConnectionException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object readProtocolWithCheckingBroken() {
|
||||||
|
try {
|
||||||
|
return Protocol.read(inputStream);
|
||||||
|
} catch (JedisConnectionException exc) {
|
||||||
|
broken = true;
|
||||||
|
throw exc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Object> getMany(int count) {
|
||||||
|
flush();
|
||||||
|
List<Object> responses = new ArrayList<Object>();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
try {
|
||||||
|
responses.add(readProtocolWithCheckingBroken());
|
||||||
|
} catch (JedisDataException e) {
|
||||||
|
responses.add(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return responses;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
package redis.clients.jedis;
|
package redis.clients.jedis;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.AbstractMap;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import redis.clients.jedis.BinaryClient.LIST_POSITION;
|
import redis.clients.jedis.BinaryClient.LIST_POSITION;
|
||||||
|
import redis.clients.util.Pool;
|
||||||
import redis.clients.util.SafeEncoder;
|
import redis.clients.util.SafeEncoder;
|
||||||
import redis.clients.util.Slowlog;
|
import redis.clients.util.Slowlog;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
public class Jedis extends BinaryJedis implements JedisCommands,
|
public class Jedis extends BinaryJedis implements JedisCommands,
|
||||||
MultiKeyCommands, AdvancedJedisCommands, ScriptingCommands,
|
MultiKeyCommands, AdvancedJedisCommands, ScriptingCommands,
|
||||||
BasicCommands, ClusterCommands {
|
BasicCommands, ClusterCommands {
|
||||||
|
|
||||||
|
protected Pool<Jedis> dataSource = null;
|
||||||
|
|
||||||
public Jedis(final String host) {
|
public Jedis(final String host) {
|
||||||
super(host);
|
super(host);
|
||||||
}
|
}
|
||||||
@@ -547,6 +544,31 @@ public class Jedis extends BinaryJedis implements JedisCommands,
|
|||||||
return client.getIntegerReply();
|
return client.getIntegerReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INCRBYFLOAT
|
||||||
|
* <p>
|
||||||
|
* INCRBYFLOAT commands are limited to double precision floating point values.
|
||||||
|
* <p>
|
||||||
|
* Note: this is actually a string operation, that is, in Redis there are
|
||||||
|
* not "double" types. Simply the string stored at the key is parsed as a
|
||||||
|
* base double precision floating point value, incremented, and then
|
||||||
|
* converted back as a string. There is no DECRYBYFLOAT but providing a
|
||||||
|
* negative value will work as expected.
|
||||||
|
* <p>
|
||||||
|
* Time complexity: O(1)
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param value
|
||||||
|
* @return Double reply, this commands will reply with the new value of key
|
||||||
|
* after the increment.
|
||||||
|
*/
|
||||||
|
public Double incrByFloat(final String key, final double value) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.incrByFloat(key, value);
|
||||||
|
String dval = client.getBulkReply();
|
||||||
|
return (dval != null ? new Double(dval) : null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increment the number stored at key by one. If the key does not exist or
|
* Increment the number stored at key by one. If the key does not exist or
|
||||||
* contains a value of a wrong type, set the key to the value of "0" before
|
* contains a value of a wrong type, set the key to the value of "0" before
|
||||||
@@ -739,6 +761,32 @@ public class Jedis extends BinaryJedis implements JedisCommands,
|
|||||||
return client.getIntegerReply();
|
return client.getIntegerReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the number stored at field in the hash at key by a double
|
||||||
|
* precision floating point value. If key does not exist,
|
||||||
|
* a new key holding a hash is created. If field does not
|
||||||
|
* exist or holds a string, the value is set to 0 before applying the
|
||||||
|
* operation. Since the value argument is signed you can use this command to
|
||||||
|
* perform both increments and decrements.
|
||||||
|
* <p>
|
||||||
|
* The range of values supported by HINCRBYFLOAT is limited to
|
||||||
|
* double precision floating point values.
|
||||||
|
* <p>
|
||||||
|
* <b>Time complexity:</b> O(1)
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param field
|
||||||
|
* @param value
|
||||||
|
* @return Double precision floating point reply The new value at field after the increment
|
||||||
|
* operation.
|
||||||
|
*/
|
||||||
|
public Double hincrByFloat(final String key, final String field, final double value) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.hincrByFloat(key, field, value);
|
||||||
|
final String dval = client.getBulkReply();
|
||||||
|
return (dval != null ? new Double(dval) : null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for existence of a specified field in a hash.
|
* Test for existence of a specified field in a hash.
|
||||||
*
|
*
|
||||||
@@ -1068,8 +1116,8 @@ public class Jedis extends BinaryJedis implements JedisCommands,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically return and remove the first (LPOP) or last (RPOP) element of
|
* Atomically return and remove the first (LPOP) or last (RPOP) element of
|
||||||
* the list. For example if the list contains the elements "a","b","c" LPOP
|
* the list. For example if the list contains the elements "a","b","c" RPOP
|
||||||
* will return "a" and the list will become "b","c".
|
* will return "c" and the list will become "a","b".
|
||||||
* <p>
|
* <p>
|
||||||
* If the key does not exist or the list is already empty the special value
|
* If the key does not exist or the list is already empty the special value
|
||||||
* 'nil' is returned.
|
* 'nil' is returned.
|
||||||
@@ -2689,6 +2737,15 @@ public class Jedis extends BinaryJedis implements JedisCommands,
|
|||||||
return client.getBulkReply();
|
return client.getBulkReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long bitpos(final String key, final boolean value) {
|
||||||
|
return bitpos(key, value, new BitPosParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long bitpos(final String key, final boolean value, final BitPosParams params) {
|
||||||
|
client.bitpos(key, value, params);
|
||||||
|
return client.getIntegerReply();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the configuration of a running Redis server. Not all the
|
* Retrieve the configuration of a running Redis server. Not all the
|
||||||
* configuration parameters are supported.
|
* configuration parameters are supported.
|
||||||
@@ -3089,7 +3146,7 @@ public class Jedis extends BinaryJedis implements JedisCommands,
|
|||||||
return client.getStatusCodeReply();
|
return client.getStatusCodeReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long pexpire(final String key, final int milliseconds) {
|
public Long pexpire(final String key, final long milliseconds) {
|
||||||
checkIsInMulti();
|
checkIsInMulti();
|
||||||
client.pexpire(key, milliseconds);
|
client.pexpire(key, milliseconds);
|
||||||
return client.getIntegerReply();
|
return client.getIntegerReply();
|
||||||
@@ -3107,12 +3164,6 @@ public class Jedis extends BinaryJedis implements JedisCommands,
|
|||||||
return client.getIntegerReply();
|
return client.getIntegerReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double incrByFloat(final String key, final double increment) {
|
|
||||||
checkIsInMulti();
|
|
||||||
client.incrByFloat(key, increment);
|
|
||||||
String relpy = client.getBulkReply();
|
|
||||||
return (relpy != null ? new Double(relpy) : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String psetex(final String key, final int milliseconds,
|
public String psetex(final String key, final int milliseconds,
|
||||||
final String value) {
|
final String value) {
|
||||||
@@ -3153,139 +3204,6 @@ public class Jedis extends BinaryJedis implements JedisCommands,
|
|||||||
return client.getStatusCodeReply();
|
return client.getStatusCodeReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double hincrByFloat(final String key, final String field,
|
|
||||||
double increment) {
|
|
||||||
checkIsInMulti();
|
|
||||||
client.hincrByFloat(key, field, increment);
|
|
||||||
String relpy = client.getBulkReply();
|
|
||||||
return (relpy != null ? new Double(relpy) : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public ScanResult<String> scan(int cursor) {
|
|
||||||
return scan(cursor, new ScanParams());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public ScanResult<String> scan(int cursor, final ScanParams params) {
|
|
||||||
checkIsInMulti();
|
|
||||||
client.scan(cursor, params);
|
|
||||||
List<Object> result = client.getObjectMultiBulkReply();
|
|
||||||
int newcursor = Integer.parseInt(new String((byte[]) result.get(0)));
|
|
||||||
List<String> results = new ArrayList<String>();
|
|
||||||
List<byte[]> rawResults = (List<byte[]>) result.get(1);
|
|
||||||
for (byte[] bs : rawResults) {
|
|
||||||
results.add(SafeEncoder.encode(bs));
|
|
||||||
}
|
|
||||||
return new ScanResult<String>(newcursor, results);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public ScanResult<Map.Entry<String, String>> hscan(final String key,
|
|
||||||
int cursor) {
|
|
||||||
return hscan(key, cursor, new ScanParams());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public ScanResult<Map.Entry<String, String>> hscan(final String key,
|
|
||||||
int cursor, final ScanParams params) {
|
|
||||||
checkIsInMulti();
|
|
||||||
client.hscan(key, cursor, params);
|
|
||||||
List<Object> result = client.getObjectMultiBulkReply();
|
|
||||||
int newcursor = Integer.parseInt(new String((byte[]) result.get(0)));
|
|
||||||
List<Map.Entry<String, String>> results = new ArrayList<Map.Entry<String, String>>();
|
|
||||||
List<byte[]> rawResults = (List<byte[]>) result.get(1);
|
|
||||||
Iterator<byte[]> iterator = rawResults.iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
results.add(new AbstractMap.SimpleEntry<String, String>(SafeEncoder
|
|
||||||
.encode(iterator.next()), SafeEncoder.encode(iterator
|
|
||||||
.next())));
|
|
||||||
}
|
|
||||||
return new ScanResult<Map.Entry<String, String>>(newcursor, results);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public ScanResult<String> sscan(final String key, int cursor) {
|
|
||||||
return sscan(key, cursor, new ScanParams());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public ScanResult<String> sscan(final String key, int cursor,
|
|
||||||
final ScanParams params) {
|
|
||||||
checkIsInMulti();
|
|
||||||
client.sscan(key, cursor, params);
|
|
||||||
List<Object> result = client.getObjectMultiBulkReply();
|
|
||||||
int newcursor = Integer.parseInt(new String((byte[]) result.get(0)));
|
|
||||||
List<String> results = new ArrayList<String>();
|
|
||||||
List<byte[]> rawResults = (List<byte[]>) result.get(1);
|
|
||||||
for (byte[] bs : rawResults) {
|
|
||||||
results.add(SafeEncoder.encode(bs));
|
|
||||||
}
|
|
||||||
return new ScanResult<String>(newcursor, results);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public ScanResult<Tuple> zscan(final String key, int cursor) {
|
|
||||||
return zscan(key, cursor, new ScanParams());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public ScanResult<Tuple> zscan(final String key, int cursor,
|
|
||||||
final ScanParams params) {
|
|
||||||
checkIsInMulti();
|
|
||||||
client.zscan(key, cursor, params);
|
|
||||||
List<Object> result = client.getObjectMultiBulkReply();
|
|
||||||
int newcursor = Integer.parseInt(new String((byte[]) result.get(0)));
|
|
||||||
List<Tuple> results = new ArrayList<Tuple>();
|
|
||||||
List<byte[]> rawResults = (List<byte[]>) result.get(1);
|
|
||||||
Iterator<byte[]> iterator = rawResults.iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
results.add(new Tuple(SafeEncoder.encode(iterator.next()), Double
|
|
||||||
.valueOf(SafeEncoder.encode(iterator.next()))));
|
|
||||||
}
|
|
||||||
return new ScanResult<Tuple>(newcursor, results);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScanResult<String> scan(final String cursor) {
|
public ScanResult<String> scan(final String cursor) {
|
||||||
return scan(cursor, new ScanParams());
|
return scan(cursor, new ScanParams());
|
||||||
}
|
}
|
||||||
@@ -3320,7 +3238,7 @@ public class Jedis extends BinaryJedis implements JedisCommands,
|
|||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
results.add(new AbstractMap.SimpleEntry<String, String>(SafeEncoder
|
results.add(new AbstractMap.SimpleEntry<String, String>(SafeEncoder
|
||||||
.encode(iterator.next()), SafeEncoder.encode(iterator
|
.encode(iterator.next()), SafeEncoder.encode(iterator
|
||||||
.next())));
|
.next())));
|
||||||
}
|
}
|
||||||
return new ScanResult<Map.Entry<String, String>>(newcursor, results);
|
return new ScanResult<Map.Entry<String, String>>(newcursor, results);
|
||||||
}
|
}
|
||||||
@@ -3417,6 +3335,67 @@ public class Jedis extends BinaryJedis implements JedisCommands,
|
|||||||
return client.getStatusCodeReply();
|
return client.getStatusCodeReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String clusterSetSlotStable(final int slot) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.clusterSetSlotStable(slot);
|
||||||
|
return client.getStatusCodeReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String clusterForget(final String nodeId) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.clusterForget(nodeId);
|
||||||
|
return client.getStatusCodeReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String clusterFlushSlots() {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.clusterFlushSlots();
|
||||||
|
return client.getStatusCodeReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long clusterKeySlot(final String key) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.clusterKeySlot(key);
|
||||||
|
return client.getIntegerReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long clusterCountKeysInSlot(final int slot) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.clusterCountKeysInSlot(slot);
|
||||||
|
return client.getIntegerReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String clusterSaveConfig() {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.clusterSaveConfig();
|
||||||
|
return client.getStatusCodeReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String clusterReplicate(final String nodeId) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.clusterReplicate(nodeId);
|
||||||
|
return client.getStatusCodeReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> clusterSlaves(final String nodeId) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.clusterSlaves(nodeId);
|
||||||
|
return client.getMultiBulkReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String clusterFailover() {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.clusterFailover();
|
||||||
|
return client.getStatusCodeReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Object> clusterSlots() {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.clusterSlots();
|
||||||
|
return client.getObjectMultiBulkReply();
|
||||||
|
}
|
||||||
|
|
||||||
public String asking() {
|
public String asking() {
|
||||||
checkIsInMulti();
|
checkIsInMulti();
|
||||||
client.asking();
|
client.asking();
|
||||||
@@ -3438,8 +3417,50 @@ public class Jedis extends BinaryJedis implements JedisCommands,
|
|||||||
public Map<String, String> pubsubNumSub(String... channels) {
|
public Map<String, String> pubsubNumSub(String... channels) {
|
||||||
checkIsInMulti();
|
checkIsInMulti();
|
||||||
client.pubsubNumSub(channels);
|
client.pubsubNumSub(channels);
|
||||||
return BuilderFactory.STRING_MAP
|
return BuilderFactory.PUBSUB_NUMSUB_MAP
|
||||||
.build(client.getBinaryMultiBulkReply());
|
.build(client.getBinaryMultiBulkReply());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (dataSource != null) {
|
||||||
|
if (client.isBroken()) {
|
||||||
|
this.dataSource.returnBrokenResource(this);
|
||||||
|
} else {
|
||||||
|
this.dataSource.returnResource(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDataSource(Pool<Jedis> jedisPool) {
|
||||||
|
this.dataSource = jedisPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long pfadd(final String key, final String... elements) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.pfadd(key, elements);
|
||||||
|
return client.getIntegerReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long pfcount(final String key) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.pfcount(key);
|
||||||
|
return client.getIntegerReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long pfcount(String... keys) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.pfcount(keys);
|
||||||
|
return client.getIntegerReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String pfmerge(final String destkey, final String... sourcekeys) {
|
||||||
|
checkIsInMulti();
|
||||||
|
client.pfmerge(destkey, sourcekeys);
|
||||||
|
return client.getStatusCodeReply();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
package redis.clients.jedis;
|
package redis.clients.jedis;
|
||||||
|
|
||||||
|
import redis.clients.jedis.BinaryClient.LIST_POSITION;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import redis.clients.jedis.BinaryClient.LIST_POSITION;
|
public class JedisCluster implements JedisCommands, BasicCommands, Closeable {
|
||||||
|
|
||||||
public class JedisCluster implements JedisCommands, BasicCommands {
|
|
||||||
public static final short HASHSLOTS = 16384;
|
public static final short HASHSLOTS = 16384;
|
||||||
private static final int DEFAULT_TIMEOUT = 1;
|
private static final int DEFAULT_TIMEOUT = 1;
|
||||||
private static final int DEFAULT_MAX_REDIRECTIONS = 5;
|
private static final int DEFAULT_MAX_REDIRECTIONS = 5;
|
||||||
@@ -33,6 +34,21 @@ public class JedisCluster implements JedisCommands, BasicCommands {
|
|||||||
this.maxRedirections = maxRedirections;
|
this.maxRedirections = maxRedirections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (connectionHandler != null) {
|
||||||
|
for (JedisPool pool : connectionHandler.getNodes().values()) {
|
||||||
|
try {
|
||||||
|
if (pool != null) {
|
||||||
|
pool.destroy();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String set(final String key, final String value) {
|
public String set(final String key, final String value) {
|
||||||
return new JedisClusterCommand<String>(connectionHandler, timeout,
|
return new JedisClusterCommand<String>(connectionHandler, timeout,
|
||||||
@@ -44,6 +60,18 @@ public class JedisCluster implements JedisCommands, BasicCommands {
|
|||||||
}.run(key);
|
}.run(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String set(final String key, final String value, final String nxxx,
|
||||||
|
final String expx, final long time) {
|
||||||
|
return new JedisClusterCommand<String>(connectionHandler, timeout,
|
||||||
|
maxRedirections) {
|
||||||
|
@Override
|
||||||
|
public String execute(Jedis connection) {
|
||||||
|
return connection.set(key, value, nxxx, expx, time);
|
||||||
|
}
|
||||||
|
}.run(key);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String get(final String key) {
|
public String get(final String key) {
|
||||||
return new JedisClusterCommand<String>(connectionHandler, timeout,
|
return new JedisClusterCommand<String>(connectionHandler, timeout,
|
||||||
@@ -382,7 +410,7 @@ public class JedisCluster implements JedisCommands, BasicCommands {
|
|||||||
maxRedirections) {
|
maxRedirections) {
|
||||||
@Override
|
@Override
|
||||||
public Long execute(Jedis connection) {
|
public Long execute(Jedis connection) {
|
||||||
return connection.hdel(key);
|
return connection.hlen(key);
|
||||||
}
|
}
|
||||||
}.run(key);
|
}.run(key);
|
||||||
}
|
}
|
||||||
@@ -611,6 +639,17 @@ public class JedisCluster implements JedisCommands, BasicCommands {
|
|||||||
}.run(key);
|
}.run(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> srandmember(final String key, final int count) {
|
||||||
|
return new JedisClusterCommand<List<String>>(connectionHandler, timeout,
|
||||||
|
maxRedirections) {
|
||||||
|
@Override
|
||||||
|
public List<String> execute(Jedis connection) {
|
||||||
|
return connection.srandmember(key, count);
|
||||||
|
}
|
||||||
|
}.run(key);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long strlen(final String key) {
|
public Long strlen(final String key) {
|
||||||
return new JedisClusterCommand<Long>(connectionHandler, timeout,
|
return new JedisClusterCommand<Long>(connectionHandler, timeout,
|
||||||
@@ -1441,58 +1480,6 @@ public class JedisCluster implements JedisCommands, BasicCommands {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public ScanResult<Entry<String, String>> hscan(final String key,
|
|
||||||
final int cursor) {
|
|
||||||
return new JedisClusterCommand<ScanResult<Entry<String, String>>>(
|
|
||||||
connectionHandler, timeout, maxRedirections) {
|
|
||||||
@Override
|
|
||||||
public ScanResult<Entry<String, String>> execute(Jedis connection) {
|
|
||||||
return connection.hscan(key, cursor);
|
|
||||||
}
|
|
||||||
}.run(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public ScanResult<String> sscan(final String key, final int cursor) {
|
|
||||||
return new JedisClusterCommand<ScanResult<String>>(connectionHandler,
|
|
||||||
timeout, maxRedirections) {
|
|
||||||
@Override
|
|
||||||
public ScanResult<String> execute(Jedis connection) {
|
|
||||||
return connection.sscan(key, cursor);
|
|
||||||
}
|
|
||||||
}.run(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public ScanResult<Tuple> zscan(final String key, final int cursor) {
|
|
||||||
return new JedisClusterCommand<ScanResult<Tuple>>(connectionHandler,
|
|
||||||
timeout, maxRedirections) {
|
|
||||||
@Override
|
|
||||||
public ScanResult<Tuple> execute(Jedis connection) {
|
|
||||||
return connection.zscan(key, cursor);
|
|
||||||
}
|
|
||||||
}.run(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ScanResult<Entry<String, String>> hscan(final String key,
|
public ScanResult<Entry<String, String>> hscan(final String key,
|
||||||
final String cursor) {
|
final String cursor) {
|
||||||
@@ -1527,4 +1514,26 @@ public class JedisCluster implements JedisCommands, BasicCommands {
|
|||||||
}.run(null);
|
}.run(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long pfadd(final String key, final String... elements) {
|
||||||
|
return new JedisClusterCommand<Long>(connectionHandler,
|
||||||
|
timeout, maxRedirections) {
|
||||||
|
@Override
|
||||||
|
public Long execute(Jedis connection) {
|
||||||
|
return connection.pfadd(key, elements);
|
||||||
|
}
|
||||||
|
}.run(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long pfcount(final String key) {
|
||||||
|
return new JedisClusterCommand<Long>(connectionHandler,
|
||||||
|
timeout, maxRedirections) {
|
||||||
|
@Override
|
||||||
|
public Long execute(Jedis connection) {
|
||||||
|
return connection.pfcount(key);
|
||||||
|
}
|
||||||
|
}.run(key);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import redis.clients.jedis.exceptions.JedisAskDataException;
|
|||||||
import redis.clients.jedis.exceptions.JedisClusterException;
|
import redis.clients.jedis.exceptions.JedisClusterException;
|
||||||
import redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException;
|
import redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException;
|
||||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||||
import redis.clients.jedis.exceptions.JedisException;
|
|
||||||
import redis.clients.jedis.exceptions.JedisMovedDataException;
|
import redis.clients.jedis.exceptions.JedisMovedDataException;
|
||||||
import redis.clients.jedis.exceptions.JedisRedirectionException;
|
import redis.clients.jedis.exceptions.JedisRedirectionException;
|
||||||
import redis.clients.util.JedisClusterCRC16;
|
import redis.clients.util.JedisClusterCRC16;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package redis.clients.jedis;
|
package redis.clients.jedis;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||||
|
import redis.clients.util.ClusterNodeInformation;
|
||||||
|
import redis.clients.util.ClusterNodeInformationParser;
|
||||||
|
|
||||||
public abstract class JedisClusterConnectionHandler {
|
public abstract class JedisClusterConnectionHandler {
|
||||||
|
public static ClusterNodeInformationParser nodeInfoParser = new ClusterNodeInformationParser();
|
||||||
|
|
||||||
protected Map<String, JedisPool> nodes = new HashMap<String, JedisPool>();
|
protected Map<String, JedisPool> nodes = new HashMap<String, JedisPool>();
|
||||||
protected Map<Integer, JedisPool> slots = new HashMap<Integer, JedisPool>();
|
protected Map<Integer, JedisPool> slots = new HashMap<Integer, JedisPool>();
|
||||||
@@ -69,65 +69,36 @@ public abstract class JedisClusterConnectionHandler {
|
|||||||
private void discoverClusterNodesAndSlots(Jedis jedis) {
|
private void discoverClusterNodesAndSlots(Jedis jedis) {
|
||||||
String localNodes = jedis.clusterNodes();
|
String localNodes = jedis.clusterNodes();
|
||||||
for (String nodeInfo : localNodes.split("\n")) {
|
for (String nodeInfo : localNodes.split("\n")) {
|
||||||
HostAndPort node = getHostAndPortFromNodeLine(nodeInfo, jedis);
|
ClusterNodeInformation clusterNodeInfo = nodeInfoParser.parse(
|
||||||
setNodeIfNotExist(node);
|
nodeInfo, new HostAndPort(jedis.getClient().getHost(),
|
||||||
|
jedis.getClient().getPort()));
|
||||||
|
|
||||||
JedisPool nodePool = nodes.get(getNodeKey(node));
|
HostAndPort targetNode = clusterNodeInfo.getNode();
|
||||||
populateNodeSlots(nodeInfo, nodePool);
|
setNodeIfNotExist(targetNode);
|
||||||
|
assignSlotsToNode(clusterNodeInfo.getAvailableSlots(), targetNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setNodeIfNotExist(HostAndPort node) {
|
|
||||||
String nodeKey = getNodeKey(node);
|
|
||||||
if (nodes.containsKey(nodeKey))
|
|
||||||
return;
|
|
||||||
|
|
||||||
JedisPool nodePool = new JedisPool(node.getHost(), node.getPort());
|
|
||||||
nodes.put(nodeKey, nodePool);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateNodeSlots(String nodeInfo, JedisPool nodePool) {
|
|
||||||
String[] nodeInfoArray = nodeInfo.split(" ");
|
|
||||||
if (nodeInfoArray.length > 7) {
|
|
||||||
for (int i = 8; i < nodeInfoArray.length; i++) {
|
|
||||||
processSlot(nodeInfoArray[i], nodePool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processSlot(String slot, JedisPool nodePool) {
|
|
||||||
if (slot.contains("-")) {
|
|
||||||
String[] slotRange = slot.split("-");
|
|
||||||
for (int i = Integer.valueOf(slotRange[0]); i <= Integer
|
|
||||||
.valueOf(slotRange[1]); i++) {
|
|
||||||
slots.put(i, nodePool);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
slots.put(Integer.valueOf(slot), nodePool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private HostAndPort getHostAndPortFromNodeLine(String nodeInfo,
|
|
||||||
Jedis currentConnection) {
|
|
||||||
String stringHostAndPort = nodeInfo.split(" ", 3)[1];
|
|
||||||
if (":0".equals(stringHostAndPort)) {
|
|
||||||
return new HostAndPort(currentConnection.getClient().getHost(),
|
|
||||||
currentConnection.getClient().getPort());
|
|
||||||
}
|
|
||||||
String[] arrayHostAndPort = stringHostAndPort.split(":");
|
|
||||||
return new HostAndPort(arrayHostAndPort[0],
|
|
||||||
Integer.valueOf(arrayHostAndPort[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assignSlotToNode(int slot, HostAndPort targetNode) {
|
public void assignSlotToNode(int slot, HostAndPort targetNode) {
|
||||||
JedisPool targetPool = nodes.get(getNodeKey(targetNode));
|
JedisPool targetPool = nodes.get(getNodeKey(targetNode));
|
||||||
|
|
||||||
if (targetPool != null) {
|
if (targetPool == null) {
|
||||||
slots.put(slot, targetPool);
|
|
||||||
} else {
|
|
||||||
setNodeIfNotExist(targetNode);
|
setNodeIfNotExist(targetNode);
|
||||||
|
|
||||||
targetPool = nodes.get(getNodeKey(targetNode));
|
targetPool = nodes.get(getNodeKey(targetNode));
|
||||||
|
}
|
||||||
|
slots.put(slot, targetPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assignSlotsToNode(List<Integer> targetSlots,
|
||||||
|
HostAndPort targetNode) {
|
||||||
|
JedisPool targetPool = nodes.get(getNodeKey(targetNode));
|
||||||
|
|
||||||
|
if (targetPool == null) {
|
||||||
|
setNodeIfNotExist(targetNode);
|
||||||
|
targetPool = nodes.get(getNodeKey(targetNode));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Integer slot : targetSlots) {
|
||||||
slots.put(slot, targetPool);
|
slots.put(slot, targetPool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,4 +115,13 @@ public abstract class JedisClusterConnectionHandler {
|
|||||||
protected String getNodeKey(Client client) {
|
protected String getNodeKey(Client client) {
|
||||||
return client.getHost() + ":" + client.getPort();
|
return client.getHost() + ":" + client.getPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setNodeIfNotExist(HostAndPort node) {
|
||||||
|
String nodeKey = getNodeKey(node);
|
||||||
|
if (nodes.containsKey(nodeKey))
|
||||||
|
return;
|
||||||
|
|
||||||
|
JedisPool nodePool = new JedisPool(node.getHost(), node.getPort());
|
||||||
|
nodes.put(nodeKey, nodePool);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ import java.util.Set;
|
|||||||
public interface JedisCommands {
|
public interface JedisCommands {
|
||||||
String set(String key, String value);
|
String set(String key, String value);
|
||||||
|
|
||||||
|
String set(String key, String value, String nxxx,
|
||||||
|
String expx, long time);
|
||||||
|
|
||||||
String get(String key);
|
String get(String key);
|
||||||
|
|
||||||
Boolean exists(String key);
|
Boolean exists(String key);
|
||||||
@@ -110,6 +113,8 @@ public interface JedisCommands {
|
|||||||
|
|
||||||
String srandmember(String key);
|
String srandmember(String key);
|
||||||
|
|
||||||
|
List<String> srandmember(String key, int count);
|
||||||
|
|
||||||
Long strlen(String key);
|
Long strlen(String key);
|
||||||
|
|
||||||
Long zadd(String key, double score, String member);
|
Long zadd(String key, double score, String member);
|
||||||
@@ -220,33 +225,14 @@ public interface JedisCommands {
|
|||||||
|
|
||||||
Long bitcount(final String key, long start, long end);
|
Long bitcount(final String key, long start, long end);
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
ScanResult<Map.Entry<String, String>> hscan(final String key, int cursor);
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
ScanResult<String> sscan(final String key, int cursor);
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
ScanResult<Tuple> zscan(final String key, int cursor);
|
|
||||||
|
|
||||||
ScanResult<Map.Entry<String, String>> hscan(final String key, final String cursor);
|
ScanResult<Map.Entry<String, String>> hscan(final String key, final String cursor);
|
||||||
|
|
||||||
ScanResult<String> sscan(final String key, final String cursor);
|
ScanResult<String> sscan(final String key, final String cursor);
|
||||||
|
|
||||||
ScanResult<Tuple> zscan(final String key, final String cursor);
|
ScanResult<Tuple> zscan(final String key, final String cursor);
|
||||||
|
|
||||||
|
Long pfadd(final String key, final String... elements);
|
||||||
|
|
||||||
|
long pfcount(final String key);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,13 @@ public class JedisPool extends Pool<Jedis> {
|
|||||||
database, clientName));
|
database, clientName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Jedis getResource() {
|
||||||
|
Jedis jedis = super.getResource();
|
||||||
|
jedis.setDataSource(this);
|
||||||
|
return jedis;
|
||||||
|
}
|
||||||
|
|
||||||
public void returnBrokenResource(final Jedis resource) {
|
public void returnBrokenResource(final Jedis resource) {
|
||||||
if (resource != null) {
|
if (resource != null) {
|
||||||
returnBrokenResourceObject(resource);
|
returnBrokenResourceObject(resource);
|
||||||
@@ -91,4 +98,12 @@ public class JedisPool extends Pool<Jedis> {
|
|||||||
returnResourceObject(resource);
|
returnResourceObject(resource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getNumActive() {
|
||||||
|
if (this.internalPool == null || this.internalPool.isClosed()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.internalPool.getNumActive();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,12 +162,6 @@ public abstract class JedisPubSub {
|
|||||||
|
|
||||||
/* Invalidate instance since this thread is no longer listening */
|
/* Invalidate instance since this thread is no longer listening */
|
||||||
this.client = null;
|
this.client = null;
|
||||||
|
|
||||||
/*
|
|
||||||
* Reset pipeline count because subscribe() calls would have increased
|
|
||||||
* it but nothing decremented it.
|
|
||||||
*/
|
|
||||||
client.resetPipelinedCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSubscribedChannels() {
|
public int getSubscribedChannels() {
|
||||||
|
|||||||
@@ -74,19 +74,6 @@ public class JedisSentinelPool extends Pool<Jedis> {
|
|||||||
initPool(master);
|
initPool(master);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void returnBrokenResource(final Jedis resource) {
|
|
||||||
if (resource != null) {
|
|
||||||
returnBrokenResourceObject(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void returnResource(final Jedis resource) {
|
|
||||||
if (resource != null) {
|
|
||||||
resource.resetState();
|
|
||||||
returnResourceObject(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private volatile HostAndPort currentHostMaster;
|
private volatile HostAndPort currentHostMaster;
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
@@ -175,6 +162,26 @@ public class JedisSentinelPool extends Pool<Jedis> {
|
|||||||
return new HostAndPort(host, port);
|
return new HostAndPort(host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Jedis getResource() {
|
||||||
|
Jedis jedis = super.getResource();
|
||||||
|
jedis.setDataSource(this);
|
||||||
|
return jedis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void returnBrokenResource(final Jedis resource) {
|
||||||
|
if (resource != null) {
|
||||||
|
returnBrokenResourceObject(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void returnResource(final Jedis resource) {
|
||||||
|
if (resource != null) {
|
||||||
|
resource.resetState();
|
||||||
|
returnResourceObject(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected class JedisPubSubAdapter extends JedisPubSub {
|
protected class JedisPubSubAdapter extends JedisPubSub {
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(String channel, String message) {
|
public void onMessage(String channel, String message) {
|
||||||
|
|||||||
@@ -69,4 +69,8 @@ public interface MultiKeyBinaryCommands {
|
|||||||
byte[] randomBinaryKey();
|
byte[] randomBinaryKey();
|
||||||
|
|
||||||
Long bitop(BitOP op, final byte[] destKey, byte[]... srcKeys);
|
Long bitop(BitOP op, final byte[] destKey, byte[]... srcKeys);
|
||||||
|
|
||||||
|
String pfmerge(final byte[] destkey, final byte[]... sourcekeys);
|
||||||
|
|
||||||
|
Long pfcount(byte[]... keys);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,4 +65,8 @@ public interface MultiKeyBinaryRedisPipeline {
|
|||||||
Response<byte[]> randomKeyBinary();
|
Response<byte[]> randomKeyBinary();
|
||||||
|
|
||||||
Response<Long> bitop(BitOP op, final byte[] destKey, byte[]... srcKeys);
|
Response<Long> bitop(BitOP op, final byte[] destKey, byte[]... srcKeys);
|
||||||
|
|
||||||
|
Response<String> pfmerge(final byte[] destkey, final byte[]... sourcekeys);
|
||||||
|
|
||||||
|
Response<Long> pfcount(final byte[] ... keys);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,13 +70,9 @@ public interface MultiKeyCommands {
|
|||||||
|
|
||||||
Long bitop(BitOP op, final String destKey, String... srcKeys);
|
Long bitop(BitOP op, final String destKey, String... srcKeys);
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
ScanResult<String> scan(int cursor);
|
|
||||||
|
|
||||||
ScanResult<String> scan(final String cursor);
|
ScanResult<String> scan(final String cursor);
|
||||||
|
|
||||||
|
String pfmerge(final String destkey, final String... sourcekeys);
|
||||||
|
|
||||||
|
long pfcount(final String...keys);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,4 +64,8 @@ public interface MultiKeyCommandsPipeline {
|
|||||||
Response<String> randomKey();
|
Response<String> randomKey();
|
||||||
|
|
||||||
Response<Long> bitop(BitOP op, final String destKey, String... srcKeys);
|
Response<Long> bitop(BitOP op, final String destKey, String... srcKeys);
|
||||||
|
|
||||||
|
Response<String> pfmerge(final String destkey, final String... sourcekeys);
|
||||||
|
|
||||||
|
Response<Long> pfcount(final String...keys);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -368,6 +368,11 @@ abstract class MultiKeyPipelineBase extends PipelineBase implements
|
|||||||
return getResponse(BuilderFactory.STRING);
|
return getResponse(BuilderFactory.STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Response<List<String>> time() {
|
||||||
|
client.time();
|
||||||
|
return getResponse(BuilderFactory.STRING_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
public Response<Long> dbSize() {
|
public Response<Long> dbSize() {
|
||||||
client.dbSize();
|
client.dbSize();
|
||||||
return getResponse(BuilderFactory.LONG);
|
return getResponse(BuilderFactory.LONG);
|
||||||
@@ -446,4 +451,28 @@ abstract class MultiKeyPipelineBase extends PipelineBase implements
|
|||||||
client.clusterSetSlotImporting(slot, nodeId);
|
client.clusterSetSlotImporting(slot, nodeId);
|
||||||
return getResponse(BuilderFactory.STRING);
|
return getResponse(BuilderFactory.STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response<String> pfmerge(byte[] destkey, byte[]... sourcekeys) {
|
||||||
|
client.pfmerge(destkey, sourcekeys);
|
||||||
|
return getResponse(BuilderFactory.STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response<String> pfmerge(String destkey, String... sourcekeys) {
|
||||||
|
client.pfmerge(destkey, sourcekeys);
|
||||||
|
return getResponse(BuilderFactory.STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response<Long> pfcount(String...keys) {
|
||||||
|
client.pfcount(keys);
|
||||||
|
return getResponse(BuilderFactory.LONG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response<Long> pfcount(final byte[] ... keys) {
|
||||||
|
client.pfcount(keys);
|
||||||
|
return getResponse(BuilderFactory.LONG);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,13 +69,25 @@ public class Pipeline extends MultiKeyPipelineBase {
|
|||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
if (isInMulti()) {
|
||||||
|
discard();
|
||||||
|
}
|
||||||
|
|
||||||
|
sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInMulti() {
|
||||||
|
return currentMulti != null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Syncronize pipeline by reading all responses. This operation close the
|
* Syncronize pipeline by reading all responses. This operation close the
|
||||||
* pipeline. In order to get return values from pipelined commands, capture
|
* pipeline. In order to get return values from pipelined commands, capture
|
||||||
* the different Response<?> of the commands you execute.
|
* the different Response<?> of the commands you execute.
|
||||||
*/
|
*/
|
||||||
public void sync() {
|
public void sync() {
|
||||||
List<Object> unformatted = client.getAll();
|
List<Object> unformatted = client.getMany(getPipelinedResponseLength());
|
||||||
for (Object o : unformatted) {
|
for (Object o : unformatted) {
|
||||||
generateResponse(o);
|
generateResponse(o);
|
||||||
}
|
}
|
||||||
@@ -90,7 +102,7 @@ public class Pipeline extends MultiKeyPipelineBase {
|
|||||||
* @return A list of all the responses in the order you executed them.
|
* @return A list of all the responses in the order you executed them.
|
||||||
*/
|
*/
|
||||||
public List<Object> syncAndReturnAll() {
|
public List<Object> syncAndReturnAll() {
|
||||||
List<Object> unformatted = client.getAll();
|
List<Object> unformatted = client.getMany(getPipelinedResponseLength());
|
||||||
List<Object> formatted = new ArrayList<Object>();
|
List<Object> formatted = new ArrayList<Object>();
|
||||||
|
|
||||||
for (Object o : unformatted) {
|
for (Object o : unformatted) {
|
||||||
@@ -104,12 +116,17 @@ public class Pipeline extends MultiKeyPipelineBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Response<String> discard() {
|
public Response<String> discard() {
|
||||||
|
if (currentMulti == null)
|
||||||
|
throw new JedisDataException("DISCARD without MULTI");
|
||||||
client.discard();
|
client.discard();
|
||||||
currentMulti = null;
|
currentMulti = null;
|
||||||
return getResponse(BuilderFactory.STRING);
|
return getResponse(BuilderFactory.STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response<List<Object>> exec() {
|
public Response<List<Object>> exec() {
|
||||||
|
if (currentMulti == null)
|
||||||
|
throw new JedisDataException("EXEC without MULTI");
|
||||||
|
|
||||||
client.exec();
|
client.exec();
|
||||||
Response<List<Object>> response = super.getResponse(currentMulti);
|
Response<List<Object>> response = super.getResponse(currentMulti);
|
||||||
currentMulti.setResponseDependency(response);
|
currentMulti.setResponseDependency(response);
|
||||||
@@ -118,6 +135,9 @@ public class Pipeline extends MultiKeyPipelineBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Response<String> multi() {
|
public Response<String> multi() {
|
||||||
|
if (currentMulti != null)
|
||||||
|
throw new JedisDataException("MULTI calls can not be nested");
|
||||||
|
|
||||||
client.multi();
|
client.multi();
|
||||||
Response<String> response = getResponse(BuilderFactory.STRING); // Expecting
|
Response<String> response = getResponse(BuilderFactory.STRING); // Expecting
|
||||||
// OK
|
// OK
|
||||||
|
|||||||
@@ -143,6 +143,24 @@ abstract class PipelineBase extends Queable implements BinaryRedisPipeline,
|
|||||||
return getResponse(BuilderFactory.BOOLEAN);
|
return getResponse(BuilderFactory.BOOLEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Response<Long> bitpos(final String key, final boolean value) {
|
||||||
|
return bitpos(key, value, new BitPosParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response<Long> bitpos(final String key, final boolean value, final BitPosParams params) {
|
||||||
|
getClient(key).bitpos(key, value, params);
|
||||||
|
return getResponse(BuilderFactory.LONG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response<Long> bitpos(final byte[] key, final boolean value) {
|
||||||
|
return bitpos(key, value, new BitPosParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response<Long> bitpos(final byte[] key, final boolean value, final BitPosParams params) {
|
||||||
|
getClient(key).bitpos(key, value, params);
|
||||||
|
return getResponse(BuilderFactory.LONG);
|
||||||
|
}
|
||||||
|
|
||||||
public Response<String> getrange(String key, long startOffset,
|
public Response<String> getrange(String key, long startOffset,
|
||||||
long endOffset) {
|
long endOffset) {
|
||||||
getClient(key).getrange(key, startOffset, endOffset);
|
getClient(key).getrange(key, startOffset, endOffset);
|
||||||
@@ -159,9 +177,9 @@ abstract class PipelineBase extends Queable implements BinaryRedisPipeline,
|
|||||||
return getResponse(BuilderFactory.BYTE_ARRAY);
|
return getResponse(BuilderFactory.BYTE_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response<Long> getrange(byte[] key, long startOffset, long endOffset) {
|
public Response<byte[]> getrange(byte[] key, long startOffset, long endOffset) {
|
||||||
getClient(key).getrange(key, startOffset, endOffset);
|
getClient(key).getrange(key, startOffset, endOffset);
|
||||||
return getResponse(BuilderFactory.LONG);
|
return getResponse(BuilderFactory.BYTE_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response<Long> hdel(String key, String... field) {
|
public Response<Long> hdel(String key, String... field) {
|
||||||
@@ -1130,12 +1148,12 @@ abstract class PipelineBase extends Queable implements BinaryRedisPipeline,
|
|||||||
return getResponse(BuilderFactory.LONG);
|
return getResponse(BuilderFactory.LONG);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response<Long> pexpire(String key, int milliseconds) {
|
public Response<Long> pexpire(String key, long milliseconds) {
|
||||||
getClient(key).pexpire(key, milliseconds);
|
getClient(key).pexpire(key, milliseconds);
|
||||||
return getResponse(BuilderFactory.LONG);
|
return getResponse(BuilderFactory.LONG);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response<Long> pexpire(byte[] key, int milliseconds) {
|
public Response<Long> pexpire(byte[] key, long milliseconds) {
|
||||||
getClient(key).pexpire(key, milliseconds);
|
getClient(key).pexpire(key, milliseconds);
|
||||||
return getResponse(BuilderFactory.LONG);
|
return getResponse(BuilderFactory.LONG);
|
||||||
}
|
}
|
||||||
@@ -1254,4 +1272,28 @@ abstract class PipelineBase extends Queable implements BinaryRedisPipeline,
|
|||||||
return getResponse(BuilderFactory.STRING);
|
return getResponse(BuilderFactory.STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response<Long> pfadd(byte[] key, byte[]... elements) {
|
||||||
|
getClient(key).pfadd(key, elements);
|
||||||
|
return getResponse(BuilderFactory.LONG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response<Long> pfcount(byte[] key) {
|
||||||
|
getClient(key).pfcount(key);
|
||||||
|
return getResponse(BuilderFactory.LONG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response<Long> pfadd(String key, String... elements) {
|
||||||
|
getClient(key).pfadd(key, elements);
|
||||||
|
return getResponse(BuilderFactory.LONG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response<Long> pfcount(String key) {
|
||||||
|
getClient(key).pfcount(key);
|
||||||
|
return getResponse(BuilderFactory.LONG);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,9 @@ package redis.clients.jedis;
|
|||||||
* @see https://github.com/xetorthio/jedis/pull/498
|
* @see https://github.com/xetorthio/jedis/pull/498
|
||||||
*/
|
*/
|
||||||
public abstract class PipelineBlock extends Pipeline {
|
public abstract class PipelineBlock extends Pipeline {
|
||||||
|
// For shadowing
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private Client client;
|
||||||
|
|
||||||
public abstract void execute();
|
public abstract void execute();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,16 @@ public final class Protocol {
|
|||||||
public static final String CLUSTER_SETSLOT_NODE = "node";
|
public static final String CLUSTER_SETSLOT_NODE = "node";
|
||||||
public static final String CLUSTER_SETSLOT_MIGRATING = "migrating";
|
public static final String CLUSTER_SETSLOT_MIGRATING = "migrating";
|
||||||
public static final String CLUSTER_SETSLOT_IMPORTING = "importing";
|
public static final String CLUSTER_SETSLOT_IMPORTING = "importing";
|
||||||
|
public static final String CLUSTER_SETSLOT_STABLE = "stable";
|
||||||
|
public static final String CLUSTER_FORGET = "forget";
|
||||||
|
public static final String CLUSTER_FLUSHSLOT = "flushslots";
|
||||||
|
public static final String CLUSTER_KEYSLOT = "keyslot";
|
||||||
|
public static final String CLUSTER_COUNTKEYINSLOT = "countkeysinslot";
|
||||||
|
public static final String CLUSTER_SAVECONFIG = "saveconfig";
|
||||||
|
public static final String CLUSTER_REPLICATE = "replicate";
|
||||||
|
public static final String CLUSTER_SLAVES = "slaves";
|
||||||
|
public static final String CLUSTER_FAILOVER = "failover";
|
||||||
|
public static final String CLUSTER_SLOTS = "slots";
|
||||||
public static final String PUBSUB_CHANNELS= "channels";
|
public static final String PUBSUB_CHANNELS= "channels";
|
||||||
public static final String PUBSUB_NUMSUB = "numsub";
|
public static final String PUBSUB_NUMSUB = "numsub";
|
||||||
public static final String PUBSUB_NUM_PAT = "numpat";
|
public static final String PUBSUB_NUM_PAT = "numpat";
|
||||||
@@ -208,7 +218,7 @@ public final class Protocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static enum Command {
|
public static enum Command {
|
||||||
PING, SET, GET, QUIT, EXISTS, DEL, 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, ZREMRANGEBYLEX, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, SHUTDOWN, INFO, MONITOR, SLAVEOF, CONFIG, STRLEN, SYNC, LPUSHX, PERSIST, RPUSHX, ECHO, LINSERT, DEBUG, BRPOPLPUSH, SETBIT, GETBIT, 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;
|
PING, SET, GET, QUIT, EXISTS, DEL, 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, 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;
|
||||||
|
|
||||||
public final byte[] raw;
|
public final byte[] raw;
|
||||||
|
|
||||||
|
|||||||
@@ -24,4 +24,11 @@ public class Queable {
|
|||||||
return lr;
|
return lr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean hasPipelinedResponse() {
|
||||||
|
return pipelinedResponses.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getPipelinedResponseLength() {
|
||||||
|
return pipelinedResponses.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,4 +197,8 @@ public interface RedisPipeline {
|
|||||||
Response<Long> bitcount(String key);
|
Response<Long> bitcount(String key);
|
||||||
|
|
||||||
Response<Long> bitcount(String key, long start, long end);
|
Response<Long> bitcount(String key, long start, long end);
|
||||||
|
|
||||||
|
Response<Long> pfadd(final String key, final String... elements);
|
||||||
|
|
||||||
|
Response<Long> pfcount(final String key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,15 +13,24 @@ import redis.clients.util.SafeEncoder;
|
|||||||
public class ScanParams {
|
public class ScanParams {
|
||||||
private List<byte[]> params = new ArrayList<byte[]>();
|
private List<byte[]> params = new ArrayList<byte[]>();
|
||||||
public final static String SCAN_POINTER_START = String.valueOf(0);
|
public final static String SCAN_POINTER_START = String.valueOf(0);
|
||||||
|
public final static byte[] SCAN_POINTER_START_BINARY = SafeEncoder.encode(SCAN_POINTER_START);
|
||||||
|
|
||||||
public void match(final String pattern) {
|
public ScanParams match(final byte[] pattern) {
|
||||||
params.add(MATCH.raw);
|
params.add(MATCH.raw);
|
||||||
params.add(SafeEncoder.encode(pattern));
|
params.add(pattern);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void count(final int count) {
|
public ScanParams match(final String pattern) {
|
||||||
|
params.add(MATCH.raw);
|
||||||
|
params.add(SafeEncoder.encode(pattern));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScanParams count(final int count) {
|
||||||
params.add(COUNT.raw);
|
params.add(COUNT.raw);
|
||||||
params.add(Protocol.toByteArray(count));
|
params.add(Protocol.toByteArray(count));
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<byte[]> getParams() {
|
public Collection<byte[]> getParams() {
|
||||||
|
|||||||
@@ -2,41 +2,26 @@ package redis.clients.jedis;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import redis.clients.util.SafeEncoder;
|
||||||
|
|
||||||
public class ScanResult<T> {
|
public class ScanResult<T> {
|
||||||
private String cursor;
|
private byte[] cursor;
|
||||||
private List<T> results;
|
private List<T> results;
|
||||||
|
|
||||||
@Deprecated
|
public ScanResult(String cursor, List<T> results) {
|
||||||
/**
|
this(SafeEncoder.encode(cursor), results);
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public ScanResult(int cursor, List<T> results) {
|
|
||||||
this.cursor = String.valueOf(cursor);
|
|
||||||
this.results = results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScanResult(String cursor, List<T> results) {
|
public ScanResult(byte[] cursor, List<T> results) {
|
||||||
this.cursor = cursor;
|
this.cursor = cursor;
|
||||||
this.results = results;
|
this.results = results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
public String getCursor() {
|
||||||
/**
|
return SafeEncoder.encode(cursor);
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
* @return int(currently), but will be changed to String, so be careful to prepare!
|
|
||||||
*/
|
|
||||||
public int getCursor() {
|
|
||||||
return Integer.parseInt(cursor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public byte[] getCursorAsBytes() {
|
||||||
* FIXME: This method should be changed to getCursor() on next major release
|
|
||||||
*/
|
|
||||||
public String getStringCursor() {
|
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,22 @@
|
|||||||
package redis.clients.jedis;
|
package redis.clients.jedis;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import redis.clients.jedis.BinaryClient.LIST_POSITION;
|
||||||
|
import redis.clients.util.Hashing;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import redis.clients.jedis.BinaryClient.LIST_POSITION;
|
import redis.clients.util.Pool;
|
||||||
import redis.clients.util.Hashing;
|
|
||||||
|
public class ShardedJedis extends BinaryShardedJedis implements JedisCommands,
|
||||||
|
Closeable {
|
||||||
|
|
||||||
|
protected Pool<ShardedJedis> dataSource = null;
|
||||||
|
|
||||||
public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
|
|
||||||
public ShardedJedis(List<JedisShardInfo> shards) {
|
public ShardedJedis(List<JedisShardInfo> shards) {
|
||||||
super(shards);
|
super(shards);
|
||||||
}
|
}
|
||||||
@@ -32,6 +39,13 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
|
|||||||
return j.set(key, value);
|
return j.set(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String set(String key, String value, String nxxx, String expx,
|
||||||
|
long time) {
|
||||||
|
Jedis j = getShard(key);
|
||||||
|
return j.set(key, value, nxxx, expx, time);
|
||||||
|
}
|
||||||
|
|
||||||
public String get(String key) {
|
public String get(String key) {
|
||||||
Jedis j = getShard(key);
|
Jedis j = getShard(key);
|
||||||
return j.get(key);
|
return j.get(key);
|
||||||
@@ -132,6 +146,11 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
|
|||||||
return j.incrBy(key, integer);
|
return j.incrBy(key, integer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Double incrByFloat(String key, double integer) {
|
||||||
|
Jedis j = getShard(key);
|
||||||
|
return j.incrByFloat(key, integer);
|
||||||
|
}
|
||||||
|
|
||||||
public Long incr(String key) {
|
public Long incr(String key) {
|
||||||
Jedis j = getShard(key);
|
Jedis j = getShard(key);
|
||||||
return j.incr(key);
|
return j.incr(key);
|
||||||
@@ -177,6 +196,11 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
|
|||||||
return j.hincrBy(key, field, value);
|
return j.hincrBy(key, field, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Double hincrByFloat(String key, String field, double value) {
|
||||||
|
Jedis j = getShard(key);
|
||||||
|
return j.hincrByFloat(key, field, value);
|
||||||
|
}
|
||||||
|
|
||||||
public Boolean hexists(String key, String field) {
|
public Boolean hexists(String key, String field) {
|
||||||
Jedis j = getShard(key);
|
Jedis j = getShard(key);
|
||||||
return j.hexists(key, field);
|
return j.hexists(key, field);
|
||||||
@@ -322,6 +346,12 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
|
|||||||
return j.srandmember(key);
|
return j.srandmember(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> srandmember(String key, int count) {
|
||||||
|
Jedis j = getShard(key);
|
||||||
|
return j.srandmember(key, count);
|
||||||
|
}
|
||||||
|
|
||||||
public Long zadd(String key, double score, String member) {
|
public Long zadd(String key, double score, String member) {
|
||||||
Jedis j = getShard(key);
|
Jedis j = getShard(key);
|
||||||
return j.zadd(key, score, member);
|
return j.zadd(key, score, member);
|
||||||
@@ -544,39 +574,6 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
|
|||||||
return j.bitcount(key, start, end);
|
return j.bitcount(key, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public ScanResult<Entry<String, String>> hscan(String key, int cursor) {
|
|
||||||
Jedis j = getShard(key);
|
|
||||||
return j.hscan(key, cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public ScanResult<String> sscan(String key, int cursor) {
|
|
||||||
Jedis j = getShard(key);
|
|
||||||
return j.sscan(key, cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
/**
|
|
||||||
* This method is deprecated due to bug (scan cursor should be unsigned long)
|
|
||||||
* And will be removed on next major release
|
|
||||||
* @see https://github.com/xetorthio/jedis/issues/531
|
|
||||||
*/
|
|
||||||
public ScanResult<Tuple> zscan(String key, int cursor) {
|
|
||||||
Jedis j = getShard(key);
|
|
||||||
return j.zscan(key, cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScanResult<Entry<String, String>> hscan(String key, final String cursor) {
|
public ScanResult<Entry<String, String>> hscan(String key, final String cursor) {
|
||||||
Jedis j = getShard(key);
|
Jedis j = getShard(key);
|
||||||
return j.hscan(key, cursor);
|
return j.hscan(key, cursor);
|
||||||
@@ -592,4 +589,48 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
|
|||||||
return j.zscan(key, cursor);
|
return j.zscan(key, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (dataSource != null) {
|
||||||
|
boolean broken = false;
|
||||||
|
|
||||||
|
for (Jedis jedis : getAllShards()) {
|
||||||
|
if (jedis.getClient().isBroken()) {
|
||||||
|
broken = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (broken) {
|
||||||
|
dataSource.returnBrokenResource(this);
|
||||||
|
} else {
|
||||||
|
this.resetState();
|
||||||
|
dataSource.returnResource(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDataSource(Pool<ShardedJedis> shardedJedisPool) {
|
||||||
|
this.dataSource = shardedJedisPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetState() {
|
||||||
|
for (Jedis jedis : getAllShards()) {
|
||||||
|
jedis.resetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long pfadd(String key, String... elements) {
|
||||||
|
Jedis j = getShard(key);
|
||||||
|
return j.pfadd(key, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long pfcount(String key) {
|
||||||
|
Jedis j = getShard(key);
|
||||||
|
return j.pfcount(key);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,28 @@ public class ShardedJedisPool extends Pool<ShardedJedis> {
|
|||||||
super(poolConfig, new ShardedJedisFactory(shards, algo, keyTagPattern));
|
super(poolConfig, new ShardedJedisFactory(shards, algo, keyTagPattern));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShardedJedis getResource() {
|
||||||
|
ShardedJedis jedis = super.getResource();
|
||||||
|
jedis.setDataSource(this);
|
||||||
|
return jedis;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void returnBrokenResource(final ShardedJedis resource) {
|
||||||
|
if (resource != null) {
|
||||||
|
returnBrokenResourceObject(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void returnResource(final ShardedJedis resource) {
|
||||||
|
if (resource != null) {
|
||||||
|
resource.resetState();
|
||||||
|
returnResourceObject(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PoolableObjectFactory custom impl.
|
* PoolableObjectFactory custom impl.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -31,9 +31,16 @@ public class Transaction extends MultiKeyPipelineBase {
|
|||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
if (inTransaction) {
|
||||||
|
discard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<Object> exec() {
|
public List<Object> exec() {
|
||||||
|
// Discard QUEUED or ERROR
|
||||||
|
client.getMany(getPipelinedResponseLength());
|
||||||
client.exec();
|
client.exec();
|
||||||
client.getAll(1); // Discard all but the last reply
|
|
||||||
|
|
||||||
List<Object> unformatted = client.getObjectMultiBulkReply();
|
List<Object> unformatted = client.getObjectMultiBulkReply();
|
||||||
if (unformatted == null) {
|
if (unformatted == null) {
|
||||||
@@ -51,8 +58,9 @@ public class Transaction extends MultiKeyPipelineBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<Response<?>> execGetResponse() {
|
public List<Response<?>> execGetResponse() {
|
||||||
|
// Discard QUEUED or ERROR
|
||||||
|
client.getMany(getPipelinedResponseLength());
|
||||||
client.exec();
|
client.exec();
|
||||||
client.getAll(1); // Discard all but the last reply
|
|
||||||
|
|
||||||
List<Object> unformatted = client.getObjectMultiBulkReply();
|
List<Object> unformatted = client.getObjectMultiBulkReply();
|
||||||
if (unformatted == null) {
|
if (unformatted == null) {
|
||||||
@@ -66,11 +74,15 @@ public class Transaction extends MultiKeyPipelineBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String discard() {
|
public String discard() {
|
||||||
|
client.getMany(getPipelinedResponseLength());
|
||||||
client.discard();
|
client.discard();
|
||||||
client.getAll(1); // Discard all but the last reply
|
|
||||||
inTransaction = false;
|
inTransaction = false;
|
||||||
clean();
|
clean();
|
||||||
return client.getStatusCodeReply();
|
return client.getStatusCodeReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setClient(Client client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,10 @@ import redis.clients.jedis.exceptions.JedisException;
|
|||||||
* @see https://github.com/xetorthio/jedis/pull/498
|
* @see https://github.com/xetorthio/jedis/pull/498
|
||||||
*/
|
*/
|
||||||
public abstract class TransactionBlock extends Transaction {
|
public abstract class TransactionBlock extends Transaction {
|
||||||
|
// For shadowing
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private Client client;
|
||||||
|
|
||||||
public TransactionBlock(Client client) {
|
public TransactionBlock(Client client) {
|
||||||
super(client);
|
super(client);
|
||||||
}
|
}
|
||||||
@@ -19,6 +23,6 @@ public abstract class TransactionBlock extends Transaction {
|
|||||||
public abstract void execute() throws JedisException;
|
public abstract void execute() throws JedisException;
|
||||||
|
|
||||||
public void setClient(Client client) {
|
public void setClient(Client client) {
|
||||||
this.client = client;
|
super.setClient(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,15 @@ public class ZParams {
|
|||||||
|
|
||||||
private List<byte[]> params = new ArrayList<byte[]>();
|
private List<byte[]> params = new ArrayList<byte[]>();
|
||||||
|
|
||||||
public ZParams weights(final int... weights) {
|
/**
|
||||||
|
* Set weights.
|
||||||
|
*
|
||||||
|
* @param weights
|
||||||
|
* weights.
|
||||||
|
*/
|
||||||
|
public ZParams weights(final double... weights) {
|
||||||
params.add(WEIGHTS.raw);
|
params.add(WEIGHTS.raw);
|
||||||
for (final int weight : weights) {
|
for (final double weight : weights) {
|
||||||
params.add(Protocol.toByteArray(weight));
|
params.add(Protocol.toByteArray(weight));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
48
src/main/java/redis/clients/util/ClusterNodeInformation.java
Normal file
48
src/main/java/redis/clients/util/ClusterNodeInformation.java
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package redis.clients.util;
|
||||||
|
|
||||||
|
import redis.clients.jedis.HostAndPort;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ClusterNodeInformation {
|
||||||
|
private HostAndPort node;
|
||||||
|
private List<Integer> availableSlots;
|
||||||
|
private List<Integer> slotsBeingImported;
|
||||||
|
private List<Integer> slotsBeingMigrated;
|
||||||
|
|
||||||
|
public ClusterNodeInformation(HostAndPort node) {
|
||||||
|
this.node = node;
|
||||||
|
this.availableSlots = new ArrayList<Integer>();
|
||||||
|
this.slotsBeingImported = new ArrayList<Integer>();
|
||||||
|
this.slotsBeingMigrated = new ArrayList<Integer>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAvailableSlot(int slot) {
|
||||||
|
availableSlots.add(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSlotBeingImported(int slot) {
|
||||||
|
slotsBeingImported.add(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSlotBeingMigrated(int slot) {
|
||||||
|
slotsBeingMigrated.add(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HostAndPort getNode() {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getAvailableSlots() {
|
||||||
|
return availableSlots;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getSlotsBeingImported() {
|
||||||
|
return slotsBeingImported;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getSlotsBeingMigrated() {
|
||||||
|
return slotsBeingMigrated;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package redis.clients.util;
|
||||||
|
|
||||||
|
import redis.clients.jedis.HostAndPort;
|
||||||
|
|
||||||
|
public class ClusterNodeInformationParser {
|
||||||
|
private static final String SLOT_IMPORT_IDENTIFIER = "-<-";
|
||||||
|
private static final String SLOT_IN_TRANSITION_IDENTIFIER = "[";
|
||||||
|
public static final int SLOT_INFORMATIONS_START_INDEX = 8;
|
||||||
|
public static final int HOST_AND_PORT_INDEX = 1;
|
||||||
|
|
||||||
|
public ClusterNodeInformation parse(String nodeInfo, HostAndPort current) {
|
||||||
|
String[] nodeInfoPartArray = nodeInfo.split(" ");
|
||||||
|
|
||||||
|
HostAndPort node = getHostAndPortFromNodeLine(nodeInfoPartArray,
|
||||||
|
current);
|
||||||
|
ClusterNodeInformation info = new ClusterNodeInformation(node);
|
||||||
|
|
||||||
|
if (nodeInfoPartArray.length >= SLOT_INFORMATIONS_START_INDEX) {
|
||||||
|
String[] slotInfoPartArray = extractSlotParts(nodeInfoPartArray);
|
||||||
|
fillSlotInformation(slotInfoPartArray, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] extractSlotParts(String[] nodeInfoPartArray) {
|
||||||
|
String[] slotInfoPartArray = new String[nodeInfoPartArray.length
|
||||||
|
- SLOT_INFORMATIONS_START_INDEX];
|
||||||
|
for (int i = SLOT_INFORMATIONS_START_INDEX; i < nodeInfoPartArray.length; i++) {
|
||||||
|
slotInfoPartArray[i - SLOT_INFORMATIONS_START_INDEX] = nodeInfoPartArray[i];
|
||||||
|
}
|
||||||
|
return slotInfoPartArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HostAndPort getHostAndPortFromNodeLine(String[] nodeInfoPartArray,
|
||||||
|
HostAndPort current) {
|
||||||
|
String stringHostAndPort = nodeInfoPartArray[HOST_AND_PORT_INDEX];
|
||||||
|
|
||||||
|
String[] arrayHostAndPort = stringHostAndPort.split(":");
|
||||||
|
return new HostAndPort(
|
||||||
|
arrayHostAndPort[0].isEmpty() ? current.getHost()
|
||||||
|
: arrayHostAndPort[0],
|
||||||
|
arrayHostAndPort[1].isEmpty() ? current.getPort() : Integer
|
||||||
|
.valueOf(arrayHostAndPort[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillSlotInformation(String[] slotInfoPartArray,
|
||||||
|
ClusterNodeInformation info) {
|
||||||
|
for (String slotRange : slotInfoPartArray) {
|
||||||
|
fillSlotInformationFromSlotRange(slotRange, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillSlotInformationFromSlotRange(String slotRange,
|
||||||
|
ClusterNodeInformation info) {
|
||||||
|
if (slotRange.startsWith(SLOT_IN_TRANSITION_IDENTIFIER)) {
|
||||||
|
// slot is in transition
|
||||||
|
int slot = Integer.parseInt(slotRange.substring(1).split("-")[0]);
|
||||||
|
|
||||||
|
if (slotRange.contains(SLOT_IMPORT_IDENTIFIER)) {
|
||||||
|
// import
|
||||||
|
info.addSlotBeingImported(slot);
|
||||||
|
} else {
|
||||||
|
// migrate (->-)
|
||||||
|
info.addSlotBeingMigrated(slot);
|
||||||
|
}
|
||||||
|
} else if (slotRange.contains("-")) {
|
||||||
|
// slot range
|
||||||
|
String[] slotRangePart = slotRange.split("-");
|
||||||
|
for (int slot = Integer.valueOf(slotRangePart[0]); slot <= Integer
|
||||||
|
.valueOf(slotRangePart[1]); slot++) {
|
||||||
|
info.addAvailableSlot(slot);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// single slot
|
||||||
|
info.addAvailableSlot(Integer.valueOf(slotRange));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -34,10 +34,10 @@ public final class RedisOutputStream extends FilterOutputStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void write(final byte b) throws IOException {
|
public void write(final byte b) throws IOException {
|
||||||
buf[count++] = b;
|
|
||||||
if (count == buf.length) {
|
if (count == buf.length) {
|
||||||
flushBuffer();
|
flushBuffer();
|
||||||
}
|
}
|
||||||
|
buf[count++] = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(final byte[] b) throws IOException {
|
public void write(final byte[] b) throws IOException {
|
||||||
@@ -63,10 +63,10 @@ public final class RedisOutputStream extends FilterOutputStream {
|
|||||||
final int size = in.length();
|
final int size = in.length();
|
||||||
|
|
||||||
for (int i = 0; i != size; ++i) {
|
for (int i = 0; i != size; ++i) {
|
||||||
buf[count++] = (byte) in.charAt(i);
|
|
||||||
if (count == buf.length) {
|
if (count == buf.length) {
|
||||||
flushBuffer();
|
flushBuffer();
|
||||||
}
|
}
|
||||||
|
buf[count++] = (byte) in.charAt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
writeCrLf();
|
writeCrLf();
|
||||||
@@ -111,19 +111,19 @@ public final class RedisOutputStream extends FilterOutputStream {
|
|||||||
char c = str.charAt(i);
|
char c = str.charAt(i);
|
||||||
if (!(c < 0x80))
|
if (!(c < 0x80))
|
||||||
break;
|
break;
|
||||||
buf[count++] = (byte) c;
|
|
||||||
if (count == buf.length) {
|
if (count == buf.length) {
|
||||||
flushBuffer();
|
flushBuffer();
|
||||||
}
|
}
|
||||||
|
buf[count++] = (byte) c;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; i < strLen; i++) {
|
for (; i < strLen; i++) {
|
||||||
char c = str.charAt(i);
|
char c = str.charAt(i);
|
||||||
if (c < 0x80) {
|
if (c < 0x80) {
|
||||||
buf[count++] = (byte) c;
|
|
||||||
if (count == buf.length) {
|
if (count == buf.length) {
|
||||||
flushBuffer();
|
flushBuffer();
|
||||||
}
|
}
|
||||||
|
buf[count++] = (byte) c;
|
||||||
} else if (c < 0x800) {
|
} else if (c < 0x800) {
|
||||||
if (2 >= buf.length - count) {
|
if (2 >= buf.length - count) {
|
||||||
flushBuffer();
|
flushBuffer();
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ public class HostAndPortUtil {
|
|||||||
clusterHostAndPortList.add(new HostAndPort("localhost", 7379));
|
clusterHostAndPortList.add(new HostAndPort("localhost", 7379));
|
||||||
clusterHostAndPortList.add(new HostAndPort("localhost", 7380));
|
clusterHostAndPortList.add(new HostAndPort("localhost", 7380));
|
||||||
clusterHostAndPortList.add(new HostAndPort("localhost", 7381));
|
clusterHostAndPortList.add(new HostAndPort("localhost", 7381));
|
||||||
|
clusterHostAndPortList.add(new HostAndPort("localhost", 7382));
|
||||||
|
clusterHostAndPortList.add(new HostAndPort("localhost", 7383));
|
||||||
|
clusterHostAndPortList.add(new HostAndPort("localhost", 7384));
|
||||||
|
clusterHostAndPortList.add(new HostAndPort("localhost", 7385));
|
||||||
|
|
||||||
String envRedisHosts = System.getProperty("redis-hosts");
|
String envRedisHosts = System.getProperty("redis-hosts");
|
||||||
String envSentinelHosts = System.getProperty("sentinel-hosts");
|
String envSentinelHosts = System.getProperty("sentinel-hosts");
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package redis.clients.jedis.tests;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import redis.clients.jedis.HostAndPort;
|
||||||
|
import redis.clients.util.ClusterNodeInformation;
|
||||||
|
import redis.clients.util.ClusterNodeInformationParser;
|
||||||
|
|
||||||
|
public class JedisClusterNodeInformationParserTest extends Assert {
|
||||||
|
private ClusterNodeInformationParser parser;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
parser = new ClusterNodeInformationParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseNodeMyself() {
|
||||||
|
String nodeInfo = "9b0d2ab38ee31482c95fdb2c7847a0d40e88d518 :7379 myself,master - 0 0 1 connected 0-5460";
|
||||||
|
HostAndPort current = new HostAndPort("localhost", 7379);
|
||||||
|
ClusterNodeInformation clusterNodeInfo = parser
|
||||||
|
.parse(nodeInfo, current);
|
||||||
|
assertEquals(clusterNodeInfo.getNode(), current);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseNormalState() {
|
||||||
|
String nodeInfo = "5f4a2236d00008fba7ac0dd24b95762b446767bd 192.168.0.3:7380 master - 0 1400598804016 2 connected 5461-10922";
|
||||||
|
HostAndPort current = new HostAndPort("localhost", 7379);
|
||||||
|
ClusterNodeInformation clusterNodeInfo = parser
|
||||||
|
.parse(nodeInfo, current);
|
||||||
|
assertNotEquals(clusterNodeInfo.getNode(), current);
|
||||||
|
assertEquals(clusterNodeInfo.getNode(), new HostAndPort("192.168.0.3",
|
||||||
|
7380));
|
||||||
|
|
||||||
|
for (int slot = 5461; slot <= 10922; slot++) {
|
||||||
|
assertTrue(clusterNodeInfo.getAvailableSlots().contains(slot));
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue(clusterNodeInfo.getSlotsBeingImported().isEmpty());
|
||||||
|
assertTrue(clusterNodeInfo.getSlotsBeingMigrated().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseSlotBeingMigrated() {
|
||||||
|
String nodeInfo = "5f4a2236d00008fba7ac0dd24b95762b446767bd :7379 myself,master - 0 0 1 connected 0-5459 [5460->-5f4a2236d00008fba7ac0dd24b95762b446767bd] [5461-<-5f4a2236d00008fba7ac0dd24b95762b446767bd]";
|
||||||
|
HostAndPort current = new HostAndPort("localhost", 7379);
|
||||||
|
ClusterNodeInformation clusterNodeInfo = parser
|
||||||
|
.parse(nodeInfo, current);
|
||||||
|
assertEquals(clusterNodeInfo.getNode(), current);
|
||||||
|
|
||||||
|
for (int slot = 0; slot <= 5459; slot++) {
|
||||||
|
assertTrue(clusterNodeInfo.getAvailableSlots().contains(slot));
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(1, clusterNodeInfo.getSlotsBeingMigrated().size());
|
||||||
|
assertTrue(clusterNodeInfo.getSlotsBeingMigrated().contains(5460));
|
||||||
|
assertEquals(1, clusterNodeInfo.getSlotsBeingImported().size());
|
||||||
|
assertTrue(clusterNodeInfo.getSlotsBeingImported().contains(5461));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
package redis.clients.jedis.tests;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import redis.clients.jedis.HostAndPort;
|
||||||
|
import redis.clients.jedis.Jedis;
|
||||||
|
import redis.clients.jedis.JedisCluster;
|
||||||
|
import redis.clients.jedis.exceptions.JedisDataException;
|
||||||
|
import redis.clients.jedis.exceptions.JedisException;
|
||||||
|
import redis.clients.jedis.tests.utils.JedisClusterTestUtil;
|
||||||
|
|
||||||
|
public class JedisClusterReplicateTest {
|
||||||
|
private static Jedis node5;
|
||||||
|
private static Jedis node6;
|
||||||
|
|
||||||
|
private HostAndPort nodeInfo5 = HostAndPortUtil.getClusterServers().get(4);
|
||||||
|
private HostAndPort nodeInfo6 = HostAndPortUtil.getClusterServers().get(5);
|
||||||
|
|
||||||
|
private static int TIMEOUT = 15000; // cluster-node-timeout * 3
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws InterruptedException {
|
||||||
|
node5 = new Jedis(nodeInfo5.getHost(), nodeInfo5.getPort(), TIMEOUT);
|
||||||
|
node5.connect();
|
||||||
|
node5.flushAll();
|
||||||
|
|
||||||
|
node6 = new Jedis(nodeInfo6.getHost(), nodeInfo6.getPort(), TIMEOUT);
|
||||||
|
node6.connect();
|
||||||
|
// cannot flushall - it will be slave
|
||||||
|
|
||||||
|
// ---- configure cluster
|
||||||
|
|
||||||
|
// add nodes to cluster
|
||||||
|
node5.clusterMeet("127.0.0.1", nodeInfo6.getPort());
|
||||||
|
|
||||||
|
JedisClusterTestUtil.assertNodeIsKnown(node5, JedisClusterTestUtil.getNodeId(node6.clusterNodes()), 1000);
|
||||||
|
JedisClusterTestUtil.assertNodeIsKnown(node6, JedisClusterTestUtil.getNodeId(node5.clusterNodes()), 1000);
|
||||||
|
|
||||||
|
// split available slots across the three nodes
|
||||||
|
int[] node5Slots = new int[JedisCluster.HASHSLOTS];
|
||||||
|
for (int i = 0 ; i < JedisCluster.HASHSLOTS; i++) {
|
||||||
|
node5Slots[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
node5.clusterAddSlots(node5Slots);
|
||||||
|
|
||||||
|
JedisClusterTestUtil.waitForClusterReady(node5);
|
||||||
|
|
||||||
|
// replicate full 1on1
|
||||||
|
node6.clusterReplicate(JedisClusterTestUtil.getNodeId(node5
|
||||||
|
.clusterNodes()));
|
||||||
|
|
||||||
|
Map<Jedis, Jedis> replMap = new HashMap<Jedis, Jedis>();
|
||||||
|
replMap.put(node5, node6);
|
||||||
|
|
||||||
|
waitForReplicateReady(replMap, TIMEOUT);
|
||||||
|
JedisClusterTestUtil.waitForClusterReady(node5, node6);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void waitForReplicateReady(Map<Jedis, Jedis> replMap, int timeoutMs) {
|
||||||
|
int interval = 100;
|
||||||
|
|
||||||
|
for (int timeout = 0; timeout <= timeoutMs; timeout += interval) {
|
||||||
|
for (Entry<Jedis, Jedis> entry : replMap.entrySet()) {
|
||||||
|
Jedis master = entry.getKey();
|
||||||
|
Jedis slave = entry.getValue();
|
||||||
|
|
||||||
|
String masterNodeId = JedisClusterTestUtil.getNodeId(master
|
||||||
|
.clusterNodes());
|
||||||
|
String slaveNodeId = JedisClusterTestUtil.getNodeId(slave
|
||||||
|
.clusterNodes());
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<String> slaves = master.clusterSlaves(masterNodeId);
|
||||||
|
|
||||||
|
if (slaves.size() > 0 && slaves.get(0).contains(slaveNodeId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (JedisDataException e) {
|
||||||
|
if (!e.getMessage().startsWith("ERR The specified node is not a master"))
|
||||||
|
throw e;
|
||||||
|
|
||||||
|
// retry...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(interval);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new JedisException("there seems to replication error");
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws InterruptedException {
|
||||||
|
// clear all slots
|
||||||
|
int[] slotsToDelete = new int[JedisCluster.HASHSLOTS];
|
||||||
|
for (int i = 0; i < JedisCluster.HASHSLOTS; i++) {
|
||||||
|
slotsToDelete[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
node5.clusterDelSlots(slotsToDelete);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClusterReplicate() {
|
||||||
|
// we're already replicate 1on1
|
||||||
|
List<String> slaveInfos = node5.clusterSlaves(JedisClusterTestUtil
|
||||||
|
.getNodeId(node5.clusterNodes()));
|
||||||
|
assertEquals(1, slaveInfos.size());
|
||||||
|
assertTrue(slaveInfos.get(0).contains(
|
||||||
|
JedisClusterTestUtil.getNodeId(node6.clusterNodes())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClusterFailover() throws InterruptedException {
|
||||||
|
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
|
||||||
|
jedisClusterNode.add(new HostAndPort(nodeInfo5.getHost(), nodeInfo5.getPort()));
|
||||||
|
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
||||||
|
|
||||||
|
jc.set("51", "foo");
|
||||||
|
// node5 is responsible of taking care of slot for key "51" (7186)
|
||||||
|
|
||||||
|
node6.clusterFailover();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// wait for failover
|
||||||
|
Map<Jedis, Jedis> replMap = new HashMap<Jedis, Jedis>();
|
||||||
|
replMap.put(node6, node5);
|
||||||
|
waitForReplicateReady(replMap, TIMEOUT);
|
||||||
|
JedisClusterTestUtil.waitForClusterReady(node5, node6);
|
||||||
|
|
||||||
|
List<String> slaveInfos = node6.clusterSlaves(JedisClusterTestUtil
|
||||||
|
.getNodeId(node6.clusterNodes()));
|
||||||
|
assertEquals(1, slaveInfos.size());
|
||||||
|
assertTrue(slaveInfos.get(0).contains(
|
||||||
|
JedisClusterTestUtil.getNodeId(node5.clusterNodes())));
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// rollback
|
||||||
|
node5.clusterFailover();
|
||||||
|
|
||||||
|
Map<Jedis, Jedis> replMap = new HashMap<Jedis, Jedis>();
|
||||||
|
replMap.put(node5, node6);
|
||||||
|
waitForReplicateReady(replMap, TIMEOUT);
|
||||||
|
JedisClusterTestUtil.waitForClusterReady(node5, node6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
package redis.clients.jedis.tests;
|
package redis.clients.jedis.tests;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@@ -12,20 +15,26 @@ import org.junit.Test;
|
|||||||
import redis.clients.jedis.HostAndPort;
|
import redis.clients.jedis.HostAndPort;
|
||||||
import redis.clients.jedis.Jedis;
|
import redis.clients.jedis.Jedis;
|
||||||
import redis.clients.jedis.JedisCluster;
|
import redis.clients.jedis.JedisCluster;
|
||||||
|
import redis.clients.jedis.JedisPool;
|
||||||
import redis.clients.jedis.exceptions.JedisAskDataException;
|
import redis.clients.jedis.exceptions.JedisAskDataException;
|
||||||
import redis.clients.jedis.exceptions.JedisClusterException;
|
import redis.clients.jedis.exceptions.JedisClusterException;
|
||||||
import redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException;
|
import redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException;
|
||||||
|
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||||
|
import redis.clients.jedis.exceptions.JedisException;
|
||||||
import redis.clients.jedis.exceptions.JedisMovedDataException;
|
import redis.clients.jedis.exceptions.JedisMovedDataException;
|
||||||
|
import redis.clients.jedis.tests.utils.JedisClusterTestUtil;
|
||||||
import redis.clients.util.JedisClusterCRC16;
|
import redis.clients.util.JedisClusterCRC16;
|
||||||
|
|
||||||
public class JedisClusterTest extends Assert {
|
public class JedisClusterTest extends Assert {
|
||||||
private Jedis node1;
|
private static Jedis node1;
|
||||||
private static Jedis node2;
|
private static Jedis node2;
|
||||||
private static Jedis node3;
|
private static Jedis node3;
|
||||||
|
private static Jedis node4;
|
||||||
|
|
||||||
private HostAndPort nodeInfo1 = HostAndPortUtil.getClusterServers().get(0);
|
private HostAndPort nodeInfo1 = HostAndPortUtil.getClusterServers().get(0);
|
||||||
private HostAndPort nodeInfo2 = HostAndPortUtil.getClusterServers().get(1);
|
private HostAndPort nodeInfo2 = HostAndPortUtil.getClusterServers().get(1);
|
||||||
private HostAndPort nodeInfo3 = HostAndPortUtil.getClusterServers().get(2);
|
private HostAndPort nodeInfo3 = HostAndPortUtil.getClusterServers().get(2);
|
||||||
|
private HostAndPort nodeInfo4 = HostAndPortUtil.getClusterServers().get(3);
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws InterruptedException {
|
public void setUp() throws InterruptedException {
|
||||||
@@ -41,6 +50,10 @@ public class JedisClusterTest extends Assert {
|
|||||||
node3.connect();
|
node3.connect();
|
||||||
node3.flushAll();
|
node3.flushAll();
|
||||||
|
|
||||||
|
node4 = new Jedis(nodeInfo4.getHost(), nodeInfo4.getPort());
|
||||||
|
node4.connect();
|
||||||
|
node4.flushAll();
|
||||||
|
|
||||||
// ---- configure cluster
|
// ---- configure cluster
|
||||||
|
|
||||||
// add nodes to cluster
|
// add nodes to cluster
|
||||||
@@ -66,29 +79,53 @@ public class JedisClusterTest extends Assert {
|
|||||||
node2.clusterAddSlots(node2Slots);
|
node2.clusterAddSlots(node2Slots);
|
||||||
node3.clusterAddSlots(node3Slots);
|
node3.clusterAddSlots(node3Slots);
|
||||||
|
|
||||||
waitForClusterReady();
|
JedisClusterTestUtil.waitForClusterReady(node1, node2, node3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void cleanUp() {
|
public static void cleanUp() {
|
||||||
int slotTest = JedisClusterCRC16.getSlot("test");
|
int slotTest = JedisClusterCRC16.getSlot("test");
|
||||||
int slot51 = JedisClusterCRC16.getSlot("51");
|
int slot51 = JedisClusterCRC16.getSlot("51");
|
||||||
String node3Id = getNodeId(node3.clusterNodes());
|
|
||||||
|
String node1Id = JedisClusterTestUtil.getNodeId(node1.clusterNodes());
|
||||||
|
String node2Id = JedisClusterTestUtil.getNodeId(node2.clusterNodes());
|
||||||
|
String node3Id = JedisClusterTestUtil.getNodeId(node3.clusterNodes());
|
||||||
node2.clusterSetSlotNode(slotTest, node3Id);
|
node2.clusterSetSlotNode(slotTest, node3Id);
|
||||||
node2.clusterSetSlotNode(slot51, node3Id);
|
node2.clusterSetSlotNode(slot51, node3Id);
|
||||||
node2.clusterDelSlots(slotTest, slot51);
|
node2.clusterDelSlots(slotTest, slot51);
|
||||||
|
|
||||||
|
// forget about all nodes
|
||||||
|
node1.clusterForget(node2Id);
|
||||||
|
node1.clusterForget(node3Id);
|
||||||
|
node2.clusterForget(node1Id);
|
||||||
|
node2.clusterForget(node3Id);
|
||||||
|
node3.clusterForget(node1Id);
|
||||||
|
node3.clusterForget(node2Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() {
|
public void tearDown() throws InterruptedException {
|
||||||
// clear all slots
|
// clear all slots
|
||||||
int[] slotsToDelete = new int[JedisCluster.HASHSLOTS];
|
int[] slotsToDelete = new int[JedisCluster.HASHSLOTS];
|
||||||
for (int i = 0; i < JedisCluster.HASHSLOTS; i++) {
|
for (int i = 0; i < JedisCluster.HASHSLOTS; i++) {
|
||||||
slotsToDelete[i] = i;
|
slotsToDelete[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
node1.clusterDelSlots(slotsToDelete);
|
node1.clusterDelSlots(slotsToDelete);
|
||||||
node2.clusterDelSlots(slotsToDelete);
|
node2.clusterDelSlots(slotsToDelete);
|
||||||
node3.clusterDelSlots(slotsToDelete);
|
node3.clusterDelSlots(slotsToDelete);
|
||||||
|
|
||||||
|
clearAnyInconsistentMigration(node1);
|
||||||
|
clearAnyInconsistentMigration(node2);
|
||||||
|
clearAnyInconsistentMigration(node3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearAnyInconsistentMigration(Jedis node) {
|
||||||
|
// FIXME: it's too slow... apply pipeline if possible
|
||||||
|
List<Integer> slots = getInconsistentSlots(node.clusterNodes());
|
||||||
|
for (Integer slot : slots) {
|
||||||
|
node.clusterSetSlotStable(slot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = JedisMovedDataException.class)
|
@Test(expected = JedisMovedDataException.class)
|
||||||
@@ -112,7 +149,7 @@ public class JedisClusterTest extends Assert {
|
|||||||
@Test(expected = JedisAskDataException.class)
|
@Test(expected = JedisAskDataException.class)
|
||||||
public void testThrowAskException() {
|
public void testThrowAskException() {
|
||||||
int keySlot = JedisClusterCRC16.getSlot("test");
|
int keySlot = JedisClusterCRC16.getSlot("test");
|
||||||
String node3Id = getNodeId(node3.clusterNodes());
|
String node3Id = JedisClusterTestUtil.getNodeId(node3.clusterNodes());
|
||||||
node2.clusterSetSlotMigrating(keySlot, node3Id);
|
node2.clusterSetSlotMigrating(keySlot, node3Id);
|
||||||
node2.get("test");
|
node2.get("test");
|
||||||
}
|
}
|
||||||
@@ -122,7 +159,7 @@ public class JedisClusterTest extends Assert {
|
|||||||
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
|
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
|
||||||
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
|
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
|
||||||
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
||||||
assertEquals(jc.getClusterNodes().size(), 3);
|
assertEquals(3, jc.getClusterNodes().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -146,7 +183,7 @@ public class JedisClusterTest extends Assert {
|
|||||||
node3.clusterDelSlots(slot51);
|
node3.clusterDelSlots(slot51);
|
||||||
node3.clusterAddSlots(slot51);
|
node3.clusterAddSlots(slot51);
|
||||||
|
|
||||||
waitForClusterReady();
|
JedisClusterTestUtil.waitForClusterReady(node1, node2, node3);
|
||||||
jc.set("51", "foo");
|
jc.set("51", "foo");
|
||||||
assertEquals("foo", jc.get("51"));
|
assertEquals("foo", jc.get("51"));
|
||||||
}
|
}
|
||||||
@@ -157,8 +194,8 @@ public class JedisClusterTest extends Assert {
|
|||||||
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
|
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
|
||||||
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
||||||
int slot51 = JedisClusterCRC16.getSlot("51");
|
int slot51 = JedisClusterCRC16.getSlot("51");
|
||||||
node3.clusterSetSlotImporting(slot51, getNodeId(node2.clusterNodes()));
|
node3.clusterSetSlotImporting(slot51, JedisClusterTestUtil.getNodeId(node2.clusterNodes()));
|
||||||
node2.clusterSetSlotMigrating(slot51, getNodeId(node3.clusterNodes()));
|
node2.clusterSetSlotMigrating(slot51, JedisClusterTestUtil.getNodeId(node3.clusterNodes()));
|
||||||
jc.set("51", "foo");
|
jc.set("51", "foo");
|
||||||
assertEquals("foo", jc.get("51"));
|
assertEquals("foo", jc.get("51"));
|
||||||
}
|
}
|
||||||
@@ -178,7 +215,7 @@ public class JedisClusterTest extends Assert {
|
|||||||
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
||||||
int slot51 = JedisClusterCRC16.getSlot("51");
|
int slot51 = JedisClusterCRC16.getSlot("51");
|
||||||
// This will cause an infinite redirection loop
|
// This will cause an infinite redirection loop
|
||||||
node2.clusterSetSlotMigrating(slot51, getNodeId(node3.clusterNodes()));
|
node2.clusterSetSlotMigrating(slot51, JedisClusterTestUtil.getNodeId(node3.clusterNodes()));
|
||||||
jc.set("51", "foo");
|
jc.set("51", "foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,25 +227,208 @@ public class JedisClusterTest extends Assert {
|
|||||||
assertEquals(JedisClusterCRC16.getSlot("foo{bar}{zap}"), JedisClusterCRC16.getSlot("bar"));
|
assertEquals(JedisClusterCRC16.getSlot("foo{bar}{zap}"), JedisClusterCRC16.getSlot("bar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getNodeId(String infoOutput) {
|
@Test
|
||||||
for (String infoLine : infoOutput.split("\n")) {
|
public void testClusterForgetNode() throws InterruptedException {
|
||||||
if (infoLine.contains("myself")) {
|
// at first, join node4 to cluster
|
||||||
return infoLine.split(" ")[0];
|
node1.clusterMeet("127.0.0.1", nodeInfo4.getPort());
|
||||||
}
|
|
||||||
}
|
String node7Id = JedisClusterTestUtil.getNodeId(node4.clusterNodes());
|
||||||
return "";
|
|
||||||
|
JedisClusterTestUtil.assertNodeIsKnown(node3, node7Id, 1000);
|
||||||
|
JedisClusterTestUtil.assertNodeIsKnown(node2, node7Id, 1000);
|
||||||
|
JedisClusterTestUtil.assertNodeIsKnown(node1, node7Id, 1000);
|
||||||
|
|
||||||
|
assertNodeHandshakeEnded(node3, 1000);
|
||||||
|
assertNodeHandshakeEnded(node2, 1000);
|
||||||
|
assertNodeHandshakeEnded(node1, 1000);
|
||||||
|
|
||||||
|
assertEquals(4, node1.clusterNodes().split("\n").length);
|
||||||
|
assertEquals(4, node2.clusterNodes().split("\n").length);
|
||||||
|
assertEquals(4, node3.clusterNodes().split("\n").length);
|
||||||
|
|
||||||
|
// do cluster forget
|
||||||
|
node1.clusterForget(node7Id);
|
||||||
|
node2.clusterForget(node7Id);
|
||||||
|
node3.clusterForget(node7Id);
|
||||||
|
|
||||||
|
JedisClusterTestUtil.assertNodeIsUnknown(node1, node7Id, 1000);
|
||||||
|
JedisClusterTestUtil.assertNodeIsUnknown(node2, node7Id, 1000);
|
||||||
|
JedisClusterTestUtil.assertNodeIsUnknown(node3, node7Id, 1000);
|
||||||
|
|
||||||
|
assertEquals(3, node1.clusterNodes().split("\n").length);
|
||||||
|
assertEquals(3, node2.clusterNodes().split("\n").length);
|
||||||
|
assertEquals(3, node3.clusterNodes().split("\n").length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void waitForClusterReady() throws InterruptedException {
|
@Test
|
||||||
boolean clusterOk = false;
|
public void testClusterFlushSlots() {
|
||||||
while (!clusterOk) {
|
String slotRange = getNodeServingSlotRange(node1.clusterNodes());
|
||||||
if (node1.clusterInfo().split("\n")[0].contains("ok")
|
assertNotNull(slotRange);
|
||||||
&& node2.clusterInfo().split("\n")[0].contains("ok")
|
|
||||||
&& node3.clusterInfo().split("\n")[0].contains("ok")) {
|
try {
|
||||||
clusterOk = true;
|
node1.clusterFlushSlots();
|
||||||
|
assertNull(getNodeServingSlotRange(node1.clusterNodes()));
|
||||||
|
} finally {
|
||||||
|
// rollback
|
||||||
|
String[] rangeInfo = slotRange.split("-");
|
||||||
|
int lower = Integer.parseInt(rangeInfo[0]);
|
||||||
|
int upper = Integer.parseInt(rangeInfo[1]);
|
||||||
|
|
||||||
|
int[] node1Slots = new int[upper - lower + 1];
|
||||||
|
for (int i = 0 ; lower <= upper ; ) {
|
||||||
|
node1Slots[i++] = lower++;
|
||||||
}
|
}
|
||||||
Thread.sleep(50);
|
node1.clusterAddSlots(node1Slots);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClusterKeySlot() {
|
||||||
|
// It assumes JedisClusterCRC16 is correctly implemented
|
||||||
|
assertEquals(node1.clusterKeySlot("foo{bar}zap}").intValue(), JedisClusterCRC16.getSlot("foo{bar}zap"));
|
||||||
|
assertEquals(node1.clusterKeySlot("{user1000}.following").intValue(), JedisClusterCRC16.getSlot("{user1000}.following"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClusterCountKeysInSlot() {
|
||||||
|
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
|
||||||
|
jedisClusterNode.add(new HostAndPort(nodeInfo1.getHost(), nodeInfo1.getPort()));
|
||||||
|
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
||||||
|
|
||||||
|
for (int index = 0 ; index < 5 ; index++) {
|
||||||
|
jc.set("foo{bar}" + index, "hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
int slot = JedisClusterCRC16.getSlot("foo{bar}");
|
||||||
|
assertEquals(5, node1.clusterCountKeysInSlot(slot).intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStableSlotWhenMigratingNodeOrImportingNodeIsNotSpecified() throws InterruptedException {
|
||||||
|
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
|
||||||
|
jedisClusterNode.add(new HostAndPort(nodeInfo1.getHost(), nodeInfo1.getPort()));
|
||||||
|
JedisCluster jc = new JedisCluster(jedisClusterNode);
|
||||||
|
|
||||||
|
int slot51 = JedisClusterCRC16.getSlot("51");
|
||||||
|
jc.set("51", "foo");
|
||||||
|
// node2 is responsible of taking care of slot51 (7186)
|
||||||
|
|
||||||
|
node3.clusterSetSlotImporting(slot51, JedisClusterTestUtil.getNodeId(node2.clusterNodes()));
|
||||||
|
assertEquals("foo", jc.get("51"));
|
||||||
|
node3.clusterSetSlotStable(slot51);
|
||||||
|
assertEquals("foo", jc.get("51"));
|
||||||
|
|
||||||
|
node2.clusterSetSlotMigrating(slot51, JedisClusterTestUtil.getNodeId(node3.clusterNodes()));
|
||||||
|
//assertEquals("foo", jc.get("51")); // it leads Max Redirections
|
||||||
|
node2.clusterSetSlotStable(slot51);
|
||||||
|
assertEquals("foo", jc.get("51"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloseable() {
|
||||||
|
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
|
||||||
|
jedisClusterNode.add(new HostAndPort(nodeInfo1.getHost(), nodeInfo1.getPort()));
|
||||||
|
|
||||||
|
JedisCluster jc = null;
|
||||||
|
try {
|
||||||
|
jc = new JedisCluster(jedisClusterNode);
|
||||||
|
jc.set("51", "foo");
|
||||||
|
} finally {
|
||||||
|
if (jc != null) {
|
||||||
|
jc.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<JedisPool> poolIterator = jc.getClusterNodes().values().iterator();
|
||||||
|
while (poolIterator.hasNext()) {
|
||||||
|
JedisPool pool = poolIterator.next();
|
||||||
|
try {
|
||||||
|
pool.getResource();
|
||||||
|
fail("JedisCluster's internal pools should be already destroyed");
|
||||||
|
} catch (JedisConnectionException e) {
|
||||||
|
// ok to go...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getNodeServingSlotRange(String infoOutput) {
|
||||||
|
// f4f3dc4befda352a4e0beccf29f5e8828438705d 127.0.0.1:7380 master - 0 1394372400827 0 connected 5461-10922
|
||||||
|
for (String infoLine : infoOutput.split("\n")) {
|
||||||
|
if (infoLine.contains("myself")) {
|
||||||
|
try {
|
||||||
|
return infoLine.split(" ")[8];
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Integer> getInconsistentSlots(String infoOuput) {
|
||||||
|
for (String infoLine : infoOuput.split("\n")) {
|
||||||
|
if (infoLine.contains("myself")) {
|
||||||
|
return getSlotsBeingMigrated(infoLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Integer> getSlotsBeingMigrated(String infoLine) {
|
||||||
|
List<Integer> inconsistentSlots = new ArrayList<Integer>();
|
||||||
|
|
||||||
|
String[] splitted = infoLine.split(" ");
|
||||||
|
|
||||||
|
if (splitted.length > 8) {
|
||||||
|
for (int index = 8 ; index < splitted.length ; index++) {
|
||||||
|
String info = splitted[index];
|
||||||
|
Integer slot = getSlotFromMigrationInfo(info);
|
||||||
|
if (slot != null) {
|
||||||
|
inconsistentSlots.add(slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return inconsistentSlots;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer getSlotFromMigrationInfo(String info) {
|
||||||
|
if (info.startsWith("[")) {
|
||||||
|
if (info.contains("-<-")) {
|
||||||
|
return Integer.parseInt(info.split("-<-")[0].substring(1));
|
||||||
|
} else if (info.contains("->-")) {
|
||||||
|
return Integer.parseInt(info.split("->-")[0].substring(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertNodeHandshakeEnded(Jedis node, int timeoutMs) {
|
||||||
|
int sleepInterval = 100;
|
||||||
|
for (int sleepTime = 0 ; sleepTime <= timeoutMs ; sleepTime += sleepInterval) {
|
||||||
|
boolean isHandshaking = isAnyNodeHandshaking(node);
|
||||||
|
if (!isHandshaking)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(sleepInterval);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new JedisException("Node handshaking is not ended");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAnyNodeHandshaking(Jedis node) {
|
||||||
|
String infoOutput = node.clusterNodes();
|
||||||
|
for (String infoLine : infoOutput.split("\n")) {
|
||||||
|
if (infoLine.contains("handshake")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,18 +187,48 @@ public class JedisPoolTest extends Assert {
|
|||||||
2000, "foobared");
|
2000, "foobared");
|
||||||
|
|
||||||
Jedis jedis = pool.getResource();
|
Jedis jedis = pool.getResource();
|
||||||
jedis.set("hello", "jedis");
|
try {
|
||||||
Transaction t = jedis.multi();
|
jedis.set("hello", "jedis");
|
||||||
t.set("hello", "world");
|
Transaction t = jedis.multi();
|
||||||
pool.returnResource(jedis);
|
t.set("hello", "world");
|
||||||
|
} finally {
|
||||||
|
jedis.close();
|
||||||
|
}
|
||||||
|
|
||||||
Jedis jedis2 = pool.getResource();
|
Jedis jedis2 = pool.getResource();
|
||||||
assertTrue(jedis == jedis2);
|
try {
|
||||||
assertEquals("jedis", jedis2.get("hello"));
|
assertTrue(jedis == jedis2);
|
||||||
pool.returnResource(jedis2);
|
assertEquals("jedis", jedis2.get("hello"));
|
||||||
|
} finally {
|
||||||
|
jedis2.close();
|
||||||
|
}
|
||||||
|
|
||||||
pool.destroy();
|
pool.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkResourceIsCloseable() {
|
||||||
|
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||||
|
config.setMaxTotal(1);
|
||||||
|
config.setBlockWhenExhausted(false);
|
||||||
|
JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort(),
|
||||||
|
2000, "foobared");
|
||||||
|
|
||||||
|
Jedis jedis = pool.getResource();
|
||||||
|
try {
|
||||||
|
jedis.set("hello", "jedis");
|
||||||
|
} finally {
|
||||||
|
jedis.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
Jedis jedis2 = pool.getResource();
|
||||||
|
try {
|
||||||
|
assertEquals(jedis, jedis2);
|
||||||
|
} finally {
|
||||||
|
jedis2.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void returnNullObjectShouldNotFail() {
|
public void returnNullObjectShouldNotFail() {
|
||||||
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
|
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
|
||||||
@@ -208,4 +238,40 @@ public class JedisPoolTest extends Assert {
|
|||||||
pool.returnResource(null);
|
pool.returnResource(null);
|
||||||
pool.returnResourceObject(null);
|
pool.returnResourceObject(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getNumActiveIsNegativeWhenPoolIsClosed() {
|
||||||
|
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
|
||||||
|
hnp.getPort(), 2000, "foobared", 0, "my_shiny_client_name");
|
||||||
|
|
||||||
|
pool.destroy();
|
||||||
|
assertTrue(pool.getNumActive() < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getNumActiveReturnsTheCorrectNumber() {
|
||||||
|
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
|
||||||
|
hnp.getPort(), 2000);
|
||||||
|
Jedis jedis = pool.getResource();
|
||||||
|
jedis.auth("foobared");
|
||||||
|
jedis.set("foo", "bar");
|
||||||
|
assertEquals("bar", jedis.get("foo"));
|
||||||
|
|
||||||
|
assertEquals(1, pool.getNumActive());
|
||||||
|
|
||||||
|
Jedis jedis2 = pool.getResource();
|
||||||
|
jedis.auth("foobared");
|
||||||
|
jedis.set("foo", "bar");
|
||||||
|
|
||||||
|
assertEquals(2, pool.getNumActive());
|
||||||
|
|
||||||
|
pool.returnResource(jedis);
|
||||||
|
assertEquals(1, pool.getNumActive());
|
||||||
|
|
||||||
|
pool.returnResource(jedis2);
|
||||||
|
|
||||||
|
assertEquals(0, pool.getNumActive());
|
||||||
|
|
||||||
|
pool.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,29 @@ public class JedisSentinelPoolTest extends JedisTestBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkResourceIsCloseable() {
|
||||||
|
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||||
|
config.setMaxTotal(1);
|
||||||
|
config.setBlockWhenExhausted(false);
|
||||||
|
JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels,
|
||||||
|
config, 1000, "foobared", 2);
|
||||||
|
|
||||||
|
Jedis jedis = pool.getResource();
|
||||||
|
try {
|
||||||
|
jedis.set("hello", "jedis");
|
||||||
|
} finally {
|
||||||
|
jedis.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
Jedis jedis2 = pool.getResource();
|
||||||
|
try {
|
||||||
|
assertEquals(jedis, jedis2);
|
||||||
|
} finally {
|
||||||
|
jedis2.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void returnResourceWithNullResource() {
|
public void returnResourceWithNullResource() {
|
||||||
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ public class PipeliningTest extends Assert {
|
|||||||
jedis.hset("hash", "foo", "bar");
|
jedis.hset("hash", "foo", "bar");
|
||||||
jedis.zadd("zset", 1, "foo");
|
jedis.zadd("zset", 1, "foo");
|
||||||
jedis.sadd("set", "foo");
|
jedis.sadd("set", "foo");
|
||||||
|
jedis.setrange("setrange", 0, "0123456789");
|
||||||
|
byte[] bytesForSetRange = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
|
jedis.setrange("setrangebytes".getBytes(), 0, bytesForSetRange);
|
||||||
|
|
||||||
Pipeline p = jedis.pipelined();
|
Pipeline p = jedis.pipelined();
|
||||||
Response<String> string = p.get("string");
|
Response<String> string = p.get("string");
|
||||||
@@ -68,8 +71,10 @@ public class PipeliningTest extends Assert {
|
|||||||
p.sadd("set", "foo");
|
p.sadd("set", "foo");
|
||||||
Response<Set<String>> smembers = p.smembers("set");
|
Response<Set<String>> smembers = p.smembers("set");
|
||||||
Response<Set<Tuple>> zrangeWithScores = p.zrangeWithScores("zset", 0,
|
Response<Set<Tuple>> zrangeWithScores = p.zrangeWithScores("zset", 0,
|
||||||
-1);
|
-1);
|
||||||
p.sync();
|
Response<String> getrange = p.getrange("setrange", 1, 3);
|
||||||
|
Response<byte[]> getrangeBytes = p.getrange("setrangebytes".getBytes(), 6, 8);
|
||||||
|
p.sync();
|
||||||
|
|
||||||
assertEquals("foo", string.get());
|
assertEquals("foo", string.get());
|
||||||
assertEquals("foo", list.get());
|
assertEquals("foo", list.get());
|
||||||
@@ -83,6 +88,9 @@ public class PipeliningTest extends Assert {
|
|||||||
assertNotNull(hgetAll.get().get("foo"));
|
assertNotNull(hgetAll.get().get("foo"));
|
||||||
assertEquals(1, smembers.get().size());
|
assertEquals(1, smembers.get().size());
|
||||||
assertEquals(1, zrangeWithScores.get().size());
|
assertEquals(1, zrangeWithScores.get().size());
|
||||||
|
assertEquals("123", getrange.get());
|
||||||
|
byte[] expectedGetRangeBytes = {6, 7, 8};
|
||||||
|
assertArrayEquals(expectedGetRangeBytes, getrangeBytes.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -272,6 +280,26 @@ public class PipeliningTest extends Assert {
|
|||||||
assertEquals("world", r3.get());
|
assertEquals("world", r3.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = JedisDataException.class)
|
||||||
|
public void pipelineExecShoudThrowJedisDataExceptionWhenNotInMulti() {
|
||||||
|
Pipeline pipeline = jedis.pipelined();
|
||||||
|
pipeline.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = JedisDataException.class)
|
||||||
|
public void pipelineDiscardShoudThrowJedisDataExceptionWhenNotInMulti() {
|
||||||
|
Pipeline pipeline = jedis.pipelined();
|
||||||
|
pipeline.discard();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = JedisDataException.class)
|
||||||
|
public void pipelineMultiShoudThrowJedisDataExceptionWhenAlreadyInMulti() {
|
||||||
|
Pipeline pipeline = jedis.pipelined();
|
||||||
|
pipeline.multi();
|
||||||
|
pipeline.set("foo", "3");
|
||||||
|
pipeline.multi();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDiscardInPipeline() {
|
public void testDiscardInPipeline() {
|
||||||
Pipeline pipeline = jedis.pipelined();
|
Pipeline pipeline = jedis.pipelined();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.io.BufferedInputStream;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.io.PipedInputStream;
|
import java.io.PipedInputStream;
|
||||||
import java.io.PipedOutputStream;
|
import java.io.PipedOutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -39,6 +40,28 @@ public class ProtocolTest extends JedisTestBase {
|
|||||||
assertEquals(expectedCommand, sb.toString());
|
assertEquals(expectedCommand, sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected=IOException.class)
|
||||||
|
public void writeOverflow() throws IOException {
|
||||||
|
RedisOutputStream ros = new RedisOutputStream(new OutputStream() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
throw new IOException("thrown exception");
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ros.write(new byte[8191]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ros.write((byte)'*');
|
||||||
|
} catch (IOException ioe) {}
|
||||||
|
|
||||||
|
|
||||||
|
ros.write((byte)'*');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void bulkReply() {
|
public void bulkReply() {
|
||||||
InputStream is = new ByteArrayInputStream("$6\r\nfoobar\r\n".getBytes());
|
InputStream is = new ByteArrayInputStream("$6\r\nfoobar\r\n".getBytes());
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import redis.clients.jedis.HostAndPort;
|
|||||||
import redis.clients.jedis.Jedis;
|
import redis.clients.jedis.Jedis;
|
||||||
import redis.clients.jedis.JedisShardInfo;
|
import redis.clients.jedis.JedisShardInfo;
|
||||||
import redis.clients.jedis.ShardedJedis;
|
import redis.clients.jedis.ShardedJedis;
|
||||||
|
import redis.clients.jedis.ShardedJedisPipeline;
|
||||||
import redis.clients.jedis.ShardedJedisPool;
|
import redis.clients.jedis.ShardedJedisPool;
|
||||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||||
|
|
||||||
@@ -233,4 +234,69 @@ public class ShardedJedisPoolTest extends Assert {
|
|||||||
assertEquals("PONG", jedis.ping());
|
assertEquals("PONG", jedis.ping());
|
||||||
assertEquals("bar", jedis.get("foo"));
|
assertEquals("bar", jedis.get("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void returnResourceShouldResetState() throws URISyntaxException {
|
||||||
|
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||||
|
config.setMaxTotal(1);
|
||||||
|
config.setBlockWhenExhausted(false);
|
||||||
|
|
||||||
|
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
|
||||||
|
shards.add(new JedisShardInfo(new URI(
|
||||||
|
"redis://:foobared@localhost:6380")));
|
||||||
|
shards.add(new JedisShardInfo(new URI(
|
||||||
|
"redis://:foobared@localhost:6379")));
|
||||||
|
|
||||||
|
ShardedJedisPool pool = new ShardedJedisPool(config, shards);
|
||||||
|
|
||||||
|
ShardedJedis jedis = pool.getResource();
|
||||||
|
jedis.set("pipelined", String.valueOf(0));
|
||||||
|
jedis.set("pipelined2", String.valueOf(0));
|
||||||
|
|
||||||
|
ShardedJedisPipeline pipeline = jedis.pipelined();
|
||||||
|
|
||||||
|
pipeline.incr("pipelined");
|
||||||
|
pipeline.incr("pipelined2");
|
||||||
|
|
||||||
|
jedis.resetState();
|
||||||
|
|
||||||
|
pipeline = jedis.pipelined();
|
||||||
|
pipeline.incr("pipelined");
|
||||||
|
pipeline.incr("pipelined2");
|
||||||
|
List<Object> results = pipeline.syncAndReturnAll();
|
||||||
|
|
||||||
|
assertEquals(2, results.size());
|
||||||
|
pool.returnResource(jedis);
|
||||||
|
pool.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkResourceIsCloseable() throws URISyntaxException {
|
||||||
|
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||||
|
config.setMaxTotal(1);
|
||||||
|
config.setBlockWhenExhausted(false);
|
||||||
|
|
||||||
|
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
|
||||||
|
shards.add(new JedisShardInfo(new URI(
|
||||||
|
"redis://:foobared@localhost:6380")));
|
||||||
|
shards.add(new JedisShardInfo(new URI(
|
||||||
|
"redis://:foobared@localhost:6379")));
|
||||||
|
|
||||||
|
ShardedJedisPool pool = new ShardedJedisPool(config, shards);
|
||||||
|
|
||||||
|
ShardedJedis jedis = pool.getResource();
|
||||||
|
try {
|
||||||
|
jedis.set("hello", "jedis");
|
||||||
|
} finally {
|
||||||
|
jedis.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShardedJedis jedis2 = pool.getResource();
|
||||||
|
try {
|
||||||
|
assertEquals(jedis, jedis2);
|
||||||
|
} finally {
|
||||||
|
jedis2.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,4 +302,25 @@ public class ShardedJedisTest extends Assert {
|
|||||||
assertEquals(jedisShardInfo.getName(), jedisShardInfo2.getName());
|
assertEquals(jedisShardInfo.getName(), jedisShardInfo2.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkCloseable() {
|
||||||
|
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
|
||||||
|
shards.add(new JedisShardInfo(redis1.getHost(), redis1.getPort()));
|
||||||
|
shards.add(new JedisShardInfo(redis2.getHost(), redis2.getPort()));
|
||||||
|
shards.get(0).setPassword("foobared");
|
||||||
|
shards.get(1).setPassword("foobared");
|
||||||
|
|
||||||
|
ShardedJedis jedisShard = new ShardedJedis(shards);
|
||||||
|
try {
|
||||||
|
jedisShard.set("shard_closeable", "true");
|
||||||
|
} finally {
|
||||||
|
jedisShard.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Jedis jedis : jedisShard.getAllShards()) {
|
||||||
|
assertTrue(!jedis.isConnected());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@ import redis.clients.jedis.ScanResult;
|
|||||||
import redis.clients.jedis.exceptions.JedisDataException;
|
import redis.clients.jedis.exceptions.JedisDataException;
|
||||||
import redis.clients.util.SafeEncoder;
|
import redis.clients.util.SafeEncoder;
|
||||||
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
|
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
|
||||||
|
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START_BINARY;
|
||||||
|
|
||||||
public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
|
public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
|
||||||
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
||||||
@@ -474,9 +475,16 @@ public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
|
|||||||
long status = jedis.pexpire("foo", 10000);
|
long status = jedis.pexpire("foo", 10000);
|
||||||
assertEquals(0, status);
|
assertEquals(0, status);
|
||||||
|
|
||||||
jedis.set("foo", "bar");
|
jedis.set("foo1", "bar1");
|
||||||
status = jedis.pexpire("foo", 10000);
|
status = jedis.pexpire("foo1", 10000);
|
||||||
assertEquals(1, status);
|
assertEquals(1, status);
|
||||||
|
|
||||||
|
jedis.set("foo2", "bar2");
|
||||||
|
status = jedis.pexpire("foo2", 200000000000L);
|
||||||
|
assertEquals(1, status);
|
||||||
|
|
||||||
|
long pttl = jedis.pttl("foo2");
|
||||||
|
assertTrue(pttl > 100000000000L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -513,8 +521,14 @@ public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
|
|||||||
|
|
||||||
ScanResult<String> result = jedis.scan(SCAN_POINTER_START);
|
ScanResult<String> result = jedis.scan(SCAN_POINTER_START);
|
||||||
|
|
||||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
assertEquals(SCAN_POINTER_START, result.getCursor());
|
||||||
assertFalse(result.getResult().isEmpty());
|
assertFalse(result.getResult().isEmpty());
|
||||||
|
|
||||||
|
// binary
|
||||||
|
ScanResult<byte[]> bResult = jedis.scan(SCAN_POINTER_START_BINARY);
|
||||||
|
|
||||||
|
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||||
|
assertFalse(bResult.getResult().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -527,8 +541,21 @@ public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
|
|||||||
jedis.set("aa", "aa");
|
jedis.set("aa", "aa");
|
||||||
ScanResult<String> result = jedis.scan(SCAN_POINTER_START, params);
|
ScanResult<String> result = jedis.scan(SCAN_POINTER_START, params);
|
||||||
|
|
||||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
assertEquals(SCAN_POINTER_START, result.getCursor());
|
||||||
assertFalse(result.getResult().isEmpty());
|
assertFalse(result.getResult().isEmpty());
|
||||||
|
|
||||||
|
// binary
|
||||||
|
params = new ScanParams();
|
||||||
|
params.match(bfoostar);
|
||||||
|
|
||||||
|
jedis.set(bfoo1, bbar);
|
||||||
|
jedis.set(bfoo2, bbar);
|
||||||
|
jedis.set(bfoo3, bbar);
|
||||||
|
|
||||||
|
ScanResult<byte[]> bResult = jedis.scan(SCAN_POINTER_START_BINARY, params);
|
||||||
|
|
||||||
|
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||||
|
assertFalse(bResult.getResult().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -543,5 +570,17 @@ public class AllKindOfValuesCommandsTest extends JedisCommandTestBase {
|
|||||||
ScanResult<String> result = jedis.scan(SCAN_POINTER_START, params);
|
ScanResult<String> result = jedis.scan(SCAN_POINTER_START, params);
|
||||||
|
|
||||||
assertFalse(result.getResult().isEmpty());
|
assertFalse(result.getResult().isEmpty());
|
||||||
|
|
||||||
|
// binary
|
||||||
|
params = new ScanParams();
|
||||||
|
params.count(2);
|
||||||
|
|
||||||
|
jedis.set(bfoo1, bbar);
|
||||||
|
jedis.set(bfoo2, bbar);
|
||||||
|
jedis.set(bfoo3, bbar);
|
||||||
|
|
||||||
|
ScanResult<byte[]> bResult = jedis.scan(SCAN_POINTER_START_BINARY, params);
|
||||||
|
|
||||||
|
assertFalse(bResult.getResult().isEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package redis.clients.jedis.tests.commands;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import redis.clients.jedis.BitOP;
|
import redis.clients.jedis.BitOP;
|
||||||
|
import redis.clients.jedis.BitPosParams;
|
||||||
|
import redis.clients.jedis.Protocol;
|
||||||
|
|
||||||
public class BitCommandsTest extends JedisCommandTestBase {
|
public class BitCommandsTest extends JedisCommandTestBase {
|
||||||
@Test
|
@Test
|
||||||
@@ -20,6 +22,111 @@ public class BitCommandsTest extends JedisCommandTestBase {
|
|||||||
assertTrue(bbit);
|
assertTrue(bbit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bitpos() {
|
||||||
|
String foo = "foo";
|
||||||
|
|
||||||
|
jedis.set(foo, String.valueOf(0));
|
||||||
|
|
||||||
|
jedis.setbit(foo, 3, true);
|
||||||
|
jedis.setbit(foo, 7, true);
|
||||||
|
jedis.setbit(foo, 13, true);
|
||||||
|
jedis.setbit(foo, 39, true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* byte: 0 1 2 3 4
|
||||||
|
* bit: 00010001 / 00000100 / 00000000 / 00000000 / 00000001
|
||||||
|
*/
|
||||||
|
long offset = jedis.bitpos(foo, true);
|
||||||
|
assertEquals(2, offset);
|
||||||
|
offset = jedis.bitpos(foo, false);
|
||||||
|
assertEquals(0, offset);
|
||||||
|
|
||||||
|
offset = jedis.bitpos(foo, true, new BitPosParams(1));
|
||||||
|
assertEquals(13, offset);
|
||||||
|
offset = jedis.bitpos(foo, false, new BitPosParams(1));
|
||||||
|
assertEquals(8, offset);
|
||||||
|
|
||||||
|
offset = jedis.bitpos(foo, true, new BitPosParams(2, 3));
|
||||||
|
assertEquals(-1, offset);
|
||||||
|
offset = jedis.bitpos(foo, false, new BitPosParams(2, 3));
|
||||||
|
assertEquals(16, offset);
|
||||||
|
|
||||||
|
offset = jedis.bitpos(foo, true, new BitPosParams(3, 4));
|
||||||
|
assertEquals(39, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bitposBinary() {
|
||||||
|
// binary
|
||||||
|
byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
||||||
|
|
||||||
|
jedis.set(bfoo, Protocol.toByteArray(0));
|
||||||
|
|
||||||
|
jedis.setbit(bfoo, 3, true);
|
||||||
|
jedis.setbit(bfoo, 7, true);
|
||||||
|
jedis.setbit(bfoo, 13, true);
|
||||||
|
jedis.setbit(bfoo, 39, true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* byte: 0 1 2 3 4
|
||||||
|
* bit: 00010001 / 00000100 / 00000000 / 00000000 / 00000001
|
||||||
|
*/
|
||||||
|
long offset = jedis.bitpos(bfoo, true);
|
||||||
|
assertEquals(2, offset);
|
||||||
|
offset = jedis.bitpos(bfoo, false);
|
||||||
|
assertEquals(0, offset);
|
||||||
|
|
||||||
|
offset = jedis.bitpos(bfoo, true, new BitPosParams(1));
|
||||||
|
assertEquals(13, offset);
|
||||||
|
offset = jedis.bitpos(bfoo, false, new BitPosParams(1));
|
||||||
|
assertEquals(8, offset);
|
||||||
|
|
||||||
|
offset = jedis.bitpos(bfoo, true, new BitPosParams(2, 3));
|
||||||
|
assertEquals(-1, offset);
|
||||||
|
offset = jedis.bitpos(bfoo, false, new BitPosParams(2, 3));
|
||||||
|
assertEquals(16, offset);
|
||||||
|
|
||||||
|
offset = jedis.bitpos(bfoo, true, new BitPosParams(3, 4));
|
||||||
|
assertEquals(39, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bitposWithNoMatchingBitExist() {
|
||||||
|
String foo = "foo";
|
||||||
|
|
||||||
|
jedis.set(foo, String.valueOf(0));
|
||||||
|
for (int idx = 0; idx < 8; idx++) {
|
||||||
|
jedis.setbit(foo, idx, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* byte: 0
|
||||||
|
* bit: 11111111
|
||||||
|
*/
|
||||||
|
long offset = jedis.bitpos(foo, false);
|
||||||
|
// offset should be last index + 1
|
||||||
|
assertEquals(8, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bitposWithNoMatchingBitExistWithinRange() {
|
||||||
|
String foo = "foo";
|
||||||
|
|
||||||
|
jedis.set(foo, String.valueOf(0));
|
||||||
|
for (int idx = 0; idx < 8 * 5; idx++) {
|
||||||
|
jedis.setbit(foo, idx, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* byte: 0 1 2 3 4
|
||||||
|
* bit: 11111111 / 11111111 / 11111111 / 11111111 / 11111111
|
||||||
|
*/
|
||||||
|
long offset = jedis.bitpos(foo, false, new BitPosParams(2, 3));
|
||||||
|
// offset should be -1
|
||||||
|
assertEquals(-1, offset);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setAndgetrange() {
|
public void setAndgetrange() {
|
||||||
jedis.set("key1", "Hello World");
|
jedis.set("key1", "Hello World");
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ public class ClusterCommandsTest extends JedisTestBase {
|
|||||||
node1.clusterDelSlots(1, 2, 3, 4, 5, 500);
|
node1.clusterDelSlots(1, 2, 3, 4, 5, 500);
|
||||||
node1.clusterSetSlotNode(5000, node1Id);
|
node1.clusterSetSlotNode(5000, node1Id);
|
||||||
node1.clusterDelSlots(5000, 10000);
|
node1.clusterDelSlots(5000, 10000);
|
||||||
|
node1.clusterDelSlots(3000, 3001, 3002);
|
||||||
|
node2.clusterDelSlots(4000, 4001, 4002);
|
||||||
node1.clusterAddSlots(6000);
|
node1.clusterAddSlots(6000);
|
||||||
node1.clusterDelSlots(6000);
|
node1.clusterDelSlots(6000);
|
||||||
waitForGossip();
|
waitForGossip();
|
||||||
@@ -135,4 +137,33 @@ public class ClusterCommandsTest extends JedisTestBase {
|
|||||||
assertEquals("OK", status);
|
assertEquals("OK", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clusterSlots() {
|
||||||
|
// please see cluster slot output format from below commit
|
||||||
|
// @see:
|
||||||
|
// https://github.com/antirez/redis/commit/e14829de3025ffb0d3294e5e5a1553afd9f10b60
|
||||||
|
String status = node1.clusterAddSlots(3000, 3001, 3002);
|
||||||
|
assertEquals("OK", status);
|
||||||
|
status = node2.clusterAddSlots(4000, 4001, 4002);
|
||||||
|
assertEquals("OK", status);
|
||||||
|
|
||||||
|
List<Object> slots = node1.clusterSlots();
|
||||||
|
assertNotNull(slots);
|
||||||
|
assertTrue(slots.size() > 0);
|
||||||
|
|
||||||
|
for (Object slotInfoObj : slots) {
|
||||||
|
List<Object> slotInfo = (List<Object>) slotInfoObj;
|
||||||
|
assertNotNull(slots);
|
||||||
|
assertTrue(slots.size() >= 2);
|
||||||
|
|
||||||
|
assertTrue(slotInfo.get(0) instanceof Long);
|
||||||
|
assertTrue(slotInfo.get(1) instanceof Long);
|
||||||
|
|
||||||
|
if (slots.size() > 2) {
|
||||||
|
// assigned slots
|
||||||
|
assertTrue(slotInfo.get(2) instanceof List);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -9,16 +9,24 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import redis.clients.jedis.Pipeline;
|
||||||
|
import redis.clients.jedis.Response;
|
||||||
import redis.clients.jedis.ScanParams;
|
import redis.clients.jedis.ScanParams;
|
||||||
import redis.clients.jedis.ScanResult;
|
import redis.clients.jedis.ScanResult;
|
||||||
|
|
||||||
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
|
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
|
||||||
|
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START_BINARY;
|
||||||
|
|
||||||
public class HashesCommandsTest extends JedisCommandTestBase {
|
public class HashesCommandsTest extends JedisCommandTestBase {
|
||||||
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
||||||
final byte[] bbar = { 0x05, 0x06, 0x07, 0x08 };
|
final byte[] bbar = { 0x05, 0x06, 0x07, 0x08 };
|
||||||
final byte[] bcar = { 0x09, 0x0A, 0x0B, 0x0C };
|
final byte[] bcar = { 0x09, 0x0A, 0x0B, 0x0C };
|
||||||
|
|
||||||
|
final byte[] bbar1 = { 0x05, 0x06, 0x07, 0x08, 0x0A };
|
||||||
|
final byte[] bbar2 = { 0x05, 0x06, 0x07, 0x08, 0x0B };
|
||||||
|
final byte[] bbar3 = { 0x05, 0x06, 0x07, 0x08, 0x0C };
|
||||||
|
final byte[] bbarstar = { 0x05, 0x06, 0x07, 0x08, '*' };
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hset() {
|
public void hset() {
|
||||||
long status = jedis.hset("foo", "bar", "car");
|
long status = jedis.hset("foo", "bar", "car");
|
||||||
@@ -147,6 +155,25 @@ public class HashesCommandsTest extends JedisCommandTestBase {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hincrByFloat() {
|
||||||
|
Double value = jedis.hincrByFloat("foo", "bar", 1.5d);
|
||||||
|
assertEquals((Double) 1.5d, value);
|
||||||
|
value = jedis.hincrByFloat("foo", "bar", -1.5d);
|
||||||
|
assertEquals((Double) 0d, value);
|
||||||
|
value = jedis.hincrByFloat("foo", "bar", -10.7d);
|
||||||
|
assertEquals(Double.compare(-10.7d, value), 0);
|
||||||
|
|
||||||
|
// Binary
|
||||||
|
double bvalue = jedis.hincrByFloat(bfoo, bbar, 1.5d);
|
||||||
|
assertEquals(Double.compare(1.5d, bvalue), 0);
|
||||||
|
bvalue = jedis.hincrByFloat(bfoo, bbar, -1.5d);
|
||||||
|
assertEquals(Double.compare(0d, bvalue), 0);
|
||||||
|
bvalue = jedis.hincrByFloat(bfoo, bbar, -10.7d);
|
||||||
|
assertEquals(Double.compare(-10.7d, value), 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hexists() {
|
public void hexists() {
|
||||||
Map<String, String> hash = new HashMap<String, String>();
|
Map<String, String> hash = new HashMap<String, String>();
|
||||||
@@ -291,6 +318,22 @@ public class HashesCommandsTest extends JedisCommandTestBase {
|
|||||||
assertArrayEquals(bbar, bhash.get(bcar));
|
assertArrayEquals(bbar, bhash.get(bcar));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hgetAllPipeline() {
|
||||||
|
Map<byte[], byte[]> bh = new HashMap<byte[], byte[]>();
|
||||||
|
bh.put(bbar, bcar);
|
||||||
|
bh.put(bcar, bbar);
|
||||||
|
jedis.hmset(bfoo, bh);
|
||||||
|
Pipeline pipeline = jedis.pipelined();
|
||||||
|
Response<Map<byte[], byte[]>> bhashResponse = pipeline.hgetAll(bfoo);
|
||||||
|
pipeline.sync();
|
||||||
|
Map<byte[], byte[]> bhash = bhashResponse.get();
|
||||||
|
|
||||||
|
assertEquals(2, bhash.size());
|
||||||
|
assertArrayEquals(bcar, bhash.get(bbar));
|
||||||
|
assertArrayEquals(bbar, bhash.get(bcar));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hscan() {
|
public void hscan() {
|
||||||
jedis.hset("foo", "b", "b");
|
jedis.hset("foo", "b", "b");
|
||||||
@@ -298,8 +341,16 @@ public class HashesCommandsTest extends JedisCommandTestBase {
|
|||||||
|
|
||||||
ScanResult<Map.Entry<String, String>> result = jedis.hscan("foo", SCAN_POINTER_START);
|
ScanResult<Map.Entry<String, String>> result = jedis.hscan("foo", SCAN_POINTER_START);
|
||||||
|
|
||||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
assertEquals(SCAN_POINTER_START, result.getCursor());
|
||||||
assertFalse(result.getResult().isEmpty());
|
assertFalse(result.getResult().isEmpty());
|
||||||
|
|
||||||
|
// binary
|
||||||
|
jedis.hset(bfoo, bbar, bcar);
|
||||||
|
|
||||||
|
ScanResult<Map.Entry<byte[], byte[]>> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY);
|
||||||
|
|
||||||
|
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||||
|
assertFalse(bResult.getResult().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -313,8 +364,22 @@ public class HashesCommandsTest extends JedisCommandTestBase {
|
|||||||
ScanResult<Map.Entry<String, String>> result = jedis.hscan("foo",
|
ScanResult<Map.Entry<String, String>> result = jedis.hscan("foo",
|
||||||
SCAN_POINTER_START, params);
|
SCAN_POINTER_START, params);
|
||||||
|
|
||||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
assertEquals(SCAN_POINTER_START, result.getCursor());
|
||||||
assertFalse(result.getResult().isEmpty());
|
assertFalse(result.getResult().isEmpty());
|
||||||
|
|
||||||
|
// binary
|
||||||
|
params = new ScanParams();
|
||||||
|
params.match(bbarstar);
|
||||||
|
|
||||||
|
jedis.hset(bfoo, bbar, bcar);
|
||||||
|
jedis.hset(bfoo, bbar1, bcar);
|
||||||
|
jedis.hset(bfoo, bbar2, bcar);
|
||||||
|
jedis.hset(bfoo, bbar3, bcar);
|
||||||
|
|
||||||
|
ScanResult<Map.Entry<byte[], byte[]>> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY, params);
|
||||||
|
|
||||||
|
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||||
|
assertFalse(bResult.getResult().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -330,5 +395,18 @@ public class HashesCommandsTest extends JedisCommandTestBase {
|
|||||||
SCAN_POINTER_START, params);
|
SCAN_POINTER_START, params);
|
||||||
|
|
||||||
assertFalse(result.getResult().isEmpty());
|
assertFalse(result.getResult().isEmpty());
|
||||||
|
|
||||||
|
// binary
|
||||||
|
params = new ScanParams();
|
||||||
|
params.count(2);
|
||||||
|
|
||||||
|
jedis.hset(bfoo, bbar, bcar);
|
||||||
|
jedis.hset(bfoo, bbar1, bcar);
|
||||||
|
jedis.hset(bfoo, bbar2, bcar);
|
||||||
|
jedis.hset(bfoo, bbar3, bcar);
|
||||||
|
|
||||||
|
ScanResult<Map.Entry<byte[], byte[]>> bResult = jedis.hscan(bfoo, SCAN_POINTER_START_BINARY, params);
|
||||||
|
|
||||||
|
assertFalse(bResult.getResult().isEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package redis.clients.jedis.tests.commands;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import redis.clients.util.SafeEncoder;
|
||||||
|
|
||||||
|
public class HyperLogLogCommandsTest extends JedisCommandTestBase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pfadd() {
|
||||||
|
long status = jedis.pfadd("foo", "a");
|
||||||
|
assertEquals(1, status);
|
||||||
|
|
||||||
|
status = jedis.pfadd("foo", "a");
|
||||||
|
assertEquals(0, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pfaddBinary() {
|
||||||
|
byte[] bFoo = SafeEncoder.encode("foo");
|
||||||
|
byte[] bBar = SafeEncoder.encode("bar");
|
||||||
|
byte[] bBar2 = SafeEncoder.encode("bar2");
|
||||||
|
|
||||||
|
long status = jedis.pfadd(bFoo, bBar, bBar2);
|
||||||
|
assertEquals(1, status);
|
||||||
|
|
||||||
|
status = jedis.pfadd(bFoo, bBar, bBar2);
|
||||||
|
assertEquals(0, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pfcount() {
|
||||||
|
long status = jedis.pfadd("hll", "foo", "bar", "zap");
|
||||||
|
assertEquals(1, status);
|
||||||
|
|
||||||
|
status = jedis.pfadd("hll", "zap", "zap", "zap");
|
||||||
|
assertEquals(0, status);
|
||||||
|
|
||||||
|
status = jedis.pfadd("hll", "foo", "bar");
|
||||||
|
assertEquals(0, status);
|
||||||
|
|
||||||
|
status = jedis.pfcount("hll");
|
||||||
|
assertEquals(3, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pfcounts() {
|
||||||
|
long status = jedis.pfadd("hll_1", "foo", "bar", "zap");
|
||||||
|
assertEquals(1, status);
|
||||||
|
status = jedis.pfadd("hll_2", "foo", "bar", "zap");
|
||||||
|
assertEquals(1, status);
|
||||||
|
|
||||||
|
status = jedis.pfadd("hll_3", "foo", "bar", "baz");
|
||||||
|
assertEquals(1, status);
|
||||||
|
status = jedis.pfcount("hll_1");
|
||||||
|
assertEquals(3, status);
|
||||||
|
status = jedis.pfcount("hll_2");
|
||||||
|
assertEquals(3, status);
|
||||||
|
status = jedis.pfcount("hll_3");
|
||||||
|
assertEquals(3, status);
|
||||||
|
|
||||||
|
status = jedis.pfcount("hll_1", "hll_2");
|
||||||
|
assertEquals(3, status);
|
||||||
|
|
||||||
|
status = jedis.pfcount("hll_1", "hll_2", "hll_3");
|
||||||
|
assertEquals(4, status);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pfcountBinary() {
|
||||||
|
byte[] bHll = SafeEncoder.encode("hll");
|
||||||
|
byte[] bFoo = SafeEncoder.encode("foo");
|
||||||
|
byte[] bBar = SafeEncoder.encode("bar");
|
||||||
|
byte[] bZap = SafeEncoder.encode("zap");
|
||||||
|
|
||||||
|
long status = jedis.pfadd(bHll, bFoo, bBar, bZap);
|
||||||
|
assertEquals(1, status);
|
||||||
|
|
||||||
|
status = jedis.pfadd(bHll, bZap, bZap, bZap);
|
||||||
|
assertEquals(0, status);
|
||||||
|
|
||||||
|
status = jedis.pfadd(bHll, bFoo, bBar);
|
||||||
|
assertEquals(0, status);
|
||||||
|
|
||||||
|
status = jedis.pfcount(bHll);
|
||||||
|
assertEquals(3, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pfmerge() {
|
||||||
|
long status = jedis.pfadd("hll1", "foo", "bar", "zap", "a");
|
||||||
|
assertEquals(1, status);
|
||||||
|
|
||||||
|
status = jedis.pfadd("hll2", "a", "b", "c", "foo");
|
||||||
|
assertEquals(1, status);
|
||||||
|
|
||||||
|
String mergeStatus = jedis.pfmerge("hll3", "hll1", "hll2");
|
||||||
|
assertEquals("OK", mergeStatus);
|
||||||
|
|
||||||
|
status = jedis.pfcount("hll3");
|
||||||
|
assertEquals(6, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pfmergeBinary() {
|
||||||
|
byte[] bHll1 = SafeEncoder.encode("hll1");
|
||||||
|
byte[] bHll2 = SafeEncoder.encode("hll2");
|
||||||
|
byte[] bHll3 = SafeEncoder.encode("hll3");
|
||||||
|
byte[] bFoo = SafeEncoder.encode("foo");
|
||||||
|
byte[] bBar = SafeEncoder.encode("bar");
|
||||||
|
byte[] bZap = SafeEncoder.encode("zap");
|
||||||
|
byte[] bA = SafeEncoder.encode("a");
|
||||||
|
byte[] bB = SafeEncoder.encode("b");
|
||||||
|
byte[] bC = SafeEncoder.encode("c");
|
||||||
|
|
||||||
|
long status = jedis.pfadd(bHll1, bFoo, bBar, bZap, bA);
|
||||||
|
assertEquals(1, status);
|
||||||
|
|
||||||
|
status = jedis.pfadd(bHll2, bA, bB, bC, bFoo);
|
||||||
|
assertEquals(1, status);
|
||||||
|
|
||||||
|
String mergeStatus = jedis.pfmerge(bHll3, bHll1, bHll2);
|
||||||
|
assertEquals("OK", mergeStatus);
|
||||||
|
|
||||||
|
status = jedis.pfcount("hll3");
|
||||||
|
assertEquals(6, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import org.junit.Test;
|
|||||||
import redis.clients.jedis.ScanParams;
|
import redis.clients.jedis.ScanParams;
|
||||||
import redis.clients.jedis.ScanResult;
|
import redis.clients.jedis.ScanResult;
|
||||||
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
|
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
|
||||||
|
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START_BINARY;
|
||||||
|
|
||||||
public class SetCommandsTest extends JedisCommandTestBase {
|
public class SetCommandsTest extends JedisCommandTestBase {
|
||||||
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
||||||
@@ -20,6 +21,11 @@ public class SetCommandsTest extends JedisCommandTestBase {
|
|||||||
final byte[] bd = { 0x0D };
|
final byte[] bd = { 0x0D };
|
||||||
final byte[] bx = { 0x42 };
|
final byte[] bx = { 0x42 };
|
||||||
|
|
||||||
|
final byte[] bbar1 = { 0x05, 0x06, 0x07, 0x08, 0x0A };
|
||||||
|
final byte[] bbar2 = { 0x05, 0x06, 0x07, 0x08, 0x0B };
|
||||||
|
final byte[] bbar3 = { 0x05, 0x06, 0x07, 0x08, 0x0C };
|
||||||
|
final byte[] bbarstar = { 0x05, 0x06, 0x07, 0x08, '*' };
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void sadd() {
|
public void sadd() {
|
||||||
long status = jedis.sadd("foo", "a");
|
long status = jedis.sadd("foo", "a");
|
||||||
@@ -460,8 +466,16 @@ public class SetCommandsTest extends JedisCommandTestBase {
|
|||||||
|
|
||||||
ScanResult<String> result = jedis.sscan("foo", SCAN_POINTER_START);
|
ScanResult<String> result = jedis.sscan("foo", SCAN_POINTER_START);
|
||||||
|
|
||||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
assertEquals(SCAN_POINTER_START, result.getCursor());
|
||||||
assertFalse(result.getResult().isEmpty());
|
assertFalse(result.getResult().isEmpty());
|
||||||
|
|
||||||
|
// binary
|
||||||
|
jedis.sadd(bfoo, ba, bb);
|
||||||
|
|
||||||
|
ScanResult<byte[]> bResult = jedis.sscan(bfoo, SCAN_POINTER_START_BINARY);
|
||||||
|
|
||||||
|
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||||
|
assertFalse(bResult.getResult().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -472,8 +486,18 @@ public class SetCommandsTest extends JedisCommandTestBase {
|
|||||||
jedis.sadd("foo", "b", "a", "aa");
|
jedis.sadd("foo", "b", "a", "aa");
|
||||||
ScanResult<String> result = jedis.sscan("foo", SCAN_POINTER_START, params);
|
ScanResult<String> result = jedis.sscan("foo", SCAN_POINTER_START, params);
|
||||||
|
|
||||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
assertEquals(SCAN_POINTER_START, result.getCursor());
|
||||||
assertFalse(result.getResult().isEmpty());
|
assertFalse(result.getResult().isEmpty());
|
||||||
|
|
||||||
|
// binary
|
||||||
|
params = new ScanParams();
|
||||||
|
params.match(bbarstar);
|
||||||
|
|
||||||
|
jedis.sadd(bfoo, bbar1, bbar2, bbar3);
|
||||||
|
ScanResult<byte[]> bResult = jedis.sscan(bfoo, SCAN_POINTER_START_BINARY, params);
|
||||||
|
|
||||||
|
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||||
|
assertFalse(bResult.getResult().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -486,5 +510,14 @@ public class SetCommandsTest extends JedisCommandTestBase {
|
|||||||
ScanResult<String> result = jedis.sscan("foo", SCAN_POINTER_START, params);
|
ScanResult<String> result = jedis.sscan("foo", SCAN_POINTER_START, params);
|
||||||
|
|
||||||
assertFalse(result.getResult().isEmpty());
|
assertFalse(result.getResult().isEmpty());
|
||||||
|
|
||||||
|
// binary
|
||||||
|
params = new ScanParams();
|
||||||
|
params.count(2);
|
||||||
|
|
||||||
|
jedis.sadd(bfoo, bbar1, bbar2, bbar3);
|
||||||
|
ScanResult<byte[]> bResult = jedis.sscan(bfoo, SCAN_POINTER_START_BINARY, params);
|
||||||
|
|
||||||
|
assertFalse(bResult.getResult().isEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,7 @@ import redis.clients.jedis.Tuple;
|
|||||||
import redis.clients.jedis.ZParams;
|
import redis.clients.jedis.ZParams;
|
||||||
import redis.clients.util.SafeEncoder;
|
import redis.clients.util.SafeEncoder;
|
||||||
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
|
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START;
|
||||||
|
import static redis.clients.jedis.ScanParams.SCAN_POINTER_START_BINARY;
|
||||||
|
|
||||||
public class SortedSetCommandsTest extends JedisCommandTestBase {
|
public class SortedSetCommandsTest extends JedisCommandTestBase {
|
||||||
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
|
||||||
@@ -26,6 +27,11 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
|||||||
final byte[] bLexMinusInf = { 0x2D };
|
final byte[] bLexMinusInf = { 0x2D };
|
||||||
final byte[] bLexPlusInf = { 0x2B };
|
final byte[] bLexPlusInf = { 0x2B };
|
||||||
|
|
||||||
|
final byte[] bbar1 = { 0x05, 0x06, 0x07, 0x08, 0x0A };
|
||||||
|
final byte[] bbar2 = { 0x05, 0x06, 0x07, 0x08, 0x0B };
|
||||||
|
final byte[] bbar3 = { 0x05, 0x06, 0x07, 0x08, 0x0C };
|
||||||
|
final byte[] bbarstar = { 0x05, 0x06, 0x07, 0x08, '*' };
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void zadd() {
|
public void zadd() {
|
||||||
long status = jedis.zadd("foo", 1d, "a");
|
long status = jedis.zadd("foo", 1d, "a");
|
||||||
@@ -894,15 +900,15 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
|||||||
jedis.zadd("bar", 2, "b");
|
jedis.zadd("bar", 2, "b");
|
||||||
|
|
||||||
ZParams params = new ZParams();
|
ZParams params = new ZParams();
|
||||||
params.weights(2, 2);
|
params.weights(2, 2.5);
|
||||||
params.aggregate(ZParams.Aggregate.SUM);
|
params.aggregate(ZParams.Aggregate.SUM);
|
||||||
long result = jedis.zunionstore("dst", params, "foo", "bar");
|
long result = jedis.zunionstore("dst", params, "foo", "bar");
|
||||||
|
|
||||||
assertEquals(2, result);
|
assertEquals(2, result);
|
||||||
|
|
||||||
Set<Tuple> expected = new LinkedHashSet<Tuple>();
|
Set<Tuple> expected = new LinkedHashSet<Tuple>();
|
||||||
expected.add(new Tuple("b", new Double(8)));
|
expected.add(new Tuple("b", new Double(9)));
|
||||||
expected.add(new Tuple("a", new Double(6)));
|
expected.add(new Tuple("a", new Double(7)));
|
||||||
|
|
||||||
assertEquals(expected, jedis.zrangeWithScores("dst", 0, 100));
|
assertEquals(expected, jedis.zrangeWithScores("dst", 0, 100));
|
||||||
|
|
||||||
@@ -913,7 +919,7 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
|||||||
jedis.zadd(bbar, 2, bb);
|
jedis.zadd(bbar, 2, bb);
|
||||||
|
|
||||||
ZParams bparams = new ZParams();
|
ZParams bparams = new ZParams();
|
||||||
bparams.weights(2, 2);
|
bparams.weights(2, 2.5);
|
||||||
bparams.aggregate(ZParams.Aggregate.SUM);
|
bparams.aggregate(ZParams.Aggregate.SUM);
|
||||||
long bresult = jedis.zunionstore(SafeEncoder.encode("dst"), bparams,
|
long bresult = jedis.zunionstore(SafeEncoder.encode("dst"), bparams,
|
||||||
bfoo, bbar);
|
bfoo, bbar);
|
||||||
@@ -921,8 +927,8 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
|||||||
assertEquals(2, bresult);
|
assertEquals(2, bresult);
|
||||||
|
|
||||||
Set<Tuple> bexpected = new LinkedHashSet<Tuple>();
|
Set<Tuple> bexpected = new LinkedHashSet<Tuple>();
|
||||||
bexpected.add(new Tuple(bb, new Double(8)));
|
bexpected.add(new Tuple(bb, new Double(9)));
|
||||||
bexpected.add(new Tuple(ba, new Double(6)));
|
bexpected.add(new Tuple(ba, new Double(7)));
|
||||||
|
|
||||||
assertEquals(bexpected,
|
assertEquals(bexpected,
|
||||||
jedis.zrangeWithScores(SafeEncoder.encode("dst"), 0, 100));
|
jedis.zrangeWithScores(SafeEncoder.encode("dst"), 0, 100));
|
||||||
@@ -966,14 +972,14 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
|||||||
jedis.zadd("bar", 2, "a");
|
jedis.zadd("bar", 2, "a");
|
||||||
|
|
||||||
ZParams params = new ZParams();
|
ZParams params = new ZParams();
|
||||||
params.weights(2, 2);
|
params.weights(2, 2.5);
|
||||||
params.aggregate(ZParams.Aggregate.SUM);
|
params.aggregate(ZParams.Aggregate.SUM);
|
||||||
long result = jedis.zinterstore("dst", params, "foo", "bar");
|
long result = jedis.zinterstore("dst", params, "foo", "bar");
|
||||||
|
|
||||||
assertEquals(1, result);
|
assertEquals(1, result);
|
||||||
|
|
||||||
Set<Tuple> expected = new LinkedHashSet<Tuple>();
|
Set<Tuple> expected = new LinkedHashSet<Tuple>();
|
||||||
expected.add(new Tuple("a", new Double(6)));
|
expected.add(new Tuple("a", new Double(7)));
|
||||||
|
|
||||||
assertEquals(expected, jedis.zrangeWithScores("dst", 0, 100));
|
assertEquals(expected, jedis.zrangeWithScores("dst", 0, 100));
|
||||||
|
|
||||||
@@ -983,7 +989,7 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
|||||||
jedis.zadd(bbar, 2, ba);
|
jedis.zadd(bbar, 2, ba);
|
||||||
|
|
||||||
ZParams bparams = new ZParams();
|
ZParams bparams = new ZParams();
|
||||||
bparams.weights(2, 2);
|
bparams.weights(2, 2.5);
|
||||||
bparams.aggregate(ZParams.Aggregate.SUM);
|
bparams.aggregate(ZParams.Aggregate.SUM);
|
||||||
long bresult = jedis.zinterstore(SafeEncoder.encode("dst"), bparams,
|
long bresult = jedis.zinterstore(SafeEncoder.encode("dst"), bparams,
|
||||||
bfoo, bbar);
|
bfoo, bbar);
|
||||||
@@ -991,7 +997,7 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
|||||||
assertEquals(1, bresult);
|
assertEquals(1, bresult);
|
||||||
|
|
||||||
Set<Tuple> bexpected = new LinkedHashSet<Tuple>();
|
Set<Tuple> bexpected = new LinkedHashSet<Tuple>();
|
||||||
bexpected.add(new Tuple(ba, new Double(6)));
|
bexpected.add(new Tuple(ba, new Double(7)));
|
||||||
|
|
||||||
assertEquals(bexpected,
|
assertEquals(bexpected,
|
||||||
jedis.zrangeWithScores(SafeEncoder.encode("dst"), 0, 100));
|
jedis.zrangeWithScores(SafeEncoder.encode("dst"), 0, 100));
|
||||||
@@ -1014,8 +1020,17 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
|||||||
|
|
||||||
ScanResult<Tuple> result = jedis.zscan("foo", SCAN_POINTER_START);
|
ScanResult<Tuple> result = jedis.zscan("foo", SCAN_POINTER_START);
|
||||||
|
|
||||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
assertEquals(SCAN_POINTER_START, result.getCursor());
|
||||||
assertFalse(result.getResult().isEmpty());
|
assertFalse(result.getResult().isEmpty());
|
||||||
|
|
||||||
|
// binary
|
||||||
|
jedis.zadd(bfoo, 1, ba);
|
||||||
|
jedis.zadd(bfoo, 1, bb);
|
||||||
|
|
||||||
|
ScanResult<Tuple> bResult = jedis.zscan(bfoo, SCAN_POINTER_START_BINARY);
|
||||||
|
|
||||||
|
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||||
|
assertFalse(bResult.getResult().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1028,8 +1043,21 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
|||||||
jedis.zadd("foo", 11, "aa");
|
jedis.zadd("foo", 11, "aa");
|
||||||
ScanResult<Tuple> result = jedis.zscan("foo", SCAN_POINTER_START, params);
|
ScanResult<Tuple> result = jedis.zscan("foo", SCAN_POINTER_START, params);
|
||||||
|
|
||||||
assertEquals(SCAN_POINTER_START, result.getStringCursor());
|
assertEquals(SCAN_POINTER_START, result.getCursor());
|
||||||
assertFalse(result.getResult().isEmpty());
|
assertFalse(result.getResult().isEmpty());
|
||||||
|
|
||||||
|
// binary
|
||||||
|
params = new ScanParams();
|
||||||
|
params.match(bbarstar);
|
||||||
|
|
||||||
|
jedis.zadd(bfoo, 2, bbar1);
|
||||||
|
jedis.zadd(bfoo, 1, bbar2);
|
||||||
|
jedis.zadd(bfoo, 11, bbar3);
|
||||||
|
ScanResult<Tuple> bResult = jedis.zscan(bfoo, SCAN_POINTER_START_BINARY, params);
|
||||||
|
|
||||||
|
assertArrayEquals(SCAN_POINTER_START_BINARY, bResult.getCursorAsBytes());
|
||||||
|
assertFalse(bResult.getResult().isEmpty());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1046,5 +1074,17 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
|
|||||||
ScanResult<Tuple> result = jedis.zscan("foo", SCAN_POINTER_START, params);
|
ScanResult<Tuple> result = jedis.zscan("foo", SCAN_POINTER_START, params);
|
||||||
|
|
||||||
assertFalse(result.getResult().isEmpty());
|
assertFalse(result.getResult().isEmpty());
|
||||||
|
|
||||||
|
// binary
|
||||||
|
params = new ScanParams();
|
||||||
|
params.count(2);
|
||||||
|
|
||||||
|
jedis.zadd(bfoo, 2, bbar1);
|
||||||
|
jedis.zadd(bfoo, 1, bbar2);
|
||||||
|
jedis.zadd(bfoo, 11, bbar3);
|
||||||
|
|
||||||
|
ScanResult<Tuple> bResult = jedis.zscan(bfoo, SCAN_POINTER_START_BINARY, params);
|
||||||
|
|
||||||
|
assertFalse(bResult.getResult().isEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,6 +123,12 @@ public class StringValuesCommandsTest extends JedisCommandTestBase {
|
|||||||
assertEquals(4, value);
|
assertEquals(4, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = JedisDataException.class)
|
||||||
|
public void incrByFloatWrongValue() {
|
||||||
|
jedis.set("foo", "bar");
|
||||||
|
jedis.incrByFloat("foo", 2d);
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = JedisDataException.class)
|
@Test(expected = JedisDataException.class)
|
||||||
public void decrWrongValue() {
|
public void decrWrongValue() {
|
||||||
jedis.set("foo", "bar");
|
jedis.set("foo", "bar");
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package redis.clients.jedis.tests.utils;
|
||||||
|
|
||||||
|
import redis.clients.jedis.Jedis;
|
||||||
|
import redis.clients.jedis.exceptions.JedisException;
|
||||||
|
|
||||||
|
public class JedisClusterTestUtil {
|
||||||
|
public static void waitForClusterReady(Jedis...nodes) throws InterruptedException {
|
||||||
|
boolean clusterOk = false;
|
||||||
|
while (!clusterOk) {
|
||||||
|
boolean isOk = true;
|
||||||
|
for (Jedis node : nodes) {
|
||||||
|
if (!node.clusterInfo().split("\n")[0].contains("ok")) {
|
||||||
|
isOk = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isOk) {
|
||||||
|
clusterOk = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.sleep(50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getNodeId(String infoOutput) {
|
||||||
|
for (String infoLine : infoOutput.split("\n")) {
|
||||||
|
if (infoLine.contains("myself")) {
|
||||||
|
return infoLine.split(" ")[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void assertNodeIsKnown(Jedis node, String targetNodeId, int timeoutMs) {
|
||||||
|
assertNodeRecognizedStatus(node, targetNodeId, true, timeoutMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void assertNodeIsUnknown(Jedis node, String targetNodeId, int timeoutMs) {
|
||||||
|
assertNodeRecognizedStatus(node, targetNodeId, false, timeoutMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertNodeRecognizedStatus(Jedis node, String targetNodeId, boolean shouldRecognized, int timeoutMs) {
|
||||||
|
int sleepInterval = 100;
|
||||||
|
for (int sleepTime = 0 ; sleepTime <= timeoutMs ; sleepTime += sleepInterval) {
|
||||||
|
boolean known = isKnownNode(node, targetNodeId);
|
||||||
|
if (shouldRecognized == known)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(sleepInterval);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new JedisException("Node recognize check error");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isKnownNode(Jedis node, String nodeId) {
|
||||||
|
String infoOutput = node.clusterNodes();
|
||||||
|
for (String infoLine : infoOutput.split("\n")) {
|
||||||
|
if (infoLine.contains(nodeId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user