Merge branch 'master' into eval-with-nested-lists-and-longs

Conflicts:
	src/main/java/redis/clients/jedis/Jedis.java
	src/test/java/redis/clients/jedis/tests/commands/ScriptingCommandsTest.java
This commit is contained in:
Daniel Josefsson
2014-02-05 22:24:23 +00:00
122 changed files with 10799 additions and 7506 deletions

148
Makefile
View File

@@ -6,6 +6,7 @@ pidfile /tmp/redis1.pid
logfile /tmp/redis1.log logfile /tmp/redis1.log
save "" save ""
appendonly no appendonly no
client-output-buffer-limit pubsub 256k 128k 5
endef endef
define REDIS2_CONF define REDIS2_CONF
@@ -37,6 +38,7 @@ pidfile /tmp/redis4.pid
logfile /tmp/redis4.log logfile /tmp/redis4.log
save "" save ""
appendonly no appendonly no
slaveof localhost 6381
endef endef
define REDIS5_CONF define REDIS5_CONF
@@ -48,8 +50,22 @@ pidfile /tmp/redis5.pid
logfile /tmp/redis5.log logfile /tmp/redis5.log
save "" save ""
appendonly no appendonly no
slaveof localhost 6381
endef endef
define REDIS6_CONF
daemonize yes
port 6384
requirepass foobared
masterauth foobared
pidfile /tmp/redis6.pid
logfile /tmp/redis6.log
save ""
appendonly no
slaveof localhost 6379
endef
# SENTINELS
define REDIS_SENTINEL1 define REDIS_SENTINEL1
port 26379 port 26379
daemonize yes daemonize yes
@@ -57,7 +73,6 @@ sentinel monitor mymaster 127.0.0.1 6379 1
sentinel auth-pass mymaster foobared sentinel auth-pass mymaster foobared
sentinel down-after-milliseconds mymaster 3000 sentinel down-after-milliseconds mymaster 3000
sentinel failover-timeout mymaster 900000 sentinel failover-timeout mymaster 900000
sentinel can-failover mymaster yes
sentinel parallel-syncs mymaster 1 sentinel parallel-syncs mymaster 1
pidfile /tmp/sentinel1.pid pidfile /tmp/sentinel1.pid
logfile /tmp/sentinel1.log logfile /tmp/sentinel1.log
@@ -69,7 +84,6 @@ daemonize yes
sentinel monitor mymaster 127.0.0.1 6381 2 sentinel monitor mymaster 127.0.0.1 6381 2
sentinel auth-pass mymaster foobared sentinel auth-pass mymaster foobared
sentinel down-after-milliseconds mymaster 3000 sentinel down-after-milliseconds mymaster 3000
sentinel can-failover mymaster yes
sentinel parallel-syncs mymaster 1 sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 900000 sentinel failover-timeout mymaster 900000
pidfile /tmp/sentinel2.pid pidfile /tmp/sentinel2.pid
@@ -82,31 +96,78 @@ daemonize yes
sentinel monitor mymaster 127.0.0.1 6381 2 sentinel monitor mymaster 127.0.0.1 6381 2
sentinel auth-pass mymaster foobared sentinel auth-pass mymaster foobared
sentinel down-after-milliseconds mymaster 3000 sentinel down-after-milliseconds mymaster 3000
sentinel can-failover mymaster yes
sentinel parallel-syncs mymaster 1 sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 900000 sentinel failover-timeout mymaster 900000
pidfile /tmp/sentinel3.pid pidfile /tmp/sentinel3.pid
logfile /tmp/sentinel3.log logfile /tmp/sentinel3.log
endef endef
# CLUSTER REDIS NODES
define REDIS_CLUSTER_NODE1_CONF
daemonize yes
port 7379
pidfile /tmp/redis_cluster_node1.pid
logfile /tmp/redis_cluster_node1.log
save ""
appendonly no
cluster-enabled yes
cluster-config-file /tmp/redis_cluster_node1.conf
endef
define REDIS_CLUSTER_NODE2_CONF
daemonize yes
port 7380
pidfile /tmp/redis_cluster_node2.pid
logfile /tmp/redis_cluster_node2.log
save ""
appendonly no
cluster-enabled yes
cluster-config-file /tmp/redis_cluster_node2.conf
endef
define REDIS_CLUSTER_NODE3_CONF
daemonize yes
port 7381
pidfile /tmp/redis_cluster_node3.pid
logfile /tmp/redis_cluster_node3.log
save ""
appendonly no
cluster-enabled yes
cluster-config-file /tmp/redis_cluster_node3.conf
endef
export REDIS1_CONF export REDIS1_CONF
export REDIS2_CONF export REDIS2_CONF
export REDIS3_CONF export REDIS3_CONF
export REDIS4_CONF export REDIS4_CONF
export REDIS5_CONF export REDIS5_CONF
export REDIS6_CONF
export REDIS_SENTINEL1 export REDIS_SENTINEL1
export REDIS_SENTINEL2 export REDIS_SENTINEL2
export REDIS_SENTINEL3 export REDIS_SENTINEL3
export REDIS_CLUSTER_NODE1_CONF
export REDIS_CLUSTER_NODE2_CONF
export REDIS_CLUSTER_NODE3_CONF
start: start: cleanup
echo "$$REDIS1_CONF" | redis-server - echo "$$REDIS1_CONF" | redis-server -
echo "$$REDIS2_CONF" | redis-server - echo "$$REDIS2_CONF" | redis-server -
echo "$$REDIS3_CONF" | redis-server - echo "$$REDIS3_CONF" | redis-server -
echo "$$REDIS4_CONF" | redis-server - echo "$$REDIS4_CONF" | redis-server -
echo "$$REDIS5_CONF" | redis-server - echo "$$REDIS5_CONF" | redis-server -
echo "$$REDIS_SENTINEL1" | redis-server - --sentinel echo "$$REDIS6_CONF" | redis-server -
echo "$$REDIS_SENTINEL2" | redis-server - --sentinel echo "$$REDIS_SENTINEL1" > /tmp/sentinel1.conf && redis-server /tmp/sentinel1.conf --sentinel
echo "$$REDIS_SENTINEL3" | redis-server - --sentinel @sleep 0.5
echo "$$REDIS_SENTINEL2" > /tmp/sentinel2.conf && redis-server /tmp/sentinel2.conf --sentinel
@sleep 0.5
echo "$$REDIS_SENTINEL3" > /tmp/sentinel3.conf && redis-server /tmp/sentinel3.conf --sentinel
echo "$$REDIS_CLUSTER_NODE1_CONF" | redis-server -
echo "$$REDIS_CLUSTER_NODE2_CONF" | redis-server -
echo "$$REDIS_CLUSTER_NODE3_CONF" | redis-server -
cleanup:
- rm -vf /tmp/redis_cluster_node*.conf 2>/dev/null
- rm dump.rdb appendonly.aof - 2>/dev/null
stop: stop:
kill `cat /tmp/redis1.pid` kill `cat /tmp/redis1.pid`
@@ -115,76 +176,33 @@ stop:
kill `cat /tmp/redis3.pid` || true kill `cat /tmp/redis3.pid` || true
kill `cat /tmp/redis4.pid` || true kill `cat /tmp/redis4.pid` || true
kill `cat /tmp/redis5.pid` || true kill `cat /tmp/redis5.pid` || true
kill `cat /tmp/redis6.pid` || true
kill `cat /tmp/sentinel1.pid` kill `cat /tmp/sentinel1.pid`
kill `cat /tmp/sentinel2.pid` kill `cat /tmp/sentinel2.pid`
kill `cat /tmp/sentinel3.pid` kill `cat /tmp/sentinel3.pid`
kill `cat /tmp/redis_cluster_node1.pid` || true
kill `cat /tmp/redis_cluster_node2.pid` || true
kill `cat /tmp/redis_cluster_node3.pid` || true
rm -f /tmp/redis_cluster_node1.conf
rm -f /tmp/redis_cluster_node2.conf
rm -f /tmp/redis_cluster_node3.conf
test: test:
echo "$$REDIS1_CONF" | redis-server - make start
echo "$$REDIS2_CONF" | redis-server - sleep 2
echo "$$REDIS3_CONF" | redis-server - mvn -Dtest=${TEST} clean compile test
echo "$$REDIS4_CONF" | redis-server - make stop
echo "$$REDIS5_CONF" | redis-server -
echo "$$REDIS_SENTINEL1" | redis-server - --sentinel
echo "$$REDIS_SENTINEL2" | redis-server - --sentinel
echo "$$REDIS_SENTINEL3" | redis-server - --sentinel
mvn clean compile test
kill `cat /tmp/redis1.pid`
kill `cat /tmp/redis2.pid`
# this get's segfaulted by the tests
kill `cat /tmp/redis3.pid` || true
kill `cat /tmp/redis4.pid` || true
kill `cat /tmp/redis5.pid` || true
kill `cat /tmp/sentinel1.pid`
kill `cat /tmp/sentinel2.pid`
kill `cat /tmp/sentinel3.pid`
deploy: deploy:
echo "$$REDIS1_CONF" | redis-server - make start
echo "$$REDIS2_CONF" | redis-server -
echo "$$REDIS3_CONF" | redis-server -
echo "$$REDIS4_CONF" | redis-server -
echo "$$REDIS5_CONF" | redis-server -
echo "$$REDIS_SENTINEL1" | redis-server - --sentinel
echo "$$REDIS_SENTINEL2" | redis-server - --sentinel
echo "$$REDIS_SENTINEL3" | redis-server - --sentinel
mvn clean deploy mvn clean deploy
make stop
kill `cat /tmp/redis1.pid`
kill `cat /tmp/redis2.pid`
# this get's segfaulted by the tests
kill `cat /tmp/redis3.pid` || true
kill `cat /tmp/redis4.pid` || true
kill `cat /tmp/redis5.pid` || true
kill `cat /tmp/sentinel1.pid`
kill `cat /tmp/sentinel2.pid`
kill `cat /tmp/sentinel3.pid`
release: release:
echo "$$REDIS1_CONF" | redis-server - make start
echo "$$REDIS2_CONF" | redis-server -
echo "$$REDIS3_CONF" | redis-server -
echo "$$REDIS4_CONF" | redis-server -
echo "$$REDIS5_CONF" | redis-server -
echo "$$REDIS_SENTINEL1" | redis-server - --sentinel
echo "$$REDIS_SENTINEL2" | redis-server - --sentinel
echo "$$REDIS_SENTINEL3" | redis-server - --sentinel
mvn release:clean mvn release:clean
mvn release:prepare mvn release:prepare
mvn release:perform mvn release:perform
make stop
kill `cat /tmp/redis1.pid`
kill `cat /tmp/redis2.pid`
# this get's segfaulted by the tests
kill `cat /tmp/redis3.pid` || true
kill `cat /tmp/redis4.pid` || true
kill `cat /tmp/redis5.pid` || true
kill `cat /tmp/sentinel1.pid`
kill `cat /tmp/sentinel2.pid`
kill `cat /tmp/sentinel3.pid`
.PHONY: test .PHONY: test

View File

@@ -4,7 +4,7 @@ Jedis is a blazingly small and sane [Redis](http://github.com/antirez/redis "Red
Jedis was conceived to be EASY to use. Jedis was conceived to be EASY to use.
Jedis is fully compatible with redis 2.6.14. Jedis is fully compatible with redis 2.8.5.
## Community ## Community
@@ -33,6 +33,7 @@ All of the following redis features are supported:
- Key-tags for sharding - Key-tags for sharding
- Sharding with pipelining - Sharding with pipelining
- Scripting with pipelining - Scripting with pipelining
- Redis Cluster
## How do I use it? ## How do I use it?
@@ -45,7 +46,7 @@ Or use it as a maven dependency:
<dependency> <dependency>
<groupId>redis.clients</groupId> <groupId>redis.clients</groupId>
<artifactId>jedis</artifactId> <artifactId>jedis</artifactId>
<version>2.0.0</version> <version>2.2.1</version>
<type>jar</type> <type>jar</type>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
@@ -65,6 +66,19 @@ Please check the [wiki](http://github.com/xetorthio/jedis/wiki "wiki"). There ar
And you are done! And you are done!
## Jedis Cluster
Redis cluster [specification](http://redis.io/topics/cluster-spec) (still under development) is implemented
```java
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
//Jedis Cluster will attempt to discover cluster nodes automatically
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
jc.set("foo", "bar");
String value = jc.get("foo");
```
## I want to contribute! ## I want to contribute!
That is great! Just fork the project in github. Create a topic branch, write some code, and add some tests for your new code. That is great! Just fork the project in github. Create a topic branch, write some code, and add some tests for your new code.

View File

@@ -11,8 +11,8 @@ repositories {
} }
dependencies { dependencies {
testCompile 'junit:junit:4.8.1' testCompile 'junit:junit:4.11'
compile 'commons-pool:commons-pool:1.5.5' compile 'org.apache.commons:commons-pool2:2.0'
} }
@@ -28,6 +28,6 @@ uploadArchives {
*/ */
task createWrapper(type: Wrapper) { task createWrapper(type: Wrapper) {
gradleVersion = '1.0-milestone-6' gradleVersion = '1.8'
} }

Binary file not shown.

View File

@@ -1,6 +1,6 @@
#Fri Dec 23 12:54:50 CST 2011 #Mon Nov 04 18:13:13 EST 2013
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=http\://repo.gradle.org/gradle/distributions/gradle-1.0-milestone-6-bin.zip distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip

114
gradlew vendored
View File

@@ -1,16 +1,16 @@
#!/bin/bash #!/usr/bin/env bash
############################################################################## ##############################################################################
## ## ##
## Gradle wrapper script for UN*X ## ## Gradle start up script for UN*X
## ## ##
############################################################################## ##############################################################################
# Uncomment those lines to set JVM options. GRADLE_OPTS and JAVA_OPTS can be used together. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
# GRADLE_OPTS="$GRADLE_OPTS -Xmx512m" DEFAULT_JVM_OPTS=""
# JAVA_OPTS="$JAVA_OPTS -Xmx512m"
GRADLE_APP_NAME=Gradle APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD="maximum"
@@ -42,54 +42,51 @@ case "`uname`" in
;; ;;
esac esac
# Attempt to set JAVA_HOME if it's not already set.
if [ -z "$JAVA_HOME" ] ; then
if $darwin ; then
[ -z "$JAVA_HOME" -a -d "/Library/Java/Home" ] && export JAVA_HOME="/Library/Java/Home"
[ -z "$JAVA_HOME" -a -d "/System/Library/Frameworks/JavaVM.framework/Home" ] && export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Home"
else
javaExecutable="`which javac`"
[ -z "$javaExecutable" -o "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ] && die "JAVA_HOME not set and cannot find javac to deduce location, please set JAVA_HOME."
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
[ `expr "$readLink" : '\([^ ]*\)'` = "no" ] && die "JAVA_HOME not set and readlink not available, please set JAVA_HOME."
javaExecutable="`readlink -f \"$javaExecutable\"`"
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
export JAVA_HOME="$javaHome"
fi
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched. # For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then if $cygwin ; then
[ -n "$JAVACMD" ] && JAVACMD=`cygpath --unix "$JAVACMD"`
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi fi
STARTER_MAIN_CLASS=org.gradle.wrapper.GradleWrapperMain # Attempt to set APP_HOME
CLASSPATH=`dirname "$0"`/gradle/wrapper/gradle-wrapper.jar # Resolve links: $0 may be a link
WRAPPER_PROPERTIES=`dirname "$0"`/gradle/wrapper/gradle-wrapper.properties PRG="$0"
# Determine the Java command to use to start the JVM. # Need this for relative symlinks.
if [ -z "$JAVACMD" ] ; then while [ -h "$PRG" ] ; do
if [ -n "$JAVA_HOME" ] ; then ls=`ls -ld "$PRG"`
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then link=`expr "$ls" : '.*-> \(.*\)$'`
# IBM's JDK on AIX uses strange locations for the executables if expr "$link" : '/.*' > /dev/null; then
JAVACMD="$JAVA_HOME/jre/sh/java" PRG="$link"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else else
JAVACMD="java" PRG=`dirname "$PRG"`"/$link"
fi fi
fi done
if [ ! -x "$JAVACMD" ] ; then SAVED="`pwd`"
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi
if [ -z "$JAVA_HOME" ] ; then
warn "JAVA_HOME environment variable is not set"
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
@@ -104,19 +101,18 @@ if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD" warn "Could not set maximum file descriptor limit: $MAX_FD"
fi fi
else else
warn "Could not query businessSystem maximum file descriptor limit: $MAX_FD_LIMIT" warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi fi
fi fi
# For Darwin, add GRADLE_APP_NAME to the JAVA_OPTS as -Xdock:name # For Darwin, add options to specify how the application appears in the dock
if $darwin; then if $darwin; then
JAVA_OPTS="$JAVA_OPTS -Xdock:name=$GRADLE_APP_NAME" GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
# we may also want to set -Xdock:image
fi fi
# For Cygwin, switch paths to Windows format before running java # For Cygwin, switch paths to Windows format before running java
if $cygwin ; then if $cygwin ; then
JAVA_HOME=`cygpath --path --mixed "$JAVA_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath
@@ -143,7 +139,7 @@ if $cygwin ; then
eval `echo args$i`="\"$arg\"" eval `echo args$i`="\"$arg\""
fi fi
i=$((i+1)) i=$((i+1))
done done
case $i in case $i in
(0) set -- ;; (0) set -- ;;
(1) set -- "$args0" ;; (1) set -- "$args0" ;;
@@ -158,11 +154,11 @@ if $cygwin ; then
esac esac
fi fi
GRADLE_APP_BASE_NAME=`basename "$0"` # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" $JAVA_OPTS $GRADLE_OPTS \ exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
-classpath "$CLASSPATH" \
-Dorg.gradle.appname="$GRADLE_APP_BASE_NAME" \
-Dorg.gradle.wrapper.properties="$WRAPPER_PROPERTIES" \
$STARTER_MAIN_CLASS \
"$@"

54
gradlew.bat vendored
View File

@@ -1,24 +1,37 @@
@if "%DEBUG%" == "" @echo off @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem ## @rem
@rem Gradle startup script for Windows ## @rem Gradle startup script for Windows
@rem ## @rem
@rem ########################################################################## @rem ##########################################################################
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
@rem Uncomment those lines to set JVM options. GRADLE_OPTS and JAVA_OPTS can be used together. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
@rem set GRADLE_OPTS=%GRADLE_OPTS% -Xmx512m set DEFAULT_JVM_OPTS=
@rem set JAVA_OPTS=%JAVA_OPTS% -Xmx512m
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.\ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe @rem Find java.exe
set JAVA_EXE=java.exe if defined JAVA_HOME goto findJavaFromJavaHome
if not defined JAVA_HOME goto init
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
@@ -29,14 +42,14 @@ echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo. echo.
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. echo location of your Java installation.
echo.
goto end goto fail
:init :init
@rem Get command-line arguments, handling Windowz variants @rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args if not "%OS%" == "Windows_NT" goto win9xME_args
if "%eval[2+2]" == "4" goto 4NT_args if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args :win9xME_args
@rem Slurp the command line arguments. @rem Slurp the command line arguments.
@@ -56,27 +69,22 @@ set CMD_LINE_ARGS=%$
:execute :execute
@rem Setup the command line @rem Setup the command line
set STARTER_MAIN_CLASS=org.gradle.wrapper.GradleWrapperMain set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set CLASSPATH=%DIRNAME%\gradle\wrapper\gradle-wrapper.jar
set WRAPPER_PROPERTIES=%DIRNAME%\gradle\wrapper\gradle-wrapper.properties
set GRADLE_OPTS=%JAVA_OPTS% %GRADLE_OPTS% -Dorg.gradle.wrapper.properties="%WRAPPER_PROPERTIES%"
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %GRADLE_OPTS% -classpath "%CLASSPATH%" %STARTER_MAIN_CLASS% %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd if "%ERRORLEVEL%"=="0" goto mainEnd
if not "%OS%"=="Windows_NT" echo 1 > nul | choice /n /c:1 :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit "%ERRORLEVEL%" if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b "%ERRORLEVEL%" exit /b 1
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal
:omega :omega

19
pom.xml
View File

@@ -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.2.2-SNAPSHOT</version> <version>2.3.2-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>
@@ -45,9 +45,10 @@
</scm> </scm>
<properties> <properties>
<redis-hosts>localhost:6379,localhost:6380,localhost:6381,localhost:6382,localhost:6383</redis-hosts> <redis-hosts>localhost:6379,localhost:6380,localhost:6381,localhost:6382,localhost:6383,localhost:6384</redis-hosts>
<sentinel-hosts>localhost:26379,localhost:26380</sentinel-hosts> <sentinel-hosts>localhost:26379,localhost:26380,localhost:26381</sentinel-hosts>
<github.global.server>github</github.global.server> <cluster-hosts>localhost:7379,localhost:7380,localhost:7381</cluster-hosts>
<github.global.server>github</github.global.server>
</properties> </properties>
<dependencies> <dependencies>
@@ -59,9 +60,9 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-pool</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool</artifactId> <artifactId>commons-pool2</artifactId>
<version>1.6</version> <version>2.0</version>
<type>jar</type> <type>jar</type>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
@@ -115,11 +116,11 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId> <artifactId>maven-release-plugin</artifactId>
<version>2.4.1</version> <version>2.4.2</version>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-deploy-plugin</artifactId> <artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version> <version>2.8.1</version>
<configuration> <configuration>
<altDeploymentRepository>internal.repo::default::file://${project.build.directory}/mvn-repo</altDeploymentRepository> <altDeploymentRepository>internal.repo::default::file://${project.build.directory}/mvn-repo</altDeploymentRepository>
</configuration> </configuration>

View File

@@ -1,6 +1,5 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.List; import java.util.List;
public interface AdvancedBinaryJedisCommands { public interface AdvancedBinaryJedisCommands {

View File

@@ -1,9 +1,8 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.util.Slowlog;
import java.util.List; import java.util.List;
import redis.clients.util.Slowlog;
public interface AdvancedJedisCommands { public interface AdvancedJedisCommands {
List<String> configGet(String pattern); List<String> configGet(String pattern);

View File

@@ -27,7 +27,7 @@ public interface BasicCommands {
String shutdown(); String shutdown();
String info(); String info();
String info(String section); String info(String section);
String slaveof(String host, int port); String slaveof(String host, int port);
@@ -39,4 +39,6 @@ public interface BasicCommands {
String debug(DebugParams params); String debug(DebugParams params);
String configResetStat(); String configResetStat();
Long waitReplicas(int replicas, long timeout);
} }

View File

@@ -1,8 +1,5 @@
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
*/ */

View File

@@ -1,22 +1,26 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.jedis.Protocol.Command; import static redis.clients.jedis.Protocol.toByteArray;
import redis.clients.jedis.Protocol.Keyword; import static redis.clients.jedis.Protocol.Command.*;
import redis.clients.util.SafeEncoder; import static redis.clients.jedis.Protocol.Keyword.ENCODING;
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;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import static redis.clients.jedis.Protocol.Command.*; import redis.clients.jedis.Protocol.Command;
import static redis.clients.jedis.Protocol.Command.EXISTS; import redis.clients.jedis.Protocol.Keyword;
import static redis.clients.jedis.Protocol.Command.PSUBSCRIBE; import redis.clients.util.SafeEncoder;
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 {
@@ -34,10 +38,16 @@ public class BinaryClient extends Connection {
private long db; private long db;
private boolean isInWatch;
public boolean isInMulti() { public boolean isInMulti() {
return isInMulti; return isInMulti;
} }
public boolean isInWatch() {
return isInWatch;
}
public BinaryClient(final String host) { public BinaryClient(final String host) {
super(host); super(host);
} }
@@ -82,11 +92,11 @@ public class BinaryClient extends Connection {
sendCommand(Command.SET, key, value); sendCommand(Command.SET, key, value);
} }
public void set(final byte[] key, final byte[] value, final byte[] nxxx, final byte[] expx, final long time) { public void set(final byte[] key, final byte[] value, final byte[] nxxx,
sendCommand(Command.SET, key, value, nxxx, expx, toByteArray(time)); final byte[] expx, final long time) {
sendCommand(Command.SET, key, value, nxxx, expx, toByteArray(time));
} }
public void get(final byte[] key) { public void get(final byte[] key) {
sendCommand(Command.GET, key); sendCommand(Command.GET, key);
} }
@@ -377,15 +387,16 @@ public class BinaryClient extends Connection {
sendCommand(ZADD, key, toByteArray(score), member); sendCommand(ZADD, key, toByteArray(score), member);
} }
public void zaddBinary(final byte[] key, Map<Double, byte[]> scoreMembers) { public void zaddBinary(final byte[] key,
final Map<byte[], Double> scoreMembers) {
ArrayList<byte[]> args = new ArrayList<byte[]>( ArrayList<byte[]> args = new ArrayList<byte[]>(
scoreMembers.size() * 2 + 1); scoreMembers.size() * 2 + 1);
args.add(key); args.add(key);
for (Map.Entry<Double, byte[]> entry : scoreMembers.entrySet()) { for (Map.Entry<byte[], Double> entry : scoreMembers.entrySet()) {
args.add(toByteArray(entry.getKey())); args.add(toByteArray(entry.getValue()));
args.add(entry.getValue()); args.add(entry.getKey());
} }
byte[][] argsArray = new byte[args.size()][]; byte[][] argsArray = new byte[args.size()][];
@@ -447,19 +458,23 @@ public class BinaryClient extends Connection {
public void discard() { public void discard() {
sendCommand(DISCARD); sendCommand(DISCARD);
isInMulti = false; isInMulti = false;
isInWatch = false;
} }
public void exec() { public void exec() {
sendCommand(EXEC); sendCommand(EXEC);
isInMulti = false; isInMulti = false;
isInWatch = false;
} }
public void watch(final byte[]... keys) { public void watch(final byte[]... keys) {
sendCommand(WATCH, keys); sendCommand(WATCH, keys);
isInWatch = true;
} }
public void unwatch() { public void unwatch() {
sendCommand(UNWATCH); sendCommand(UNWATCH);
isInWatch = false;
} }
public void sort(final byte[] key) { public void sort(final byte[] key) {
@@ -476,14 +491,14 @@ public class BinaryClient extends Connection {
public void blpop(final byte[][] args) { public void blpop(final byte[][] args) {
sendCommand(BLPOP, args); sendCommand(BLPOP, args);
} }
public void blpop(final int timeout, final byte[]... keys) { public void blpop(final int timeout, final byte[]... keys) {
final List<byte[]> args = new ArrayList<byte[]>(); final List<byte[]> args = new ArrayList<byte[]>();
for (final byte[] arg : keys) { for (final byte[] arg : keys) {
args.add(arg); args.add(arg);
} }
args.add(Protocol.toByteArray(timeout)); args.add(Protocol.toByteArray(timeout));
blpop(args.toArray(new byte[args.size()][])); blpop(args.toArray(new byte[args.size()][]));
} }
public void sort(final byte[] key, final SortingParams sortingParameters, public void sort(final byte[] key, final SortingParams sortingParameters,
@@ -503,14 +518,14 @@ public class BinaryClient extends Connection {
public void brpop(final byte[][] args) { public void brpop(final byte[][] args) {
sendCommand(BRPOP, args); sendCommand(BRPOP, args);
} }
public void brpop(final int timeout, final byte[]... keys) { public void brpop(final int timeout, final byte[]... keys) {
final List<byte[]> args = new ArrayList<byte[]>(); final List<byte[]> args = new ArrayList<byte[]>();
for (final byte[] arg : keys) { for (final byte[] arg : keys) {
args.add(arg); args.add(arg);
} }
args.add(Protocol.toByteArray(timeout)); args.add(Protocol.toByteArray(timeout));
brpop(args.toArray(new byte[args.size()][])); brpop(args.toArray(new byte[args.size()][]));
} }
public void auth(final String password) { public void auth(final String password) {
@@ -543,32 +558,39 @@ public class BinaryClient extends Connection {
} }
public void punsubscribe(final byte[]... patterns) { public void punsubscribe(final byte[]... patterns) {
sendCommand(PUNSUBSCRIBE, patterns); sendCommand(PUNSUBSCRIBE, patterns);
}
public void pubsub(final byte[]... args) {
sendCommand(PUBSUB, args);
} }
public void zcount(final byte[] key, final double min, final double max) { public void zcount(final byte[] key, final double min, final double max) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZCOUNT, key, byteArrayMin, byteArrayMax); sendCommand(ZCOUNT, key, byteArrayMin, byteArrayMax);
} }
public void zcount(final byte[] key, final byte min[], final byte max[]) { public void zcount(final byte[] key, final byte min[], final byte max[]) {
sendCommand(ZCOUNT, key, min, max); sendCommand(ZCOUNT, key, min, max);
} }
public void zcount(final byte[] key, final String min, final String max) { public void zcount(final byte[] key, final String min, final String max) {
sendCommand(ZCOUNT, key, min.getBytes(), max.getBytes()); sendCommand(ZCOUNT, key, min.getBytes(), max.getBytes());
} }
public void zrangeByScore(final byte[] key, final double min, public void zrangeByScore(final byte[] key, final double min,
final double max) { final double max) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax); sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax);
} }
public void zrangeByScore(final byte[] key, final byte[] min, public void zrangeByScore(final byte[] key, final byte[] min,
@@ -577,17 +599,19 @@ public class BinaryClient extends Connection {
} }
public void zrangeByScore(final byte[] key, final String min, public void zrangeByScore(final byte[] key, final String min,
final String max) { final String max) {
sendCommand(ZRANGEBYSCORE, key, min.getBytes(), max.getBytes()); sendCommand(ZRANGEBYSCORE, key, min.getBytes(), max.getBytes());
} }
public void zrevrangeByScore(final byte[] key, final double max, public void zrevrangeByScore(final byte[] key, final double max,
final double min) { final double min) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin); sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin);
} }
public void zrevrangeByScore(final byte[] key, final byte[] max, public void zrevrangeByScore(final byte[] key, final byte[] max,
@@ -596,114 +620,125 @@ public class BinaryClient extends Connection {
} }
public void zrevrangeByScore(final byte[] key, final String max, public void zrevrangeByScore(final byte[] key, final String max,
final String min) { final String min) {
sendCommand(ZREVRANGEBYSCORE, key, max.getBytes(), min.getBytes()); sendCommand(ZREVRANGEBYSCORE, key, max.getBytes(), min.getBytes());
} }
public void zrangeByScore(final byte[] key, final double min, public void zrangeByScore(final byte[] key, final double min,
final double max, final int offset, int count) { final double max, final int offset, int count) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax, sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax, LIMIT.raw,
LIMIT.raw, toByteArray(offset), toByteArray(count)); toByteArray(offset), toByteArray(count));
} }
public void zrangeByScore(final byte[] key, final String min,
final String max, final int offset, int count) {
sendCommand(ZRANGEBYSCORE, key, min.getBytes(), max.getBytes(), public void zrangeByScore(final byte[] key, final String min,
LIMIT.raw, toByteArray(offset), toByteArray(count)); final String max, final int offset, int count) {
sendCommand(ZRANGEBYSCORE, key, min.getBytes(), max.getBytes(),
LIMIT.raw, toByteArray(offset), toByteArray(count));
} }
public void zrevrangeByScore(final byte[] key, final double max, public void zrevrangeByScore(final byte[] key, final double max,
final double min, final int offset, int count) { final double min, final int offset, int count) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin, sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin,
LIMIT.raw, toByteArray(offset), toByteArray(count)); LIMIT.raw, toByteArray(offset), toByteArray(count));
} }
public void zrevrangeByScore(final byte[] key, final String max, public void zrevrangeByScore(final byte[] key, final String max,
final String min, final int offset, int count) { final String min, final int offset, int count) {
sendCommand(ZREVRANGEBYSCORE, key, max.getBytes(), min.getBytes(), sendCommand(ZREVRANGEBYSCORE, key, max.getBytes(), min.getBytes(),
LIMIT.raw, toByteArray(offset), toByteArray(count)); LIMIT.raw, toByteArray(offset), toByteArray(count));
} }
public void zrangeByScoreWithScores(final byte[] key, final double min, public void zrangeByScoreWithScores(final byte[] key, final double min,
final double max) { final double max) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax, sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax,
WITHSCORES.raw); WITHSCORES.raw);
} }
public void zrangeByScoreWithScores(final byte[] key, final String min, public void zrangeByScoreWithScores(final byte[] key, final String min,
final String max) { final String max) {
sendCommand(ZRANGEBYSCORE, key, min.getBytes(), max.getBytes(), sendCommand(ZRANGEBYSCORE, key, min.getBytes(), max.getBytes(),
WITHSCORES.raw); WITHSCORES.raw);
} }
public void zrevrangeByScoreWithScores(final byte[] key, final double max, public void zrevrangeByScoreWithScores(final byte[] key, final double max,
final double min) { final double min) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin, sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin,
WITHSCORES.raw); WITHSCORES.raw);
} }
public void zrevrangeByScoreWithScores(final byte[] key, final String max, public void zrevrangeByScoreWithScores(final byte[] key, final String max,
final String min) { final String min) {
sendCommand(ZREVRANGEBYSCORE, key, max.getBytes(), min.getBytes(), sendCommand(ZREVRANGEBYSCORE, key, max.getBytes(), min.getBytes(),
WITHSCORES.raw); WITHSCORES.raw);
} }
public void zrangeByScoreWithScores(final byte[] key, final double min, public void zrangeByScoreWithScores(final byte[] key, final double min,
final double max, final int offset, final int count) { final double max, final int offset, final int count) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax, sendCommand(ZRANGEBYSCORE, key, byteArrayMin, byteArrayMax, LIMIT.raw,
LIMIT.raw, toByteArray(offset), toByteArray(count), toByteArray(offset), toByteArray(count), WITHSCORES.raw);
WITHSCORES.raw);
} }
public void zrangeByScoreWithScores(final byte[] key, final String min, public void zrangeByScoreWithScores(final byte[] key, final String min,
final String max, final int offset, final int count) { final String max, final int offset, final int count) {
sendCommand(ZRANGEBYSCORE, key, min.getBytes(), max.getBytes(), sendCommand(ZRANGEBYSCORE, key, min.getBytes(), max.getBytes(),
LIMIT.raw, toByteArray(offset), toByteArray(count), LIMIT.raw, toByteArray(offset), toByteArray(count),
WITHSCORES.raw); WITHSCORES.raw);
} }
public void zrevrangeByScoreWithScores(final byte[] key, final double max, public void zrevrangeByScoreWithScores(final byte[] key, final double max,
final double min, final int offset, final int count) { final double min, final int offset, final int count) {
byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf".getBytes() : toByteArray(min); byte byteArrayMin[] = (min == Double.NEGATIVE_INFINITY) ? "-inf"
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf".getBytes() : toByteArray(max); .getBytes() : toByteArray(min);
byte byteArrayMax[] = (max == Double.POSITIVE_INFINITY) ? "+inf"
.getBytes() : toByteArray(max);
sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin, sendCommand(ZREVRANGEBYSCORE, key, byteArrayMax, byteArrayMin,
LIMIT.raw, toByteArray(offset), toByteArray(count), LIMIT.raw, toByteArray(offset), toByteArray(count),
WITHSCORES.raw); WITHSCORES.raw);
} }
public void zrevrangeByScoreWithScores(final byte[] key, final String max, public void zrevrangeByScoreWithScores(final byte[] key, final String max,
final String min, final int offset, final int count) { final String min, final int offset, final int count) {
sendCommand(ZREVRANGEBYSCORE, key, max.getBytes(), min.getBytes(), sendCommand(ZREVRANGEBYSCORE, key, max.getBytes(), min.getBytes(),
LIMIT.raw, toByteArray(offset), toByteArray(count), LIMIT.raw, toByteArray(offset), toByteArray(count),
WITHSCORES.raw); WITHSCORES.raw);
} }
public void zrangeByScore(final byte[] key, final byte[] min, public void zrangeByScore(final byte[] key, final byte[] min,
final byte[] max, final int offset, int count) { final byte[] max, final int offset, int count) {
sendCommand(ZRANGEBYSCORE, key, min, max, LIMIT.raw, sendCommand(ZRANGEBYSCORE, key, min, max, LIMIT.raw,
@@ -746,11 +781,11 @@ public class BinaryClient extends Connection {
public void zremrangeByScore(final byte[] key, final byte[] start, public void zremrangeByScore(final byte[] key, final byte[] start,
final byte[] end) { final byte[] end) {
sendCommand(ZREMRANGEBYSCORE, key, start, end); sendCommand(ZREMRANGEBYSCORE, key, start, end);
} }
public void zremrangeByScore(final byte[] key, final String start, public void zremrangeByScore(final byte[] key, final String start,
final String end) { final String end) {
sendCommand(ZREMRANGEBYSCORE, key, start.getBytes(), end.getBytes()); sendCommand(ZREMRANGEBYSCORE, key, start.getBytes(), end.getBytes());
} }
public void zunionstore(final byte[] dstkey, final byte[]... sets) { public void zunionstore(final byte[] dstkey, final byte[]... sets) {
@@ -816,7 +851,7 @@ public class BinaryClient extends Connection {
public void info() { public void info() {
sendCommand(INFO); sendCommand(INFO);
} }
public void info(final String section) { public void info(final String section) {
sendCommand(INFO, section); sendCommand(INFO, section);
} }
@@ -888,7 +923,7 @@ public class BinaryClient extends Connection {
} }
public void setbit(byte[] key, long offset, boolean value) { public void setbit(byte[] key, long offset, boolean value) {
sendCommand(SETBIT, key, toByteArray(offset), toByteArray(value)); sendCommand(SETBIT, key, toByteArray(offset), toByteArray(value));
} }
public void getbit(byte[] key, long offset) { public void getbit(byte[] key, long offset) {
@@ -913,6 +948,14 @@ public class BinaryClient extends Connection {
super.disconnect(); super.disconnect();
} }
public void resetState() {
if (isInMulti())
discard();
if (isInWatch())
unwatch();
}
private void sendEvalCommand(Command command, byte[] script, private void sendEvalCommand(Command command, byte[] script,
byte[] keyCount, byte[][] params) { byte[] keyCount, byte[][] params) {
@@ -932,7 +975,7 @@ public class BinaryClient extends Connection {
} }
public void eval(byte[] script, int keyCount, byte[]... params) { public void eval(byte[] script, int keyCount, byte[]... params) {
eval(script, toByteArray(keyCount), params); eval(script, toByteArray(keyCount), params);
} }
public void evalsha(byte[] sha1, byte[] keyCount, byte[]... params) { public void evalsha(byte[] sha1, byte[] keyCount, byte[]... params) {
@@ -940,7 +983,7 @@ public class BinaryClient extends Connection {
} }
public void evalsha(byte[] sha1, int keyCount, byte[]... params) { public void evalsha(byte[] sha1, int keyCount, byte[]... params) {
sendEvalCommand(EVALSHA, sha1, toByteArray(keyCount), params); sendEvalCommand(EVALSHA, sha1, toByteArray(keyCount), params);
} }
public void scriptFlush() { public void scriptFlush() {
@@ -993,111 +1036,160 @@ public class BinaryClient extends Connection {
} }
public void bitcount(byte[] key) { public void bitcount(byte[] key) {
sendCommand(BITCOUNT, key); sendCommand(BITCOUNT, key);
} }
public void bitcount(byte[] key, long start, long end) { public void bitcount(byte[] key, long start, long end) {
sendCommand(BITCOUNT, key, toByteArray(start), toByteArray(end)); sendCommand(BITCOUNT, key, toByteArray(start), toByteArray(end));
} }
public void bitop(BitOP op, byte[] destKey, byte[]... srcKeys) { public void bitop(BitOP op, byte[] destKey, byte[]... srcKeys) {
Keyword kw = Keyword.AND; Keyword kw = Keyword.AND;
int len = srcKeys.length; int len = srcKeys.length;
switch (op) { switch (op) {
case AND: case AND:
kw = Keyword.AND; kw = Keyword.AND;
break; break;
case OR: case OR:
kw = Keyword.OR; kw = Keyword.OR;
break; break;
case XOR: case XOR:
kw = Keyword.XOR; kw = Keyword.XOR;
break; break;
case NOT: case NOT:
kw = Keyword.NOT; kw = Keyword.NOT;
len = Math.min(1, len); len = Math.min(1, len);
break; break;
} }
byte[][] bargs = new byte[len + 2][]; byte[][] bargs = new byte[len + 2][];
bargs[0] = kw.raw; bargs[0] = kw.raw;
bargs[1] = destKey; bargs[1] = destKey;
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
bargs[i + 2] = srcKeys[i]; bargs[i + 2] = srcKeys[i];
} }
sendCommand(BITOP, bargs); sendCommand(BITOP, bargs);
} }
public void sentinel(final byte[]... args) { public void sentinel(final byte[]... args) {
sendCommand(SENTINEL, args); sendCommand(SENTINEL, args);
} }
public void dump(final byte[] key) { public void dump(final byte[] key) {
sendCommand(DUMP, key); sendCommand(DUMP, key);
} }
public void restore(final byte[] key, final int ttl, final byte[] serializedValue) { public void restore(final byte[] key, final int ttl,
sendCommand(RESTORE, key, toByteArray(ttl), serializedValue); final byte[] serializedValue) {
sendCommand(RESTORE, key, toByteArray(ttl), serializedValue);
} }
public void pexpire(final byte[] key, final int milliseconds) { public void pexpire(final byte[] key, final int milliseconds) {
sendCommand(PEXPIRE, key, toByteArray(milliseconds)); sendCommand(PEXPIRE, key, toByteArray(milliseconds));
} }
public void pexpireAt(final byte[] key, final long millisecondsTimestamp) { public void pexpireAt(final byte[] key, final long millisecondsTimestamp) {
sendCommand(PEXPIREAT, key, toByteArray(millisecondsTimestamp)); sendCommand(PEXPIREAT, key, toByteArray(millisecondsTimestamp));
} }
public void pttl(final byte[] key) { public void pttl(final byte[] key) {
sendCommand(PTTL, key); sendCommand(PTTL, key);
} }
public void incrByFloat(final byte[] key, final double increment) { public void incrByFloat(final byte[] key, final double increment) {
sendCommand(INCRBYFLOAT, key, toByteArray(increment)); sendCommand(INCRBYFLOAT, key, toByteArray(increment));
} }
public void psetex(final byte[] key, final int milliseconds, final byte[] value) { public void psetex(final byte[] key, final int milliseconds,
sendCommand(PSETEX, key, toByteArray(milliseconds), value); final byte[] value) {
sendCommand(PSETEX, key, toByteArray(milliseconds), value);
} }
public void set(final byte[] key, final byte[] value, final byte[] nxxx) { public void set(final byte[] key, final byte[] value, final byte[] nxxx) {
sendCommand(Command.SET, key, value, nxxx); sendCommand(Command.SET, key, value, nxxx);
} }
public void set(final byte[] key, final byte[] value, final byte[] nxxx, final byte[] expx, final int time) { public void set(final byte[] key, final byte[] value, final byte[] nxxx,
sendCommand(Command.SET, key, value, nxxx, expx, toByteArray(time)); final byte[] expx, final int time) {
sendCommand(Command.SET, key, value, nxxx, expx, toByteArray(time));
} }
public void srandmember(final byte[] key, final int count) { public void srandmember(final byte[] key, final int count) {
sendCommand(SRANDMEMBER, key, toByteArray(count)); sendCommand(SRANDMEMBER, key, toByteArray(count));
} }
public void clientKill(final byte[] client) { public void clientKill(final byte[] client) {
sendCommand(CLIENT, Keyword.KILL.raw, client); sendCommand(CLIENT, Keyword.KILL.raw, client);
} }
public void clientGetname() { public void clientGetname() {
sendCommand(CLIENT, Keyword.GETNAME.raw); sendCommand(CLIENT, Keyword.GETNAME.raw);
} }
public void clientList() { public void clientList() {
sendCommand(CLIENT, Keyword.LIST.raw); sendCommand(CLIENT, Keyword.LIST.raw);
} }
public void clientSetname(final byte[] name) { public void clientSetname(final byte[] name) {
sendCommand(CLIENT, Keyword.SETNAME.raw, name); sendCommand(CLIENT, Keyword.SETNAME.raw, name);
} }
public void time() { public void time() {
sendCommand(TIME); sendCommand(TIME);
} }
public void migrate(final byte[] host, final int port, final byte[] key, final int destinationDb, final int timeout) { public void migrate(final byte[] host, final int port, final byte[] key,
sendCommand(MIGRATE, host, toByteArray(port), key, toByteArray(destinationDb), toByteArray(timeout)); final int destinationDb, final int timeout) {
sendCommand(MIGRATE, host, toByteArray(port), key,
toByteArray(destinationDb), toByteArray(timeout));
} }
public void hincrByFloat(final byte[] key, final byte[] field, double increment) { public void hincrByFloat(final byte[] key, final byte[] field,
sendCommand(HINCRBYFLOAT, key, field, toByteArray(increment)); double increment) {
sendCommand(HINCRBYFLOAT, key, field, toByteArray(increment));
}
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()][]));
}
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()][]));
}
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()][]));
}
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 waitReplicas(int replicas, long timeout) {
sendCommand(WAIT, toByteArray(replicas), toByteArray(timeout));
}
public void cluster(final byte[]... args) {
sendCommand(CLUSTER, args);
}
public void asking() {
sendCommand(Command.ASKING);
} }
} }

View File

@@ -1,17 +1,25 @@
package redis.clients.jedis; package redis.clients.jedis;
import static redis.clients.jedis.Protocol.toByteArray;
import java.net.URI;
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.Set;
import redis.clients.jedis.BinaryClient.LIST_POSITION; import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.exceptions.JedisException; import redis.clients.jedis.exceptions.JedisException;
import redis.clients.util.JedisByteHashMap; import redis.clients.util.JedisByteHashMap;
import redis.clients.util.SafeEncoder; import redis.clients.util.SafeEncoder;
import java.net.URI; public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
import java.util.*; MultiKeyBinaryCommands, AdvancedBinaryJedisCommands,
BinaryScriptingCommands {
import static redis.clients.jedis.Protocol.toByteArray;
public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKeyBinaryCommands, AdvancedBinaryJedisCommands, BinaryScriptingCommands {
protected Client client = null; protected Client client = null;
public BinaryJedis(final String host) { public BinaryJedis(final String host) {
@@ -75,18 +83,23 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
/** /**
* Set the string value as value of the key. The string can't be longer than * Set the string value as value of the key. The string can't be longer than
* 1073741824 bytes (1 GB). * 1073741824 bytes (1 GB).
*
* @param key * @param key
* @param value * @param value
* @param nxxx NX|XX, NX -- Only set the key if it does not already exist. * @param nxxx
* XX -- Only set the key if it already exist. * NX|XX, NX -- Only set the key if it does not already exist. XX
* @param expx EX|PX, expire time units: EX = seconds; PX = milliseconds * -- Only set the key if it already exist.
* @param time expire time in the units of {@param #expx} * @param expx
* EX|PX, expire time units: EX = seconds; PX = milliseconds
* @param time
* expire time in the units of {@param #expx}
* @return Status code reply * @return Status code reply
*/ */
public String set(final byte[] key, final byte[] value, final byte[] nxxx, final byte[] expx, final long time) { public String set(final byte[] key, final byte[] value, final byte[] nxxx,
checkIsInMulti(); final byte[] expx, final long time) {
client.set(key, value, nxxx, expx, time); checkIsInMulti();
return client.getStatusCodeReply(); client.set(key, value, nxxx, expx, time);
return client.getStatusCodeReply();
} }
/** /**
@@ -147,9 +160,9 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
} }
public Long del(final byte[] key) { public Long del(final byte[] key) {
checkIsInMulti(); checkIsInMulti();
client.del(key); client.del(key);
return client.getIntegerReply(); return client.getIntegerReply();
} }
/** /**
@@ -1006,7 +1019,8 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
* @return Multi bulk reply, specifically a list of elements in the * @return Multi bulk reply, specifically a list of elements in the
* specified range. * specified range.
*/ */
public List<byte[]> lrange(final byte[] key, final long start, final long end) { public List<byte[]> lrange(final byte[] key, final long start,
final long end) {
checkIsInMulti(); checkIsInMulti();
client.lrange(key, start, end); client.lrange(key, start, end);
return client.getBinaryMultiBulkReply(); return client.getBinaryMultiBulkReply();
@@ -1468,11 +1482,11 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
client.srandmember(key); client.srandmember(key);
return client.getBinaryBulkReply(); return client.getBinaryBulkReply();
} }
public List<byte[]> srandmember(final byte[] key, final int count) { public List<byte[]> srandmember(final byte[] key, final int count) {
checkIsInMulti(); checkIsInMulti();
client.srandmember(key, count); client.srandmember(key, count);
return client.getBinaryMultiBulkReply(); return client.getBinaryMultiBulkReply();
} }
/** /**
@@ -1502,7 +1516,7 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Long zadd(final byte[] key, final Map<Double, byte[]> scoreMembers) { public Long zadd(final byte[] key, final Map<byte[], Double> scoreMembers) {
checkIsInMulti(); checkIsInMulti();
client.zaddBinary(key, scoreMembers); client.zaddBinary(key, scoreMembers);
return client.getIntegerReply(); return client.getIntegerReply();
@@ -1685,13 +1699,9 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
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);
try { client.multi();
client.multi(); jedisTransaction.execute();
jedisTransaction.execute(); results = jedisTransaction.exec();
results = jedisTransaction.exec();
} catch (Exception ex) {
jedisTransaction.discard();
}
return results; return results;
} }
@@ -1710,6 +1720,11 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
client.disconnect(); client.disconnect();
} }
public void resetState() {
client.resetState();
client.getAll();
}
public String watch(final byte[]... keys) { public String watch(final byte[]... keys) {
client.watch(keys); client.watch(keys);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
@@ -2044,43 +2059,43 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
} }
public List<byte[]> blpop(byte[] arg) { public List<byte[]> blpop(byte[] arg) {
checkIsInMulti(); checkIsInMulti();
byte[][] args = new byte[1][]; byte[][] args = new byte[1][];
args[0] = arg; args[0] = arg;
client.blpop(args); client.blpop(args);
client.setTimeoutInfinite(); client.setTimeoutInfinite();
final List<byte[]> multiBulkReply = client.getBinaryMultiBulkReply(); final List<byte[]> multiBulkReply = client.getBinaryMultiBulkReply();
client.rollbackTimeout(); client.rollbackTimeout();
return multiBulkReply; return multiBulkReply;
} }
public List<byte[]> brpop(byte[] arg) { public List<byte[]> brpop(byte[] arg) {
checkIsInMulti(); checkIsInMulti();
byte[][] args = new byte[1][]; byte[][] args = new byte[1][];
args[0] = arg; args[0] = arg;
client.brpop(args); client.brpop(args);
client.setTimeoutInfinite(); client.setTimeoutInfinite();
final List<byte[]> multiBulkReply = client.getBinaryMultiBulkReply(); final List<byte[]> multiBulkReply = client.getBinaryMultiBulkReply();
client.rollbackTimeout(); client.rollbackTimeout();
return multiBulkReply; return multiBulkReply;
} }
public List<byte[]> blpop(byte[]... args) { public List<byte[]> blpop(byte[]... args) {
checkIsInMulti(); checkIsInMulti();
client.blpop(args); client.blpop(args);
client.setTimeoutInfinite(); client.setTimeoutInfinite();
final List<byte[]> multiBulkReply = client.getBinaryMultiBulkReply(); final List<byte[]> multiBulkReply = client.getBinaryMultiBulkReply();
client.rollbackTimeout(); client.rollbackTimeout();
return multiBulkReply; return multiBulkReply;
} }
public List<byte[]> brpop(byte[]... args) { public List<byte[]> brpop(byte[]... args) {
checkIsInMulti(); checkIsInMulti();
client.brpop(args); client.brpop(args);
client.setTimeoutInfinite(); client.setTimeoutInfinite();
final List<byte[]> multiBulkReply = client.getBinaryMultiBulkReply(); final List<byte[]> multiBulkReply = client.getBinaryMultiBulkReply();
client.rollbackTimeout(); client.rollbackTimeout();
return multiBulkReply; return multiBulkReply;
} }
/** /**
@@ -2126,15 +2141,15 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
} }
public Long zcount(final byte[] key, final double min, final double max) { public Long zcount(final byte[] key, final double min, final double max) {
return zcount(key, toByteArray(min), toByteArray(max)); return zcount(key, toByteArray(min), toByteArray(max));
} }
public Long zcount(final byte[] key, final byte[] min, final byte[] max) { public Long zcount(final byte[] key, final byte[] min, final byte[] max) {
checkIsInMulti(); checkIsInMulti();
client.zcount(key, min, max); client.zcount(key, min, max);
return client.getIntegerReply(); return client.getIntegerReply();
} }
/** /**
* Return the all the elements in the sorted set at key with a score between * Return the all the elements in the sorted set at key with a score between
* min and max (including elements with score equal to min or max). * min and max (including elements with score equal to min or max).
@@ -2194,7 +2209,7 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
public Set<byte[]> zrangeByScore(final byte[] key, final double min, public Set<byte[]> zrangeByScore(final byte[] key, final double min,
final double max) { final double max) {
return zrangeByScore(key, toByteArray(min), toByteArray(max)); return zrangeByScore(key, toByteArray(min), toByteArray(max));
} }
public Set<byte[]> zrangeByScore(final byte[] key, final byte[] min, public Set<byte[]> zrangeByScore(final byte[] key, final byte[] min,
final byte[] max) { final byte[] max) {
@@ -2261,15 +2276,16 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
*/ */
public Set<byte[]> zrangeByScore(final byte[] key, final double min, public Set<byte[]> zrangeByScore(final byte[] key, final double min,
final double max, final int offset, final int count) { final double max, final int offset, final int count) {
return zrangeByScore(key, toByteArray(min),toByteArray(max),offset, count); return zrangeByScore(key, toByteArray(min), toByteArray(max), offset,
count);
} }
public Set<byte[]> zrangeByScore(final byte[] key, final byte[] min, public Set<byte[]> zrangeByScore(final byte[] key, final byte[] min,
final byte[] max, final int offset, final int count) { final byte[] max, final int offset, final int count) {
checkIsInMulti(); checkIsInMulti();
client.zrangeByScore(key, min, max, offset, count); client.zrangeByScore(key, min, max, offset, count);
return new LinkedHashSet<byte[]>(client.getBinaryMultiBulkReply()); return new LinkedHashSet<byte[]>(client.getBinaryMultiBulkReply());
} }
/** /**
* Return the all the elements in the sorted set at key with a score between * Return the all the elements in the sorted set at key with a score between
@@ -2331,14 +2347,14 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
final double min, final double max) { final double min, final double max) {
return zrangeByScoreWithScores(key, toByteArray(min), toByteArray(max)); return zrangeByScoreWithScores(key, toByteArray(min), toByteArray(max));
} }
public Set<Tuple> zrangeByScoreWithScores(final byte[] key, public Set<Tuple> zrangeByScoreWithScores(final byte[] key,
final byte[] min, final byte[] max) { final byte[] min, final byte[] max) {
checkIsInMulti(); checkIsInMulti();
client.zrangeByScoreWithScores(key, min, max); client.zrangeByScoreWithScores(key, min, max);
Set<Tuple> set = getBinaryTupledSet(); Set<Tuple> set = getBinaryTupledSet();
return set; return set;
} }
/** /**
* Return the all the elements in the sorted set at key with a score between * Return the all the elements in the sorted set at key with a score between
@@ -2399,17 +2415,18 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
public Set<Tuple> zrangeByScoreWithScores(final byte[] key, public Set<Tuple> zrangeByScoreWithScores(final byte[] key,
final double min, final double max, final int offset, final double min, final double max, final int offset,
final int count) { final int count) {
return zrangeByScoreWithScores(key, toByteArray(min), toByteArray(max), offset, count); return zrangeByScoreWithScores(key, toByteArray(min), toByteArray(max),
offset, count);
} }
public Set<Tuple> zrangeByScoreWithScores(final byte[] key, public Set<Tuple> zrangeByScoreWithScores(final byte[] key,
final byte[] min, final byte[] max, final int offset, final byte[] min, final byte[] max, final int offset,
final int count) { final int count) {
checkIsInMulti(); checkIsInMulti();
client.zrangeByScoreWithScores(key, min, max, offset, count); client.zrangeByScoreWithScores(key, min, max, offset, count);
Set<Tuple> set = getBinaryTupledSet(); Set<Tuple> set = getBinaryTupledSet();
return set; return set;
} }
private Set<Tuple> getBinaryTupledSet() { private Set<Tuple> getBinaryTupledSet() {
checkIsInMulti(); checkIsInMulti();
@@ -2437,29 +2454,32 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
public Set<byte[]> zrevrangeByScore(final byte[] key, final double max, public Set<byte[]> zrevrangeByScore(final byte[] key, final double max,
final double min, final int offset, final int count) { final double min, final int offset, final int count) {
return zrevrangeByScore(key, toByteArray(max), toByteArray(min), offset, count); return zrevrangeByScore(key, toByteArray(max), toByteArray(min),
offset, count);
} }
public Set<byte[]> zrevrangeByScore(final byte[] key, final byte[] max, public Set<byte[]> zrevrangeByScore(final byte[] key, final byte[] max,
final byte[] min, final int offset, final int count) { final byte[] min, final int offset, final int count) {
checkIsInMulti(); checkIsInMulti();
client.zrevrangeByScore(key, max, min, offset, count); client.zrevrangeByScore(key, max, min, offset, count);
return new LinkedHashSet<byte[]>(client.getBinaryMultiBulkReply()); return new LinkedHashSet<byte[]>(client.getBinaryMultiBulkReply());
} }
public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key,
final double max, final double min) { final double max, final double min) {
return zrevrangeByScoreWithScores(key, toByteArray(max), toByteArray(min)); return zrevrangeByScoreWithScores(key, toByteArray(max),
toByteArray(min));
} }
public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key,
final double max, final double min, final int offset, final double max, final double min, final int offset,
final int count) { final int count) {
return zrevrangeByScoreWithScores(key, toByteArray(max), toByteArray(min), offset, count); return zrevrangeByScoreWithScores(key, toByteArray(max),
toByteArray(min), offset, count);
} }
public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key, public Set<Tuple> zrevrangeByScoreWithScores(final byte[] key,
final byte[] max, final byte[] min) { final byte[] max, final byte[] min) {
checkIsInMulti(); checkIsInMulti();
client.zrevrangeByScoreWithScores(key, max, min); client.zrevrangeByScoreWithScores(key, max, min);
Set<Tuple> set = getBinaryTupledSet(); Set<Tuple> set = getBinaryTupledSet();
@@ -2473,7 +2493,7 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
client.zrevrangeByScoreWithScores(key, max, min, offset, count); client.zrevrangeByScoreWithScores(key, max, min, offset, count);
Set<Tuple> set = getBinaryTupledSet(); Set<Tuple> set = getBinaryTupledSet();
return set; return set;
} }
/** /**
* Remove all elements in the sorted set at key with rank between start and * Remove all elements in the sorted set at key with rank between start and
@@ -2488,7 +2508,8 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
* operation * operation
* *
*/ */
public Long zremrangeByRank(final byte[] key, final long start, final long end) { public Long zremrangeByRank(final byte[] key, final long start,
final long end) {
checkIsInMulti(); checkIsInMulti();
client.zremrangeByRank(key, start, end); client.zremrangeByRank(key, start, end);
return client.getIntegerReply(); return client.getIntegerReply();
@@ -2512,13 +2533,13 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
final double end) { final double end) {
return zremrangeByScore(key, toByteArray(start), toByteArray(end)); return zremrangeByScore(key, toByteArray(start), toByteArray(end));
} }
public Long zremrangeByScore(final byte[] key, final byte[] start, public Long zremrangeByScore(final byte[] key, final byte[] start,
final byte[] end) { final byte[] end) {
checkIsInMulti(); checkIsInMulti();
client.zremrangeByScore(key, start, end); client.zremrangeByScore(key, start, end);
return client.getIntegerReply(); return client.getIntegerReply();
} }
/** /**
* Creates a union or intersection of N sorted sets given by keys k1 through * Creates a union or intersection of N sorted sets given by keys k1 through
@@ -2842,7 +2863,7 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
client.info(); client.info();
return client.getBulkReply(); return client.getBulkReply();
} }
public String info(final String section) { public String info(final String section) {
client.info(section); client.info(section);
return client.getBulkReply(); return client.getBulkReply();
@@ -2860,6 +2881,7 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
*/ */
public void monitor(final JedisMonitor jedisMonitor) { public void monitor(final JedisMonitor jedisMonitor) {
client.monitor(); client.monitor();
client.getStatusCodeReply();
jedisMonitor.proceed(client); jedisMonitor.proceed(client);
} }
@@ -3077,8 +3099,8 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
} }
public Boolean setbit(byte[] key, long offset, byte[] value) { public Boolean setbit(byte[] key, long offset, byte[] value) {
client.setbit(key, offset, value); client.setbit(key, offset, value);
return client.getIntegerReply() == 1; return client.getIntegerReply() == 1;
} }
/** /**
@@ -3139,12 +3161,13 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
private byte[][] getParams(List<byte[]> keys, List<byte[]> args) { private byte[][] getParams(List<byte[]> keys, List<byte[]> args) {
int keyCount = keys.size(); int keyCount = keys.size();
int argCount = args.size();
byte[][] params = new byte[keyCount + args.size()][]; byte[][] params = new byte[keyCount + args.size()][];
for (int i = 0; i < keyCount; i++) for (int i = 0; i < keyCount; i++)
params[i] = keys.get(i); params[i] = keys.get(i);
for (int i = 0; i < keys.size(); i++) for (int i = 0; i < argCount; i++)
params[keyCount + i] = args.get(i); params[keyCount + i] = args.get(i);
return params; return params;
@@ -3157,44 +3180,44 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
} }
public Object eval(byte[] script, int keyCount, byte[]... params) { public Object eval(byte[] script, int keyCount, byte[]... params) {
client.setTimeoutInfinite(); client.setTimeoutInfinite();
client.eval(script, SafeEncoder.encode(Integer.toString(keyCount)), params); client.eval(script, SafeEncoder.encode(Integer.toString(keyCount)),
return client.getOne(); params);
return client.getOne();
} }
public Object eval(byte[] script) { public Object eval(byte[] script) {
client.setTimeoutInfinite(); client.setTimeoutInfinite();
client.eval(script, 0); client.eval(script, 0);
return client.getOne(); return client.getOne();
} }
public Object evalsha(byte[] sha1) { public Object evalsha(byte[] sha1) {
client.setTimeoutInfinite(); client.setTimeoutInfinite();
client.evalsha(sha1, 0); client.evalsha(sha1, 0);
return client.getOne(); return client.getOne();
} }
public Object evalsha(byte[] sha1, List<byte[]> keys, List<byte[]> args) {
int keyCount = keys == null ? 0 : keys.size(); public Object evalsha(byte[] sha1, List<byte[]> keys, List<byte[]> args) {
int argCount = args == null ? 0 : args.size();
byte[][] params = new byte[keyCount + argCount][]; int keyCount = keys == null ? 0 : keys.size();
int argCount = args == null ? 0 : args.size();
for (int i = 0; i < keyCount; i++) byte[][] params = new byte[keyCount + argCount][];
params[i] = keys.get(i);
for (int i = 0; i < argCount; i++) for (int i = 0; i < keyCount; i++)
params[keyCount + i] = args.get(i); params[i] = keys.get(i);
for (int i = 0; i < argCount; i++)
params[keyCount + i] = args.get(i);
return evalsha(sha1, keyCount, params); return evalsha(sha1, keyCount, params);
} }
public Object evalsha(byte[] sha1, int keyCount, byte[]... params) { public Object evalsha(byte[] sha1, int keyCount, byte[]... params) {
client.setTimeoutInfinite(); client.setTimeoutInfinite();
client.evalsha(sha1, keyCount, params); client.evalsha(sha1, keyCount, params);
return client.getOne(); return client.getOne();
} }
public String scriptFlush() { public String scriptFlush() {
@@ -3204,7 +3227,7 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
public List<Long> scriptExists(byte[]... sha1) { public List<Long> scriptExists(byte[]... sha1) {
client.scriptExists(sha1); client.scriptExists(sha1);
return client.getIntegerMultiBulkReply(); return client.getIntegerMultiBulkReply();
} }
public byte[] scriptLoad(byte[] script) { public byte[] scriptLoad(byte[] script) {
@@ -3236,133 +3259,151 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
client.slowlogGet(entries); client.slowlogGet(entries);
return client.getBinaryMultiBulkReply(); return client.getBinaryMultiBulkReply();
} }
public Long objectRefcount(byte[] key) {
client.objectRefcount(key);
return client.getIntegerReply();
}
public byte[] objectEncoding(byte[] key) {
client.objectEncoding(key);
return client.getBinaryBulkReply();
}
public Long objectIdletime(byte[] key) { public Long objectRefcount(byte[] key) {
client.objectIdletime(key); client.objectRefcount(key);
return client.getIntegerReply(); return client.getIntegerReply();
} }
public byte[] objectEncoding(byte[] key) {
client.objectEncoding(key);
return client.getBinaryBulkReply();
}
public Long objectIdletime(byte[] key) {
client.objectIdletime(key);
return client.getIntegerReply();
}
public Long bitcount(final byte[] key) { public Long bitcount(final byte[] key) {
client.bitcount(key); client.bitcount(key);
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Long bitcount(final byte[] key, long start, long end) { public Long bitcount(final byte[] key, long start, long end) {
client.bitcount(key, start, end); client.bitcount(key, start, end);
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Long bitop(BitOP op, final byte[] destKey, byte[]... srcKeys) { public Long bitop(BitOP op, final byte[] destKey, byte[]... srcKeys) {
client.bitop(op, destKey, srcKeys); client.bitop(op, destKey, srcKeys);
return client.getIntegerReply(); return client.getIntegerReply();
} }
public byte[] dump(final byte[] key) { public byte[] dump(final byte[] key) {
checkIsInMulti(); checkIsInMulti();
client.dump(key); client.dump(key);
return client.getBinaryBulkReply(); return client.getBinaryBulkReply();
} }
public String restore(final byte[] key, final int ttl, final byte[] serializedValue) { public String restore(final byte[] key, final int ttl,
checkIsInMulti(); final byte[] serializedValue) {
client.restore(key, ttl, serializedValue); checkIsInMulti();
return client.getStatusCodeReply(); client.restore(key, ttl, serializedValue);
return client.getStatusCodeReply();
} }
public Long pexpire(final byte[] key, final int milliseconds) { public Long pexpire(final byte[] key, final int milliseconds) {
checkIsInMulti(); checkIsInMulti();
client.pexpire(key, milliseconds); client.pexpire(key, milliseconds);
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Long pexpireAt(final byte[] key, final long millisecondsTimestamp) { public Long pexpireAt(final byte[] key, final long millisecondsTimestamp) {
checkIsInMulti(); checkIsInMulti();
client.pexpireAt(key, millisecondsTimestamp); client.pexpireAt(key, millisecondsTimestamp);
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Long pttl(final byte[] key) { public Long pttl(final byte[] key) {
checkIsInMulti(); checkIsInMulti();
client.pttl(key); client.pttl(key);
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Double incrByFloat(final byte[] key, final double increment) { public Double incrByFloat(final byte[] key, final double increment) {
checkIsInMulti(); checkIsInMulti();
client.incrByFloat(key, increment); client.incrByFloat(key, increment);
String relpy = client.getBulkReply(); String relpy = client.getBulkReply();
return (relpy != null ? new Double(relpy) : null); return (relpy != null ? new Double(relpy) : null);
} }
public String psetex(final byte[] key, final int milliseconds, final byte[] value) { public String psetex(final byte[] key, final int milliseconds,
checkIsInMulti(); final byte[] value) {
client.psetex(key, milliseconds, value); checkIsInMulti();
return client.getStatusCodeReply(); client.psetex(key, milliseconds, value);
return client.getStatusCodeReply();
} }
public String set(final byte[] key, final byte[] value, final byte[] nxxx) { public String set(final byte[] key, final byte[] value, final byte[] nxxx) {
checkIsInMulti(); checkIsInMulti();
client.set(key, value, nxxx); client.set(key, value, nxxx);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
} }
public String set(final byte[] key, final byte[] value, final byte[] nxxx, final byte[] expx, final int time) { public String set(final byte[] key, final byte[] value, final byte[] nxxx,
checkIsInMulti(); final byte[] expx, final int time) {
client.set(key, value, nxxx, expx, time); checkIsInMulti();
return client.getStatusCodeReply(); client.set(key, value, nxxx, expx, time);
return client.getStatusCodeReply();
} }
public String clientKill(final byte[] client) { public String clientKill(final byte[] client) {
checkIsInMulti(); checkIsInMulti();
this.client.clientKill(client); this.client.clientKill(client);
return this.client.getStatusCodeReply(); return this.client.getStatusCodeReply();
} }
public String clientGetname() { public String clientGetname() {
checkIsInMulti(); checkIsInMulti();
client.clientGetname(); client.clientGetname();
return client.getBulkReply(); return client.getBulkReply();
} }
public String clientList() { public String clientList() {
checkIsInMulti(); checkIsInMulti();
client.clientList(); client.clientList();
return client.getBulkReply(); return client.getBulkReply();
} }
public String clientSetname(final byte[] name) { public String clientSetname(final byte[] name) {
checkIsInMulti(); checkIsInMulti();
client.clientSetname(name); client.clientSetname(name);
return client.getBulkReply(); return client.getBulkReply();
} }
public List<String> time() { public List<String> time() {
checkIsInMulti(); checkIsInMulti();
client.time(); client.time();
return client.getMultiBulkReply(); return client.getMultiBulkReply();
} }
public String migrate(final byte[] host, final int port, final byte[] key, final int destinationDb, final int timeout) { public String migrate(final byte[] host, final int port, final byte[] key,
checkIsInMulti(); final int destinationDb, final int timeout) {
client.migrate(host, port, key, destinationDb, timeout); checkIsInMulti();
return client.getStatusCodeReply(); client.migrate(host, port, key, destinationDb, timeout);
return client.getStatusCodeReply();
} }
public Double hincrByFloat(final byte[] key, final byte[] field, double increment) { public Double hincrByFloat(final byte[] key, final byte[] field,
checkIsInMulti(); double increment) {
client.hincrByFloat(key, field, increment); checkIsInMulti();
String relpy = client.getBulkReply(); client.hincrByFloat(key, field, increment);
return (relpy != null ? new Double(relpy) : null); String relpy = client.getBulkReply();
return (relpy != null ? new Double(relpy) : null);
}
/**
* Syncrhonous replication of Redis as described here:
* http://antirez.com/news/66
*
* Since Java Object class has implemented "wait" method, we cannot use it,
* so I had to change the name of the method. Sorry :S
*/
public Long waitReplicas(int replicas, long timeout) {
checkIsInMulti();
client.waitReplicas(replicas, timeout);
return client.getIntegerReply();
} }
} }

View File

@@ -5,8 +5,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
/** /**
* Common interface for sharded and non-sharded BinaryJedis * Common interface for sharded and non-sharded BinaryJedis
*/ */
@@ -116,8 +114,8 @@ public interface BinaryJedisCommands {
Long strlen(byte[] key); Long strlen(byte[] key);
Long zadd(byte[] key, double score, byte[] member); Long zadd(byte[] key, double score, byte[] member);
Long zadd(byte[] key, Map<Double, byte[]> scoreMembers); Long zadd(byte[] key, Map<byte[], Double> scoreMembers);
Set<byte[]> zrange(byte[] key, long start, long end); Set<byte[]> zrange(byte[] key, long start, long end);
@@ -159,45 +157,45 @@ public interface BinaryJedisCommands {
Set<byte[]> zrevrangeByScore(byte[] key, byte[] max, byte[] min); Set<byte[]> zrevrangeByScore(byte[] key, byte[] max, byte[] min);
Set<byte[]> zrangeByScore(byte[] key, byte[] min, byte[] max, int offset, Set<byte[]> zrangeByScore(byte[] key, byte[] min, byte[] max, int offset,
int count); int count);
Set<byte[]> zrevrangeByScore(byte[] key, double max, double min, Set<byte[]> zrevrangeByScore(byte[] key, double max, double min,
int offset, int count); int offset, int count);
Set<Tuple> zrangeByScoreWithScores(byte[] key, double min, double max); Set<Tuple> zrangeByScoreWithScores(byte[] key, double min, double max);
Set<Tuple> zrevrangeByScoreWithScores(byte[] key, double max, double min); Set<Tuple> zrevrangeByScoreWithScores(byte[] key, double max, double min);
Set<Tuple> zrangeByScoreWithScores(byte[] key, double min, double max, Set<Tuple> zrangeByScoreWithScores(byte[] key, double min, double max,
int offset, int count); int offset, int count);
Set<byte[]> zrevrangeByScore(byte[] key, byte[] max, byte[] min, Set<byte[]> zrevrangeByScore(byte[] key, byte[] max, byte[] min,
int offset, int count); int offset, int count);
Set<Tuple> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max); Set<Tuple> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max);
Set<Tuple> zrevrangeByScoreWithScores(byte[] key, byte[] max, byte[] min); Set<Tuple> zrevrangeByScoreWithScores(byte[] key, byte[] max, byte[] min);
Set<Tuple> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max, Set<Tuple> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max,
int offset, int count); int offset, int count);
Set<Tuple> zrevrangeByScoreWithScores(byte[] key, double max, double min, Set<Tuple> zrevrangeByScoreWithScores(byte[] key, double max, double min,
int offset, int count); int offset, int count);
Set<Tuple> zrevrangeByScoreWithScores(byte[] key, byte[] max, byte[] min, Set<Tuple> zrevrangeByScoreWithScores(byte[] key, byte[] max, byte[] min,
int offset, int count); int offset, int count);
Long zremrangeByRank(byte[] key, long start, long end); Long zremrangeByRank(byte[] key, long start, long end);
Long zremrangeByScore(byte[] key, double start, double end); Long zremrangeByScore(byte[] key, double start, double end);
Long zremrangeByScore(byte[] key, byte[] start, byte[] end); Long zremrangeByScore(byte[] key, byte[] start, byte[] end);
Long linsert(byte[] key, Client.LIST_POSITION where, byte[] pivot, Long linsert(byte[] key, Client.LIST_POSITION where, byte[] pivot,
byte[] value); byte[] value);
Long lpushx(byte[] key, byte[]... arg); Long lpushx(byte[] key, byte[]... arg);
Long rpushx(byte[] key, byte[]... arg); Long rpushx(byte[] key, byte[]... arg);
List<byte[]> blpop(byte[] arg); List<byte[]> blpop(byte[] arg);

View File

@@ -19,7 +19,7 @@ public abstract class BinaryJedisPubSub {
public abstract void onMessage(byte[] channel, byte[] message); public abstract void onMessage(byte[] channel, byte[] message);
public abstract void onPMessage(byte[] pattern, byte[] channel, public abstract void onPMessage(byte[] pattern, byte[] channel,
byte[] message); byte[] message);
public abstract void onSubscribe(byte[] channel, int subscribedChannels); public abstract void onSubscribe(byte[] channel, int subscribedChannels);
@@ -30,91 +30,91 @@ public abstract class BinaryJedisPubSub {
public abstract void onPSubscribe(byte[] pattern, int subscribedChannels); public abstract void onPSubscribe(byte[] pattern, int subscribedChannels);
public void unsubscribe() { public void unsubscribe() {
client.unsubscribe(); client.unsubscribe();
client.flush(); client.flush();
} }
public void unsubscribe(byte[]... channels) { public void unsubscribe(byte[]... channels) {
client.unsubscribe(channels); client.unsubscribe(channels);
client.flush(); client.flush();
} }
public void subscribe(byte[]... channels) { public void subscribe(byte[]... channels) {
client.subscribe(channels); client.subscribe(channels);
client.flush(); client.flush();
} }
public void psubscribe(byte[]... patterns) { public void psubscribe(byte[]... patterns) {
client.psubscribe(patterns); client.psubscribe(patterns);
client.flush(); client.flush();
} }
public void punsubscribe() { public void punsubscribe() {
client.punsubscribe(); client.punsubscribe();
client.flush(); client.flush();
} }
public void punsubscribe(byte[]... patterns) { public void punsubscribe(byte[]... patterns) {
client.punsubscribe(patterns); client.punsubscribe(patterns);
client.flush(); client.flush();
} }
public boolean isSubscribed() { public boolean isSubscribed() {
return subscribedChannels > 0; return subscribedChannels > 0;
} }
public void proceedWithPatterns(Client client, byte[]... patterns) { public void proceedWithPatterns(Client client, byte[]... patterns) {
this.client = client; this.client = client;
client.psubscribe(patterns); client.psubscribe(patterns);
process(client); process(client);
} }
public void proceed(Client client, byte[]... channels) { public void proceed(Client client, byte[]... channels) {
this.client = client; this.client = client;
client.subscribe(channels); client.subscribe(channels);
process(client); process(client);
} }
private void process(Client client) { private void process(Client client) {
do { do {
List<Object> reply = client.getObjectMultiBulkReply(); List<Object> reply = client.getObjectMultiBulkReply();
final Object firstObj = reply.get(0); final Object firstObj = reply.get(0);
if (!(firstObj instanceof byte[])) { if (!(firstObj instanceof byte[])) {
throw new JedisException("Unknown message type: " + firstObj); throw new JedisException("Unknown message type: " + firstObj);
} }
final byte[] resp = (byte[]) firstObj; final byte[] resp = (byte[]) firstObj;
if (Arrays.equals(SUBSCRIBE.raw, resp)) { if (Arrays.equals(SUBSCRIBE.raw, resp)) {
subscribedChannels = ((Long) reply.get(2)).intValue(); subscribedChannels = ((Long) reply.get(2)).intValue();
final byte[] bchannel = (byte[]) reply.get(1); final byte[] bchannel = (byte[]) reply.get(1);
onSubscribe(bchannel, subscribedChannels); onSubscribe(bchannel, subscribedChannels);
} else if (Arrays.equals(UNSUBSCRIBE.raw, resp)) { } else if (Arrays.equals(UNSUBSCRIBE.raw, resp)) {
subscribedChannels = ((Long) reply.get(2)).intValue(); subscribedChannels = ((Long) reply.get(2)).intValue();
final byte[] bchannel = (byte[]) reply.get(1); final byte[] bchannel = (byte[]) reply.get(1);
onUnsubscribe(bchannel, subscribedChannels); onUnsubscribe(bchannel, subscribedChannels);
} else if (Arrays.equals(MESSAGE.raw, resp)) { } else if (Arrays.equals(MESSAGE.raw, resp)) {
final byte[] bchannel = (byte[]) reply.get(1); final byte[] bchannel = (byte[]) reply.get(1);
final byte[] bmesg = (byte[]) reply.get(2); final byte[] bmesg = (byte[]) reply.get(2);
onMessage(bchannel, bmesg); onMessage(bchannel, bmesg);
} else if (Arrays.equals(PMESSAGE.raw, resp)) { } else if (Arrays.equals(PMESSAGE.raw, resp)) {
final byte[] bpattern = (byte[]) reply.get(1); final byte[] bpattern = (byte[]) reply.get(1);
final byte[] bchannel = (byte[]) reply.get(2); final byte[] bchannel = (byte[]) reply.get(2);
final byte[] bmesg = (byte[]) reply.get(3); final byte[] bmesg = (byte[]) reply.get(3);
onPMessage(bpattern, bchannel, bmesg); onPMessage(bpattern, bchannel, bmesg);
} else if (Arrays.equals(PSUBSCRIBE.raw, resp)) { } else if (Arrays.equals(PSUBSCRIBE.raw, resp)) {
subscribedChannels = ((Long) reply.get(2)).intValue(); subscribedChannels = ((Long) reply.get(2)).intValue();
final byte[] bpattern = (byte[]) reply.get(1); final byte[] bpattern = (byte[]) reply.get(1);
onPSubscribe(bpattern, subscribedChannels); onPSubscribe(bpattern, subscribedChannels);
} else if (Arrays.equals(PUNSUBSCRIBE.raw, resp)) { } else if (Arrays.equals(PUNSUBSCRIBE.raw, resp)) {
subscribedChannels = ((Long) reply.get(2)).intValue(); subscribedChannels = ((Long) reply.get(2)).intValue();
final byte[] bpattern = (byte[]) reply.get(1); final byte[] bpattern = (byte[]) reply.get(1);
onPUnsubscribe(bpattern, subscribedChannels); onPUnsubscribe(bpattern, subscribedChannels);
} else { } else {
throw new JedisException("Unknown message type: " + firstObj); throw new JedisException("Unknown message type: " + firstObj);
} }
} while (isSubscribed()); } while (isSubscribed());
} }
public int getSubscribedChannels() { public int getSubscribedChannels() {
return subscribedChannels; return subscribedChannels;
} }
} }

View File

@@ -67,7 +67,7 @@ public interface BinaryRedisPipeline {
Response<byte[]> lindex(byte[] key, long index); Response<byte[]> lindex(byte[] key, long index);
Response<Long> linsert(byte[] key, BinaryClient.LIST_POSITION where, Response<Long> linsert(byte[] key, BinaryClient.LIST_POSITION where,
byte[] pivot, byte[] value); byte[] pivot, byte[] value);
Response<Long> llen(byte[] key); Response<Long> llen(byte[] key);
@@ -117,8 +117,7 @@ public interface BinaryRedisPipeline {
Response<List<byte[]>> sort(byte[] key); Response<List<byte[]>> sort(byte[] key);
Response<List<byte[]>> sort(byte[] key, Response<List<byte[]>> sort(byte[] key, SortingParams sortingParameters);
SortingParams sortingParameters);
Response<byte[]> spop(byte[] key); Response<byte[]> spop(byte[] key);
@@ -144,53 +143,49 @@ public interface BinaryRedisPipeline {
Response<Set<byte[]>> zrange(byte[] key, long start, long end); Response<Set<byte[]>> zrange(byte[] key, long start, long end);
Response<Set<byte[]>> zrangeByScore(byte[] key, double min, Response<Set<byte[]>> zrangeByScore(byte[] key, double min, double max);
double max);
Response<Set<byte[]>> zrangeByScore(byte[] key, byte[] min, Response<Set<byte[]>> zrangeByScore(byte[] key, byte[] min, byte[] max);
byte[] max);
Response<Set<byte[]>> zrangeByScore(byte[] key, double min, Response<Set<byte[]>> zrangeByScore(byte[] key, double min, double max,
double max, int offset, int count); int offset, int count);
Response<Set<byte[]>> zrangeByScore(byte[] key, byte[] min, Response<Set<byte[]>> zrangeByScore(byte[] key, byte[] min, byte[] max,
byte[] max, int offset, int count); int offset, int count);
Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, double min, Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, double min,
double max); double max);
Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, byte[] min, Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, byte[] min,
byte[] max); byte[] max);
Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, double min, Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, double min,
double max, int offset, int count); double max, int offset, int count);
Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, byte[] min, Response<Set<Tuple>> zrangeByScoreWithScores(byte[] key, byte[] min,
byte[] max, int offset, int count); byte[] max, int offset, int count);
Response<Set<byte[]>> zrevrangeByScore(byte[] key, double max, Response<Set<byte[]>> zrevrangeByScore(byte[] key, double max, double min);
double min);
Response<Set<byte[]>> zrevrangeByScore(byte[] key, byte[] max, Response<Set<byte[]>> zrevrangeByScore(byte[] key, byte[] max, byte[] min);
byte[] min);
Response<Set<byte[]>> zrevrangeByScore(byte[] key, double max, Response<Set<byte[]>> zrevrangeByScore(byte[] key, double max, double min,
double min, int offset, int count); int offset, int count);
Response<Set<byte[]>> zrevrangeByScore(byte[] key, byte[] max, Response<Set<byte[]>> zrevrangeByScore(byte[] key, byte[] max, byte[] min,
byte[] min, int offset, int count); int offset, int count);
Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, double max,
double max, double min); double min);
Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, byte[] max,
byte[] max, byte[] min); byte[] min);
Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, double max,
double max, double min, int offset, int count); double min, int offset, int count);
Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, Response<Set<Tuple>> zrevrangeByScoreWithScores(byte[] key, byte[] max,
byte[] max, byte[] min, int offset, int count); byte[] min, int offset, int count);
Response<Set<Tuple>> zrangeWithScores(byte[] key, long start, long end); Response<Set<Tuple>> zrangeWithScores(byte[] key, long start, long end);
@@ -206,8 +201,7 @@ public interface BinaryRedisPipeline {
Response<Set<byte[]>> zrevrange(byte[] key, long start, long end); Response<Set<byte[]>> zrevrange(byte[] key, long start, long end);
Response<Set<Tuple>> zrevrangeWithScores(byte[] key, long start, Response<Set<Tuple>> zrevrangeWithScores(byte[] key, long start, long end);
long end);
Response<Long> zrevrank(byte[] key, byte[] member); Response<Long> zrevrank(byte[] key, byte[] member);

View File

@@ -1,6 +1,5 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.List; import java.util.List;
public interface BinaryScriptingCommands { public interface BinaryScriptingCommands {
@@ -8,7 +7,7 @@ public interface BinaryScriptingCommands {
Object eval(byte[] script, byte[] keyCount, byte[]... params); Object eval(byte[] script, byte[] keyCount, byte[]... params);
Object eval(byte[] script, int keyCount, byte[]... params); Object eval(byte[] script, int keyCount, byte[]... params);
Object eval(byte[] script, List<byte[]> keys, List<byte[]> args); Object eval(byte[] script, List<byte[]> keys, List<byte[]> args);
Object eval(byte[] script); Object eval(byte[] script);

View File

@@ -1,16 +1,15 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.util.Hashing;
import redis.clients.util.Sharded;
import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
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.Hashing;
import redis.clients.util.Sharded;
public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo> public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
implements BinaryJedisCommands { implements BinaryJedisCommands {
public BinaryShardedJedis(List<JedisShardInfo> shards) { public BinaryShardedJedis(List<JedisShardInfo> shards) {
@@ -31,10 +30,10 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
} }
public void disconnect() { public void disconnect() {
for (Jedis jedis : getAllShards()) { for (Jedis jedis : getAllShards()) {
jedis.quit(); jedis.quit();
jedis.disconnect(); jedis.disconnect();
} }
} }
protected Jedis create(JedisShardInfo shard) { protected Jedis create(JedisShardInfo shard) {
@@ -102,10 +101,10 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
} }
public Long del(byte[] key) { public Long del(byte[] key) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.del(key); return j.del(key);
} }
public Long incrBy(byte[] key, long integer) { public Long incrBy(byte[] key, long integer) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.incrBy(key, integer); return j.incrBy(key, integer);
@@ -197,23 +196,23 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
} }
public Long strlen(final byte[] key) { public Long strlen(final byte[] key) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.strlen(key); return j.strlen(key);
} }
public Long lpushx(byte[] key, byte[]... string) { public Long lpushx(byte[] key, byte[]... string) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.lpushx(key, string); return j.lpushx(key, string);
} }
public Long persist(final byte[] key) { public Long persist(final byte[] key) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.persist(key); return j.persist(key);
} }
public Long rpushx(byte[] key, byte[]... string) { public Long rpushx(byte[] key, byte[]... string) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.rpushx(key, string); return j.rpushx(key, string);
} }
public Long llen(byte[] key) { public Long llen(byte[] key) {
@@ -296,7 +295,7 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
return j.zadd(key, score, member); return j.zadd(key, score, member);
} }
public Long zadd(byte[] key, Map<Double, byte[]> scoreMembers) { public Long zadd(byte[] key, Map<byte[], Double> scoreMembers) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.zadd(key, scoreMembers); return j.zadd(key, scoreMembers);
} }
@@ -365,7 +364,7 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
Jedis j = getShard(key); Jedis j = getShard(key);
return j.zcount(key, min, max); return j.zcount(key, min, max);
} }
public Long zcount(byte[] key, byte[] min, byte[] max) { public Long zcount(byte[] key, byte[] min, byte[] max) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.zcount(key, min, max); return j.zcount(key, min, max);
@@ -394,8 +393,8 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
} }
public Set<byte[]> zrangeByScore(byte[] key, byte[] min, byte[] max) { public Set<byte[]> zrangeByScore(byte[] key, byte[] min, byte[] max) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.zrangeByScore(key, min, max); return j.zrangeByScore(key, min, max);
} }
public Set<Tuple> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max) { public Set<Tuple> zrangeByScoreWithScores(byte[] key, byte[] min, byte[] max) {
@@ -404,14 +403,15 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
} }
public Set<Tuple> zrangeByScoreWithScores(byte[] key, byte[] min, public Set<Tuple> zrangeByScoreWithScores(byte[] key, byte[] min,
byte[] max, int offset, int count) { byte[] max, int offset, int count) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.zrangeByScoreWithScores(key, min, max, offset, count); return j.zrangeByScoreWithScores(key, min, max, offset, count);
} }
public Set<byte[]> zrangeByScore(byte[] key, byte[] min, byte[] max, int offset, int count) { public Set<byte[]> zrangeByScore(byte[] key, byte[] min, byte[] max,
Jedis j = getShard(key); int offset, int count) {
return j.zrangeByScore(key, min, max, offset, count); Jedis j = getShard(key);
return j.zrangeByScore(key, min, max, offset, count);
} }
public Set<byte[]> zrevrangeByScore(byte[] key, double max, double min) { public Set<byte[]> zrevrangeByScore(byte[] key, double max, double min) {
@@ -436,7 +436,7 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
Jedis j = getShard(key); Jedis j = getShard(key);
return j.zrevrangeByScoreWithScores(key, max, min, offset, count); return j.zrevrangeByScoreWithScores(key, max, min, offset, count);
} }
public Set<byte[]> zrevrangeByScore(byte[] key, byte[] max, byte[] min) { public Set<byte[]> zrevrangeByScore(byte[] key, byte[] max, byte[] min) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.zrevrangeByScore(key, max, min); return j.zrevrangeByScore(key, max, min);
@@ -449,13 +449,13 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
} }
public Set<Tuple> zrevrangeByScoreWithScores(byte[] key, byte[] max, public Set<Tuple> zrevrangeByScoreWithScores(byte[] key, byte[] max,
byte[] min) { byte[] min) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.zrevrangeByScoreWithScores(key, max, min); return j.zrevrangeByScoreWithScores(key, max, min);
} }
public Set<Tuple> zrevrangeByScoreWithScores(byte[] key, byte[] max, public Set<Tuple> zrevrangeByScoreWithScores(byte[] key, byte[] max,
byte[] min, int offset, int count) { byte[] min, int offset, int count) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.zrevrangeByScoreWithScores(key, max, min, offset, count); return j.zrevrangeByScoreWithScores(key, max, min, offset, count);
} }
@@ -510,57 +510,57 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
} }
public Boolean setbit(byte[] key, long offset, boolean value) { public Boolean setbit(byte[] key, long offset, boolean value) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.setbit(key, offset, value); return j.setbit(key, offset, value);
} }
public Boolean setbit(byte[] key, long offset, byte[] value) { public Boolean setbit(byte[] key, long offset, byte[] value) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.setbit(key, offset, value); return j.setbit(key, offset, value);
} }
public Boolean getbit(byte[] key, long offset) { public Boolean getbit(byte[] key, long offset) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.getbit(key, offset); return j.getbit(key, offset);
} }
public Long setrange(byte[] key, long offset, byte[] value) { public Long setrange(byte[] key, long offset, byte[] value) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.setrange(key, offset, value); return j.setrange(key, offset, value);
} }
public byte[] getrange(byte[] key, long startOffset, long endOffset) { public byte[] getrange(byte[] key, long startOffset, long endOffset) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.getrange(key, startOffset, endOffset); return j.getrange(key, startOffset, endOffset);
} }
public Long move(byte[] key, int dbIndex) { public Long move(byte[] key, int dbIndex) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.move(key, dbIndex); return j.move(key, dbIndex);
} }
public byte[] echo(byte[] arg) { public byte[] echo(byte[] arg) {
Jedis j = getShard(arg); Jedis j = getShard(arg);
return j.echo(arg); return j.echo(arg);
} }
public List<byte[]> brpop(byte[] arg) { public List<byte[]> brpop(byte[] arg) {
Jedis j = getShard(arg); Jedis j = getShard(arg);
return j.brpop(arg); return j.brpop(arg);
} }
public List<byte[]> blpop(byte[] arg) { public List<byte[]> blpop(byte[] arg) {
Jedis j = getShard(arg); Jedis j = getShard(arg);
return j.blpop(arg); return j.blpop(arg);
} }
public Long bitcount(byte[] key) { public Long bitcount(byte[] key) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.bitcount(key); return j.bitcount(key);
} }
public Long bitcount(byte[] key, long start, long end) { public Long bitcount(byte[] key, long start, long end) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.bitcount(key, start, end); return j.bitcount(key, start, end);
} }
} }

View File

@@ -1,8 +1,5 @@
package redis.clients.jedis; package redis.clients.jedis;
public enum BitOP { public enum BitOP {
AND, AND, OR, XOR, NOT;
OR,
XOR,
NOT;
} }

View File

@@ -1,249 +1,257 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import redis.clients.util.SafeEncoder; import redis.clients.util.SafeEncoder;
import java.util.*;
public class BuilderFactory { public class BuilderFactory {
public static final Builder<Double> DOUBLE = new Builder<Double>() { public static final Builder<Double> DOUBLE = new Builder<Double>() {
public Double build(Object data) { public Double build(Object data) {
String asString = STRING.build(data); String asString = STRING.build(data);
return asString == null ? null : Double.valueOf(asString); return asString == null ? null : Double.valueOf(asString);
} }
public String toString() { public String toString() {
return "double"; return "double";
} }
}; };
public static final Builder<Boolean> BOOLEAN = new Builder<Boolean>() { public static final Builder<Boolean> BOOLEAN = new Builder<Boolean>() {
public Boolean build(Object data) { public Boolean build(Object data) {
return ((Long) data) == 1; return ((Long) data) == 1;
} }
public String toString() { public String toString() {
return "boolean"; return "boolean";
} }
}; };
public static final Builder<byte[]> BYTE_ARRAY = new Builder<byte[]>() { public static final Builder<byte[]> BYTE_ARRAY = new Builder<byte[]>() {
public byte[] build(Object data) { public byte[] build(Object data) {
return ((byte[]) data); // deleted == 1 return ((byte[]) data); // deleted == 1
} }
public String toString() { public String toString() {
return "byte[]"; return "byte[]";
} }
}; };
public static final Builder<Long> LONG = new Builder<Long>() { public static final Builder<Long> LONG = new Builder<Long>() {
public Long build(Object data) { public Long build(Object data) {
return (Long) data; return (Long) data;
} }
public String toString() { public String toString() {
return "long"; return "long";
} }
}; };
public static final Builder<String> STRING = new Builder<String>() { public static final Builder<String> STRING = new Builder<String>() {
public String build(Object data) { public String build(Object data) {
return data == null ? null : SafeEncoder.encode((byte[]) data); return data == null ? null : SafeEncoder.encode((byte[]) data);
} }
public String toString() { public String toString() {
return "string"; return "string";
} }
}; };
public static final Builder<List<String>> STRING_LIST = new Builder<List<String>>() { public static final Builder<List<String>> STRING_LIST = new Builder<List<String>>() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<String> build(Object data) { public List<String> build(Object data) {
if (null == data) { if (null == data) {
return null; return null;
} }
List<byte[]> l = (List<byte[]>) data; List<byte[]> l = (List<byte[]>) data;
final ArrayList<String> result = new ArrayList<String>(l.size()); final ArrayList<String> result = new ArrayList<String>(l.size());
for (final byte[] barray : l) { for (final byte[] barray : l) {
if (barray == null) { if (barray == null) {
result.add(null); result.add(null);
} else { } else {
result.add(SafeEncoder.encode(barray)); result.add(SafeEncoder.encode(barray));
} }
} }
return result; return result;
} }
public String toString() { public String toString() {
return "List<String>"; return "List<String>";
} }
}; };
public static final Builder<Map<String, String>> STRING_MAP = new Builder<Map<String, String>>() { public static final Builder<Map<String, String>> STRING_MAP = new Builder<Map<String, String>>() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Map<String, String> build(Object data) { public Map<String, String> build(Object data) {
final List<byte[]> flatHash = (List<byte[]>) data; final List<byte[]> flatHash = (List<byte[]>) data;
final Map<String, String> hash = new HashMap<String, String>(); final Map<String, String> hash = new HashMap<String, String>();
final Iterator<byte[]> iterator = flatHash.iterator(); final Iterator<byte[]> iterator = flatHash.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
hash.put(SafeEncoder.encode(iterator.next()), SafeEncoder hash.put(SafeEncoder.encode(iterator.next()),
.encode(iterator.next())); SafeEncoder.encode(iterator.next()));
} }
return hash; return hash;
} }
public String toString() { public String toString() {
return "Map<String, String>"; return "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) {
if (null == data) { if (null == data) {
return null; return null;
} }
List<byte[]> l = (List<byte[]>) data; List<byte[]> l = (List<byte[]>) data;
final Set<String> result = new HashSet<String>(l.size()); final Set<String> result = new HashSet<String>(l.size());
for (final byte[] barray : l) { for (final byte[] barray : l) {
if (barray == null) { if (barray == null) {
result.add(null); result.add(null);
} else { } else {
result.add(SafeEncoder.encode(barray)); result.add(SafeEncoder.encode(barray));
} }
} }
return result; return result;
} }
public String toString() { public String toString() {
return "Set<String>"; return "Set<String>";
} }
}; };
public static final Builder<List<byte[]>> BYTE_ARRAY_LIST = new Builder<List<byte[]>>() { public static final Builder<List<byte[]>> BYTE_ARRAY_LIST = new Builder<List<byte[]>>() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<byte[]> build(Object data) { public List<byte[]> build(Object data) {
if (null == data) { if (null == data) {
return null; return null;
} }
List<byte[]> l = (List<byte[]>) data; List<byte[]> l = (List<byte[]>) data;
return l; return l;
} }
public String toString() { public String toString() {
return "List<byte[]>"; return "List<byte[]>";
} }
}; };
public static final Builder<Set<byte[]>> BYTE_ARRAY_ZSET = new Builder<Set<byte[]>>() { public static final Builder<Set<byte[]>> BYTE_ARRAY_ZSET = new Builder<Set<byte[]>>() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Set<byte[]> build(Object data) { public Set<byte[]> build(Object data) {
if (null == data) { if (null == data) {
return null; return null;
} }
List<byte[]> l = (List<byte[]>) data; List<byte[]> l = (List<byte[]>) data;
final Set<byte[]> result = new LinkedHashSet<byte[]>(l); final Set<byte[]> result = new LinkedHashSet<byte[]>(l);
for (final byte[] barray : l) { for (final byte[] barray : l) {
if (barray == null) { if (barray == null) {
result.add(null); result.add(null);
} else { } else {
result.add(barray); result.add(barray);
} }
} }
return result; return result;
} }
public String toString() { public String toString() {
return "ZSet<byte[]>"; return "ZSet<byte[]>";
} }
}; };
public static final Builder<Map<byte[], byte[]>> BYTE_ARRAY_MAP = new Builder<Map<byte[], byte[]>>() { public static final Builder<Map<byte[], byte[]>> BYTE_ARRAY_MAP = new Builder<Map<byte[], byte[]>>() {
@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 HashMap<byte[], byte[]>();
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());
} }
return hash; return hash;
} }
public String toString() { public String toString() {
return "Map<byte[], byte[]>"; return "Map<byte[], byte[]>";
} }
}; };
public static final Builder<Set<String>> STRING_ZSET = new Builder<Set<String>>() { public static final Builder<Set<String>> STRING_ZSET = new Builder<Set<String>>() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Set<String> build(Object data) { public Set<String> build(Object data) {
if (null == data) { if (null == data) {
return null; return null;
} }
List<byte[]> l = (List<byte[]>) data; List<byte[]> l = (List<byte[]>) data;
final Set<String> result = new LinkedHashSet<String>(l.size()); final Set<String> result = new LinkedHashSet<String>(l.size());
for (final byte[] barray : l) { for (final byte[] barray : l) {
if (barray == null) { if (barray == null) {
result.add(null); result.add(null);
} else { } else {
result.add(SafeEncoder.encode(barray)); result.add(SafeEncoder.encode(barray));
} }
} }
return result; return result;
} }
public String toString() { public String toString() {
return "ZSet<String>"; return "ZSet<String>";
} }
}; };
public static final Builder<Set<Tuple>> TUPLE_ZSET = new Builder<Set<Tuple>>() { public static final Builder<Set<Tuple>> TUPLE_ZSET = new Builder<Set<Tuple>>() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Set<Tuple> build(Object data) { public Set<Tuple> build(Object data) {
if (null == data) { if (null == data) {
return null; return null;
} }
List<byte[]> l = (List<byte[]>) data; List<byte[]> l = (List<byte[]>) data;
final Set<Tuple> result = new LinkedHashSet<Tuple>(l.size()); final Set<Tuple> result = new LinkedHashSet<Tuple>(l.size());
Iterator<byte[]> iterator = l.iterator(); Iterator<byte[]> iterator = l.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
result.add(new Tuple(SafeEncoder.encode(iterator.next()), result.add(new Tuple(SafeEncoder.encode(iterator.next()),
Double.valueOf(SafeEncoder.encode(iterator.next())))); Double.valueOf(SafeEncoder.encode(iterator.next()))));
} }
return result; return result;
} }
public String toString() { public String toString() {
return "ZSet<Tuple>"; return "ZSet<Tuple>";
} }
}; };
public static final Builder<Set<Tuple>> TUPLE_ZSET_BINARY = new Builder<Set<Tuple>>() { public static final Builder<Set<Tuple>> TUPLE_ZSET_BINARY = new Builder<Set<Tuple>>() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Set<Tuple> build(Object data) { public Set<Tuple> build(Object data) {
if (null == data) { if (null == data) {
return null; return null;
} }
List<byte[]> l = (List<byte[]>) data; List<byte[]> l = (List<byte[]>) data;
final Set<Tuple> result = new LinkedHashSet<Tuple>(l.size()); final Set<Tuple> result = new LinkedHashSet<Tuple>(l.size());
Iterator<byte[]> iterator = l.iterator(); Iterator<byte[]> iterator = l.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
result.add(new Tuple(iterator.next(), Double result.add(new Tuple(iterator.next(), Double
.valueOf(SafeEncoder.encode(iterator.next())))); .valueOf(SafeEncoder.encode(iterator.next()))));
} }
return result; return result;
} }
public String toString() { public String toString() {
return "ZSet<Tuple>"; return "ZSet<Tuple>";
} }
}; };
} }

View File

@@ -1,6 +1,6 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.util.SafeEncoder; import static redis.clients.jedis.Protocol.toByteArray;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@@ -8,7 +8,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import static redis.clients.jedis.Protocol.toByteArray; import redis.clients.util.SafeEncoder;
public class Client extends BinaryClient implements Commands { public class Client extends BinaryClient implements Commands {
public Client(final String host) { public Client(final String host) {
@@ -23,8 +23,10 @@ public class Client extends BinaryClient implements Commands {
set(SafeEncoder.encode(key), SafeEncoder.encode(value)); set(SafeEncoder.encode(key), SafeEncoder.encode(value));
} }
public void set(final String key, final String value, final String nxxx, final String expx, final long time) { public void set(final String key, final String value, final String nxxx,
set(SafeEncoder.encode(key), SafeEncoder.encode(value), SafeEncoder.encode(nxxx), SafeEncoder.encode(expx), time); final String expx, final long time) {
set(SafeEncoder.encode(key), SafeEncoder.encode(value),
SafeEncoder.encode(nxxx), SafeEncoder.encode(expx), time);
} }
public void get(final String key) { public void get(final String key) {
@@ -391,14 +393,14 @@ public class Client extends BinaryClient implements Commands {
} }
blpop(bargs); blpop(bargs);
} }
public void blpop(final int timeout, final String... keys) { public void blpop(final int timeout, final String... keys) {
List<String> args = new ArrayList<String>(); List<String> args = new ArrayList<String>();
for (String arg : keys) { for (String arg : keys) {
args.add(arg); args.add(arg);
} }
args.add(String.valueOf(timeout)); args.add(String.valueOf(timeout));
blpop(args.toArray(new String[args.size()])); blpop(args.toArray(new String[args.size()]));
} }
public void sort(final String key, final SortingParams sortingParameters, public void sort(final String key, final SortingParams sortingParameters,
@@ -418,14 +420,14 @@ public class Client extends BinaryClient implements Commands {
} }
brpop(bargs); brpop(bargs);
} }
public void brpop(final int timeout, final String... keys) { public void brpop(final int timeout, final String... keys) {
List<String> args = new ArrayList<String>(); List<String> args = new ArrayList<String>();
for (String arg : keys) { for (String arg : keys) {
args.add(arg); args.add(arg);
} }
args.add(String.valueOf(timeout)); args.add(String.valueOf(timeout));
brpop(args.toArray(new String[args.size()])); brpop(args.toArray(new String[args.size()]));
} }
public void zcount(final String key, final double min, final double max) { public void zcount(final String key, final double min, final double max) {
@@ -620,7 +622,7 @@ public class Client extends BinaryClient implements Commands {
} }
public void setbit(final String key, final long offset, final String value) { public void setbit(final String key, final long offset, final String value) {
setbit(SafeEncoder.encode(key), offset, SafeEncoder.encode(value)); setbit(SafeEncoder.encode(key), offset, SafeEncoder.encode(value));
} }
public void getbit(String key, long offset) { public void getbit(String key, long offset) {
@@ -670,6 +672,18 @@ public class Client extends BinaryClient implements Commands {
} }
subscribe(cs); subscribe(cs);
} }
public void pubsubChannels(String pattern) {
pubsub(Protocol.PUBSUB_CHANNELS, pattern);
}
public void pubsubNumPat() {
pubsub(Protocol.PUBSUB_NUM_PAT);
}
public void pubsubNumSub(String... channels) {
pubsub(Protocol.PUBSUB_NUMSUB, channels);
}
public void configSet(String parameter, String value) { public void configSet(String parameter, String value) {
configSet(SafeEncoder.encode(parameter), SafeEncoder.encode(value)); configSet(SafeEncoder.encode(parameter), SafeEncoder.encode(value));
@@ -709,12 +723,14 @@ public class Client extends BinaryClient implements Commands {
scriptLoad(SafeEncoder.encode(script)); scriptLoad(SafeEncoder.encode(script));
} }
public void zadd(String key, Map<Double, String> scoreMembers) { public void zadd(String key, Map<String, Double> scoreMembers) {
HashMap<Double, byte[]> binaryScoreMembers = new HashMap<Double, byte[]>();
for (Map.Entry<Double, String> entry : scoreMembers.entrySet()) { HashMap<byte[], Double> binaryScoreMembers = new HashMap<byte[], Double>();
binaryScoreMembers.put(entry.getKey(),
SafeEncoder.encode(entry.getValue())); for (Map.Entry<String, Double> entry : scoreMembers.entrySet()) {
binaryScoreMembers.put(SafeEncoder.encode(entry.getKey()),
entry.getValue());
} }
zaddBinary(SafeEncoder.encode(key), binaryScoreMembers); zaddBinary(SafeEncoder.encode(key), binaryScoreMembers);
@@ -733,15 +749,15 @@ public class Client extends BinaryClient implements Commands {
} }
public void bitcount(final String key) { public void bitcount(final String key) {
bitcount(SafeEncoder.encode(key)); bitcount(SafeEncoder.encode(key));
} }
public void bitcount(final String key, long start, long end) { public void bitcount(final String key, long start, long end) {
bitcount(SafeEncoder.encode(key), start, end); bitcount(SafeEncoder.encode(key), start, end);
} }
public void bitop(BitOP op, final String destKey, String... srcKeys) { public void bitop(BitOP op, final String destKey, String... srcKeys) {
bitop(op, SafeEncoder.encode(destKey), getByteParams(srcKeys)); bitop(op, SafeEncoder.encode(destKey), getByteParams(srcKeys));
} }
public void sentinel(final String... args) { public void sentinel(final String... args) {
@@ -752,64 +768,153 @@ public class Client extends BinaryClient implements Commands {
sentinel(arg); sentinel(arg);
} }
public void sentinel(final String cmd, String arg1, int arg2) { public void dump(final String key) {
sentinel(SafeEncoder.encode(cmd), SafeEncoder.encode(arg1), dump(SafeEncoder.encode(key));
toByteArray(arg2));
} }
public void dump(final String key) { public void restore(final String key, final int ttl,
dump(SafeEncoder.encode(key)); final byte[] serializedValue) {
restore(SafeEncoder.encode(key), ttl, serializedValue);
} }
public void restore(final String key, final int ttl, final byte[] serializedValue) {
restore(SafeEncoder.encode(key), ttl, serializedValue);
}
public void pexpire(final String key, final int milliseconds) { public void pexpire(final String key, final int milliseconds) {
pexpire(SafeEncoder.encode(key), milliseconds); pexpire(SafeEncoder.encode(key), milliseconds);
} }
public void pexpireAt(final String key, final long millisecondsTimestamp) { public void pexpireAt(final String key, final long millisecondsTimestamp) {
pexpireAt(SafeEncoder.encode(key), millisecondsTimestamp); pexpireAt(SafeEncoder.encode(key), millisecondsTimestamp);
} }
public void pttl(final String key) { public void pttl(final String key) {
pttl(SafeEncoder.encode(key)); pttl(SafeEncoder.encode(key));
} }
public void incrByFloat(final String key, final double increment) { public void incrByFloat(final String key, final double increment) {
incrByFloat(SafeEncoder.encode(key), increment); incrByFloat(SafeEncoder.encode(key), increment);
} }
public void psetex(final String key, final int milliseconds, final String value) { public void psetex(final String key, final int milliseconds,
psetex(SafeEncoder.encode(key), milliseconds, SafeEncoder.encode(value)); final String value) {
psetex(SafeEncoder.encode(key), milliseconds, SafeEncoder.encode(value));
} }
public void set(final String key, final String value, final String nxxx) { public void set(final String key, final String value, final String nxxx) {
set(SafeEncoder.encode(key), SafeEncoder.encode(value), SafeEncoder.encode(nxxx)); set(SafeEncoder.encode(key), SafeEncoder.encode(value),
SafeEncoder.encode(nxxx));
} }
public void set(final String key, final String value, final String nxxx, final String expx, final int time) { public void set(final String key, final String value, final String nxxx,
set(SafeEncoder.encode(key), SafeEncoder.encode(value), SafeEncoder.encode(nxxx), SafeEncoder.encode(expx), time); final String expx, final int time) {
set(SafeEncoder.encode(key), SafeEncoder.encode(value),
SafeEncoder.encode(nxxx), SafeEncoder.encode(expx), time);
} }
public void srandmember(final String key, final int count) { public void srandmember(final String key, final int count) {
srandmember(SafeEncoder.encode(key), count); srandmember(SafeEncoder.encode(key), count);
} }
public void clientKill(final String client) { public void clientKill(final String client) {
clientKill(SafeEncoder.encode(client)); clientKill(SafeEncoder.encode(client));
} }
public void clientSetname(final String name) { public void clientSetname(final String name) {
clientSetname(SafeEncoder.encode(name)); clientSetname(SafeEncoder.encode(name));
}
public void migrate(final String host, final int port, final String key,
final int destinationDb, final int timeout) {
migrate(SafeEncoder.encode(host), port, SafeEncoder.encode(key),
destinationDb, timeout);
}
public void hincrByFloat(final String key, final String field,
double increment) {
hincrByFloat(SafeEncoder.encode(key), SafeEncoder.encode(field),
increment);
}
public void hscan(final String key, int cursor, final ScanParams params) {
hscan(SafeEncoder.encode(key), cursor, params);
}
public void sscan(final String key, int cursor, final ScanParams params) {
sscan(SafeEncoder.encode(key), cursor, params);
}
public void zscan(final String key, int cursor, final ScanParams params) {
zscan(SafeEncoder.encode(key), cursor, params);
}
public void cluster(final String subcommand, final int... args) {
final byte[][] arg = new byte[args.length + 1][];
for (int i = 1; i < arg.length; i++) {
arg[i] = toByteArray(args[i - 1]);
}
arg[0] = SafeEncoder.encode(subcommand);
cluster(arg);
} }
public void migrate(final String host, final int port, final String key, final int destinationDb, final int timeout) { public void pubsub(final String subcommand, final String... args) {
migrate(SafeEncoder.encode(host), port, SafeEncoder.encode(key), destinationDb, timeout); final byte[][] arg = new byte[args.length+1][];
for (int i = 1; i < arg.length; i++) {
arg[i] = SafeEncoder.encode(args[i-1]);
}
arg[0] = SafeEncoder.encode(subcommand);
pubsub(arg);
} }
public void hincrByFloat(final String key, final String field, double increment) { public void cluster(final String subcommand, final String... args) {
hincrByFloat(SafeEncoder.encode(key), SafeEncoder.encode(field), increment); final byte[][] arg = new byte[args.length + 1][];
for (int i = 1; i < arg.length; i++) {
arg[i] = SafeEncoder.encode(args[i - 1]);
}
arg[0] = SafeEncoder.encode(subcommand);
cluster(arg);
}
public void cluster(final String subcommand) {
final byte[][] arg = new byte[1][];
arg[0] = SafeEncoder.encode(subcommand);
cluster(arg);
}
public void clusterNodes() {
cluster(Protocol.CLUSTER_NODES);
}
public void clusterMeet(final String ip, final int port) {
cluster(Protocol.CLUSTER_MEET, ip, String.valueOf(port));
}
public void clusterAddSlots(final int... slots) {
cluster(Protocol.CLUSTER_ADDSLOTS, slots);
}
public void clusterDelSlots(final int... slots) {
cluster(Protocol.CLUSTER_DELSLOTS, slots);
}
public void clusterInfo() {
cluster(Protocol.CLUSTER_INFO);
}
public void clusterGetKeysInSlot(final int slot, final int count) {
final int[] args = new int[] { slot, count };
cluster(Protocol.CLUSTER_GETKEYSINSLOT, args);
}
public void clusterSetSlotNode(final int slot, final String nodeId) {
cluster(Protocol.CLUSTER_SETSLOT, String.valueOf(slot),
Protocol.CLUSTER_SETSLOT_NODE, nodeId);
}
public void clusterSetSlotMigrating(final int slot, final String nodeId) {
cluster(Protocol.CLUSTER_SETSLOT, String.valueOf(slot),
Protocol.CLUSTER_SETSLOT_MIGRATING, nodeId);
}
public void clusterSetSlotImporting(final int slot, final String nodeId) {
cluster(Protocol.CLUSTER_SETSLOT, String.valueOf(slot),
Protocol.CLUSTER_SETSLOT_IMPORTING, nodeId);
} }
} }

View File

@@ -0,0 +1,23 @@
package redis.clients.jedis;
import java.util.List;
public interface ClusterCommands {
String clusterNodes();
String clusterMeet(final String ip, final int port);
String clusterAddSlots(final int... slots);
String clusterDelSlots(final int... slots);
String clusterInfo();
List<String> clusterGetKeysInSlot(final int slot, final int count);
String clusterSetSlotNode(final int slot, final String nodeId);
String clusterSetSlotMigrating(final int slot, final String nodeId);
String clusterSetSlotImporting(final int slot, final String nodeId);
}

View File

@@ -0,0 +1,23 @@
package redis.clients.jedis;
import java.util.List;
public interface ClusterPipeline {
Response<String> clusterNodes();
Response<String> clusterMeet(final String ip, final int port);
Response<String> clusterAddSlots(final int... slots);
Response<String> clusterDelSlots(final int... slots);
Response<String> clusterInfo();
Response<List<String>> clusterGetKeysInSlot(final int slot, final int count);
Response<String> clusterSetSlotNode(final int slot, final String nodeId);
Response<String> clusterSetSlotMigrating(final int slot, final String nodeId);
Response<String> clusterSetSlotImporting(final int slot, final String nodeId);
}

View File

@@ -1,14 +1,15 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import java.util.Map; import java.util.Map;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
public interface Commands { public interface Commands {
public void set(final String key, final String value); public void set(final String key, final String value);
public void set(final String key, final String value, final String nxxx, final String expx, final long time); public void set(final String key, final String value, final String nxxx,
final String expx, final long time);
public void get(final String key); public void get(final String key);
@@ -143,7 +144,7 @@ public interface Commands {
public void zadd(final String key, final double score, final String member); public void zadd(final String key, final double score, final String member);
public void zadd(final String key, final Map<Double, String> scoreMembers); public void zadd(final String key, final Map<String, Double> scoreMembers);
public void zrange(final String key, final long start, final long end); public void zrange(final String key, final long start, final long end);
@@ -295,4 +296,14 @@ public interface Commands {
public void bitcount(final String key, long start, long end); public void bitcount(final String key, long start, long end);
public void bitop(BitOP op, final String destKey, String... srcKeys); public void bitop(BitOP op, final String destKey, String... srcKeys);
public void scan(int cursor, final ScanParams params);
public void hscan(final String key, int cursor, final ScanParams params);
public void sscan(final String key, int cursor, final ScanParams params);
public void zscan(final String key, int cursor, final ScanParams params);
public void waitReplicas(int replicas, long timeout);
} }

View File

@@ -25,218 +25,230 @@ public class Connection {
private int timeout = Protocol.DEFAULT_TIMEOUT; private int timeout = Protocol.DEFAULT_TIMEOUT;
public Socket getSocket() { public Socket getSocket() {
return socket; return socket;
} }
public int getTimeout() { public int getTimeout() {
return timeout; return timeout;
} }
public void setTimeout(final int timeout) { public void setTimeout(final int timeout) {
this.timeout = timeout; this.timeout = timeout;
} }
public void setTimeoutInfinite() { public void setTimeoutInfinite() {
try { try {
if(!isConnected()) { if (!isConnected()) {
connect(); connect();
} }
socket.setKeepAlive(true); socket.setKeepAlive(true);
socket.setSoTimeout(0); socket.setSoTimeout(0);
} catch (SocketException ex) { } catch (SocketException ex) {
throw new JedisException(ex); throw new JedisException(ex);
} }
} }
public void rollbackTimeout() { public void rollbackTimeout() {
try { try {
socket.setSoTimeout(timeout); socket.setSoTimeout(timeout);
socket.setKeepAlive(false); socket.setKeepAlive(false);
} catch (SocketException ex) { } catch (SocketException ex) {
throw new JedisException(ex); throw new JedisException(ex);
} }
} }
public Connection(final String host) { public Connection(final String host) {
super(); super();
this.host = host; this.host = host;
} }
protected void flush() { protected void flush() {
try { try {
outputStream.flush(); outputStream.flush();
} catch (IOException e) { } catch (IOException e) {
throw new JedisConnectionException(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++) {
bargs[i] = SafeEncoder.encode(args[i]); bargs[i] = SafeEncoder.encode(args[i]);
} }
return sendCommand(cmd, bargs); return sendCommand(cmd, bargs);
} }
protected Connection sendCommand(final Command cmd, final byte[]... args) { protected Connection sendCommand(final Command cmd, final byte[]... args) {
connect(); connect();
Protocol.sendCommand(outputStream, cmd, args); Protocol.sendCommand(outputStream, cmd, args);
pipelinedCommands++; pipelinedCommands++;
return this; return this;
} }
protected Connection sendCommand(final Command cmd) { protected Connection sendCommand(final Command cmd) {
connect(); connect();
Protocol.sendCommand(outputStream, cmd, new byte[0][]); Protocol.sendCommand(outputStream, cmd, new byte[0][]);
pipelinedCommands++; pipelinedCommands++;
return this; return this;
} }
public Connection(final String host, final int port) { public Connection(final String host, final int port) {
super(); super();
this.host = host; this.host = host;
this.port = port; this.port = port;
} }
public String getHost() { public String getHost() {
return host; return host;
} }
public void setHost(final String host) { public void setHost(final String host) {
this.host = host; this.host = host;
} }
public int getPort() { public int getPort() {
return port; return port;
} }
public void setPort(final int port) { public void setPort(final int port) {
this.port = port; this.port = port;
} }
public Connection() { public Connection() {
} }
public void connect() { public void connect() {
if (!isConnected()) { if (!isConnected()) {
try { try {
socket = new Socket(); socket = new Socket();
//->@wjw_add // ->@wjw_add
socket.setReuseAddress(true); socket.setReuseAddress(true);
socket.setKeepAlive(true); //Will monitor the TCP connection is valid socket.setKeepAlive(true); // Will monitor the TCP connection is
socket.setTcpNoDelay(true); //Socket buffer Whetherclosed, to ensure timely delivery of data // valid
socket.setSoLinger(true,0); //Control calls close () method, the underlying socket is closed immediately socket.setTcpNoDelay(true); // Socket buffer Whetherclosed, to
//<-@wjw_add // ensure timely delivery of data
socket.setSoLinger(true, 0); // Control calls close () method,
// the underlying socket is closed
// immediately
// <-@wjw_add
socket.connect(new InetSocketAddress(host, port), timeout); socket.connect(new InetSocketAddress(host, port), timeout);
socket.setSoTimeout(timeout); socket.setSoTimeout(timeout);
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) {
throw new JedisConnectionException(ex); throw new JedisConnectionException(ex);
} }
} }
} }
public void disconnect() { public void disconnect() {
if (isConnected()) { if (isConnected()) {
try { try {
inputStream.close(); inputStream.close();
outputStream.close(); outputStream.close();
if (!socket.isClosed()) { if (!socket.isClosed()) {
socket.close(); socket.close();
} }
} catch (IOException ex) { } catch (IOException ex) {
throw new JedisConnectionException(ex); throw new JedisConnectionException(ex);
} }
} }
} }
public boolean isConnected() { public boolean isConnected() {
return socket != null && socket.isBound() && !socket.isClosed() return socket != null && socket.isBound() && !socket.isClosed()
&& socket.isConnected() && !socket.isInputShutdown() && socket.isConnected() && !socket.isInputShutdown()
&& !socket.isOutputShutdown(); && !socket.isOutputShutdown();
} }
protected String getStatusCodeReply() { protected String getStatusCodeReply() {
flush(); flush();
pipelinedCommands--; pipelinedCommands--;
final byte[] resp = (byte[]) Protocol.read(inputStream); final byte[] resp = (byte[]) Protocol.read(inputStream);
if (null == resp) { if (null == resp) {
return null; return null;
} else { } else {
return SafeEncoder.encode(resp); return SafeEncoder.encode(resp);
} }
} }
public String getBulkReply() { public String getBulkReply() {
final byte[] result = getBinaryBulkReply(); final byte[] result = getBinaryBulkReply();
if (null != result) { if (null != result) {
return SafeEncoder.encode(result); return SafeEncoder.encode(result);
} else { } else {
return null; return null;
} }
} }
public byte[] getBinaryBulkReply() { public byte[] getBinaryBulkReply() {
flush(); flush();
pipelinedCommands--; pipelinedCommands--;
return (byte[]) Protocol.read(inputStream); return (byte[]) Protocol.read(inputStream);
} }
public Long getIntegerReply() { public Long getIntegerReply() {
flush(); flush();
pipelinedCommands--; pipelinedCommands--;
return (Long) Protocol.read(inputStream); return (Long) Protocol.read(inputStream);
} }
public List<String> getMultiBulkReply() { public List<String> getMultiBulkReply() {
return BuilderFactory.STRING_LIST.build(getBinaryMultiBulkReply()); return BuilderFactory.STRING_LIST.build(getBinaryMultiBulkReply());
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<byte[]> getBinaryMultiBulkReply() { public List<byte[]> getBinaryMultiBulkReply() {
flush(); flush();
pipelinedCommands--; pipelinedCommands--;
return (List<byte[]>) Protocol.read(inputStream); return (List<byte[]>) Protocol.read(inputStream);
}
public void resetPipelinedCount() {
pipelinedCommands = 0;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<Object> getRawObjectMultiBulkReply() {
return (List<Object>) Protocol.read(inputStream);
}
public List<Object> getObjectMultiBulkReply() { public List<Object> getObjectMultiBulkReply() {
flush(); flush();
pipelinedCommands--; pipelinedCommands--;
return (List<Object>) Protocol.read(inputStream); return getRawObjectMultiBulkReply();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<Long> getIntegerMultiBulkReply() { public List<Long> getIntegerMultiBulkReply() {
flush(); flush();
pipelinedCommands--; pipelinedCommands--;
return (List<Long>) Protocol.read(inputStream); return (List<Long>) Protocol.read(inputStream);
} }
public List<Object> getAll() { public List<Object> getAll() {
return getAll(0); return getAll(0);
} }
public List<Object> getAll(int except) { public List<Object> getAll(int except) {
List<Object> all = new ArrayList<Object>(); List<Object> all = new ArrayList<Object>();
flush(); flush();
while (pipelinedCommands > except) { while (pipelinedCommands > except) {
try{ try {
all.add(Protocol.read(inputStream)); all.add(Protocol.read(inputStream));
}catch(JedisDataException e){ } catch (JedisDataException e) {
all.add(e); all.add(e);
} }
pipelinedCommands--; pipelinedCommands--;
} }
return all; return all;
} }
public Object getOne() { public Object getOne() {
flush(); flush();
pipelinedCommands--; pipelinedCommands--;
return Protocol.read(inputStream); return Protocol.read(inputStream);
} }
} }

View File

@@ -0,0 +1,49 @@
package redis.clients.jedis;
public class HostAndPort {
public static final String LOCALHOST_STR = "localhost";
private String host;
private int port;
public HostAndPort(String host, int port) {
this.host = host;
this.port = port;
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof HostAndPort) {
HostAndPort hp = (HostAndPort) obj;
String thisHost = convertHost(host);
String hpHost = convertHost(hp.host);
return port == hp.port && thisHost.equals(hpHost);
}
return false;
}
@Override
public String toString() {
return host + ":" + port;
}
private String convertHost(String host) {
if (host.equals("127.0.0.1"))
return LOCALHOST_STR;
else if (host.equals("::1"))
return LOCALHOST_STR;
return host;
}
}

View File

@@ -1,13 +1,22 @@
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.Set;
import redis.clients.jedis.BinaryClient.LIST_POSITION; import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.util.SafeEncoder; import redis.clients.util.SafeEncoder;
import redis.clients.util.Slowlog; import redis.clients.util.Slowlog;
import java.net.URI; public class Jedis extends BinaryJedis implements JedisCommands,
import java.util.*; MultiKeyCommands, AdvancedJedisCommands, ScriptingCommands,
BasicCommands, ClusterCommands {
public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommands, AdvancedJedisCommands, ScriptingCommands {
public Jedis(final String host) { public Jedis(final String host) {
super(host); super(host);
} }
@@ -47,24 +56,29 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
/** /**
* Set the string value as value of the key. The string can't be longer than * Set the string value as value of the key. The string can't be longer than
* 1073741824 bytes (1 GB). * 1073741824 bytes (1 GB).
*
* @param key * @param key
* @param value * @param value
* @param nxxx NX|XX, NX -- Only set the key if it does not already exist. * @param nxxx
* XX -- Only set the key if it already exist. * NX|XX, NX -- Only set the key if it does not already exist. XX
* @param expx EX|PX, expire time units: EX = seconds; PX = milliseconds * -- Only set the key if it already exist.
* @param time expire time in the units of {@param #expx} * @param expx
* EX|PX, expire time units: EX = seconds; PX = milliseconds
* @param time
* expire time in the units of {@param #expx}
* @return Status code reply * @return Status code reply
*/ */
public String set(final String key, final String value, final String nxxx, final String expx, final long time) { public String set(final String key, final String value, final String nxxx,
checkIsInMulti(); final String expx, final long time) {
client.set(key, value, nxxx, expx, time); checkIsInMulti();
return client.getStatusCodeReply(); client.set(key, value, nxxx, expx, time);
return client.getStatusCodeReply();
} }
/** /**
* Get the value of the specified key. If the key does not exist the special * Get the value of the specified key. If the key does not exist null is
* value 'nil' is returned. If the value stored at key is not a string an * returned. If the value stored at key is not a string an error is returned
* error is returned because GET can only handle string values. * because GET can only handle string values.
* <p> * <p>
* Time complexity: O(1) * Time complexity: O(1)
* *
@@ -110,8 +124,8 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
} }
public Long del(String key) { public Long del(String key) {
client.del(key); client.del(key);
return client.getIntegerReply(); return client.getIntegerReply();
} }
/** /**
@@ -1372,7 +1386,7 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
client.srandmember(key); client.srandmember(key);
return client.getBulkReply(); return client.getBulkReply();
} }
public List<String> srandmember(final String key, final int count) { public List<String> srandmember(final String key, final int count) {
checkIsInMulti(); checkIsInMulti();
client.srandmember(key, count); client.srandmember(key, count);
@@ -1406,7 +1420,7 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Long zadd(final String key, final Map<Double, String> scoreMembers) { public Long zadd(final String key, final Map<String, Double> scoreMembers) {
checkIsInMulti(); checkIsInMulti();
client.zadd(key, scoreMembers); client.zadd(key, scoreMembers);
return client.getIntegerReply(); return client.getIntegerReply();
@@ -1780,39 +1794,39 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
} }
public List<String> blpop(String... args) { public List<String> blpop(String... args) {
client.blpop(args); client.blpop(args);
client.setTimeoutInfinite(); client.setTimeoutInfinite();
final List<String> multiBulkReply = client.getMultiBulkReply(); final List<String> multiBulkReply = client.getMultiBulkReply();
client.rollbackTimeout(); client.rollbackTimeout();
return multiBulkReply; return multiBulkReply;
} }
public List<String> brpop(String... args) { public List<String> brpop(String... args) {
client.brpop(args); client.brpop(args);
client.setTimeoutInfinite(); client.setTimeoutInfinite();
final List<String> multiBulkReply = client.getMultiBulkReply(); final List<String> multiBulkReply = client.getMultiBulkReply();
client.rollbackTimeout(); client.rollbackTimeout();
return multiBulkReply; return multiBulkReply;
} }
public List<String> blpop(String arg) { public List<String> blpop(String arg) {
String[] args = new String[1]; String[] args = new String[1];
args[0] = arg; args[0] = arg;
client.blpop(args); client.blpop(args);
client.setTimeoutInfinite(); client.setTimeoutInfinite();
final List<String> multiBulkReply = client.getMultiBulkReply(); final List<String> multiBulkReply = client.getMultiBulkReply();
client.rollbackTimeout(); client.rollbackTimeout();
return multiBulkReply; return multiBulkReply;
} }
public List<String> brpop(String arg) { public List<String> brpop(String arg) {
String[] args = new String[1]; String[] args = new String[1];
args[0] = arg; args[0] = arg;
client.brpop(args); client.brpop(args);
client.setTimeoutInfinite(); client.setTimeoutInfinite();
final List<String> multiBulkReply = client.getMultiBulkReply(); final List<String> multiBulkReply = client.getMultiBulkReply();
client.rollbackTimeout(); client.rollbackTimeout();
return multiBulkReply; return multiBulkReply;
} }
/** /**
@@ -1945,8 +1959,6 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
return multiBulkReply; return multiBulkReply;
} }
public Long zcount(final String key, final double min, final double max) { public Long zcount(final String key, final double min, final double max) {
checkIsInMulti(); checkIsInMulti();
client.zcount(key, min, max); client.zcount(key, min, max);
@@ -2011,8 +2023,10 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
* @see #zcount(String, double, double) * @see #zcount(String, double, double)
* *
* @param key * @param key
* @param min a double or Double.MIN_VALUE for "-inf" * @param min
* @param max a double or Double.MAX_VALUE for "+inf" * a double or Double.MIN_VALUE for "-inf"
* @param max
* a double or Double.MAX_VALUE for "+inf"
* @return Multi bulk reply specifically a list of elements in the specified * @return Multi bulk reply specifically a list of elements in the specified
* score range. * score range.
*/ */
@@ -2619,8 +2633,8 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
} }
public Boolean setbit(String key, long offset, String value) { public Boolean setbit(String key, long offset, String value) {
client.setbit(key, offset, value); client.setbit(key, offset, value);
return client.getIntegerReply() == 1; return client.getIntegerReply() == 1;
} }
/** /**
@@ -2733,26 +2747,26 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
} }
public void subscribe(final JedisPubSub jedisPubSub, public void subscribe(final JedisPubSub jedisPubSub,
final String... channels) { final String... channels) {
client.setTimeoutInfinite(); client.setTimeoutInfinite();
jedisPubSub.proceed(client, channels); jedisPubSub.proceed(client, channels);
client.rollbackTimeout(); client.rollbackTimeout();
} }
public Long publish(final String channel, final String message) { public Long publish(final String channel, final String message) {
checkIsInMulti(); checkIsInMulti();
connect(); connect();
client.publish(channel, message); client.publish(channel, message);
return client.getIntegerReply(); return client.getIntegerReply();
} }
public void psubscribe(final JedisPubSub jedisPubSub, public void psubscribe(final JedisPubSub jedisPubSub,
final String... patterns) { final String... patterns) {
checkIsInMulti(); checkIsInMulti();
connect(); connect();
client.setTimeoutInfinite(); client.setTimeoutInfinite();
jedisPubSub.proceedWithPatterns(client, patterns); jedisPubSub.proceedWithPatterns(client, patterns);
client.rollbackTimeout(); client.rollbackTimeout();
} }
protected static String[] getParams(List<String> keys, List<String> args) { protected static String[] getParams(List<String> keys, List<String> args) {
@@ -2862,18 +2876,18 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
} }
public Long bitcount(final String key) { public Long bitcount(final String key) {
client.bitcount(key); client.bitcount(key);
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Long bitcount(final String key, long start, long end) { public Long bitcount(final String key, long start, long end) {
client.bitcount(key, start, end); client.bitcount(key, start, end);
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Long bitop(BitOP op, final String destKey, String... srcKeys) { public Long bitop(BitOP op, final String destKey, String... srcKeys) {
client.bitop(op, destKey, srcKeys); client.bitop(op, destKey, srcKeys);
return client.getIntegerReply(); return client.getIntegerReply();
} }
/** /**
@@ -2909,7 +2923,7 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
* @return * @return
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public List<Map<String, String>> sentinelMasters() { public List<Map<String, String>> sentinelMasters() {
client.sentinel(Protocol.SENTINEL_MASTERS); client.sentinel(Protocol.SENTINEL_MASTERS);
final List<Object> reply = client.getObjectMultiBulkReply(); final List<Object> reply = client.getObjectMultiBulkReply();
@@ -2987,7 +3001,7 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
* @return * @return
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public List<Map<String, String>> sentinelSlaves(String masterName) { public List<Map<String, String>> sentinelSlaves(String masterName) {
client.sentinel(Protocol.SENTINEL_SLAVES, masterName); client.sentinel(Protocol.SENTINEL_SLAVES, masterName);
final List<Object> reply = client.getObjectMultiBulkReply(); final List<Object> reply = client.getObjectMultiBulkReply();
@@ -2998,104 +3012,244 @@ public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommand
return slaves; return slaves;
} }
/**
* <pre>
* redis 127.0.0.1:26381> SENTINEL is-master-down-by-addr 127.0.0.1 1
* 1) (integer) 0
* 2) "?"
* redis 127.0.0.1:26381> SENTINEL is-master-down-by-addr 127.0.0.1 6379
* 1) (integer) 0
* 2) "aaef11fbb2712346a386078c7f9834e72ed51e96"
* </pre>
*
* @return Long followed by the String (runid)
*/
@SuppressWarnings("unchecked")
public List<? extends Object> sentinelIsMasterDownByAddr(String host,
int port) {
client.sentinel(Protocol.SENTINEL_IS_MASTER_DOWN_BY_ADDR, host, port);
final List<Object> reply = client.getObjectMultiBulkReply();
return Arrays.asList(BuilderFactory.LONG.build(reply.get(0)),
BuilderFactory.STRING.build(reply.get(1)));
}
public byte[] dump(final String key) { public byte[] dump(final String key) {
checkIsInMulti(); checkIsInMulti();
client.dump(key); client.dump(key);
return client.getBinaryBulkReply(); return client.getBinaryBulkReply();
} }
public String restore(final String key, final int ttl, final byte[] serializedValue) { public String restore(final String key, final int ttl,
checkIsInMulti(); final byte[] serializedValue) {
client.restore(key, ttl, serializedValue); checkIsInMulti();
return client.getStatusCodeReply(); client.restore(key, ttl, serializedValue);
return client.getStatusCodeReply();
} }
public Long pexpire(final String key, final int milliseconds) { public Long pexpire(final String key, final int milliseconds) {
checkIsInMulti(); checkIsInMulti();
client.pexpire(key, milliseconds); client.pexpire(key, milliseconds);
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Long pexpireAt(final String key, final long millisecondsTimestamp) { public Long pexpireAt(final String key, final long millisecondsTimestamp) {
checkIsInMulti(); checkIsInMulti();
client.pexpireAt(key, millisecondsTimestamp); client.pexpireAt(key, millisecondsTimestamp);
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Long pttl(final String key) { public Long pttl(final String key) {
checkIsInMulti(); checkIsInMulti();
client.pttl(key); client.pttl(key);
return client.getIntegerReply(); return client.getIntegerReply();
} }
public Double incrByFloat(final String key, final double increment) { public Double incrByFloat(final String key, final double increment) {
checkIsInMulti(); checkIsInMulti();
client.incrByFloat(key, increment); client.incrByFloat(key, increment);
String relpy = client.getBulkReply(); String relpy = client.getBulkReply();
return (relpy != null ? new Double(relpy) : null); return (relpy != null ? new Double(relpy) : null);
} }
public String psetex(final String key, final int milliseconds, final String value) { public String psetex(final String key, final int milliseconds,
checkIsInMulti(); final String value) {
client.psetex(key, milliseconds, value); checkIsInMulti();
return client.getStatusCodeReply(); client.psetex(key, milliseconds, value);
return client.getStatusCodeReply();
} }
public String set(final String key, final String value, final String nxxx) { public String set(final String key, final String value, final String nxxx) {
checkIsInMulti(); checkIsInMulti();
client.set(key, value, nxxx); client.set(key, value, nxxx);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
} }
public String set(final String key, final String value, final String nxxx, final String expx, final int time) { public String set(final String key, final String value, final String nxxx,
checkIsInMulti(); final String expx, final int time) {
client.set(key, value, nxxx, expx, time); checkIsInMulti();
return client.getStatusCodeReply(); client.set(key, value, nxxx, expx, time);
return client.getStatusCodeReply();
} }
public String clientKill(final String client) { public String clientKill(final String client) {
checkIsInMulti(); checkIsInMulti();
this.client.clientKill(client); this.client.clientKill(client);
return this.client.getStatusCodeReply(); return this.client.getStatusCodeReply();
} }
public String clientSetname(final String name) { public String clientSetname(final String name) {
checkIsInMulti(); checkIsInMulti();
client.clientSetname(name); client.clientSetname(name);
return client.getStatusCodeReply(); return client.getStatusCodeReply();
} }
public String migrate(final String host, final int port, final String key, final int destinationDb, final int timeout) { public String migrate(final String host, final int port, final String key,
checkIsInMulti(); final int destinationDb, final int timeout) {
client.migrate(host, port, key, destinationDb, timeout); checkIsInMulti();
return client.getStatusCodeReply(); client.migrate(host, port, key, destinationDb, timeout);
return client.getStatusCodeReply();
} }
public Double hincrByFloat(final String key, final String field, double increment) { public Double hincrByFloat(final String key, final String field,
checkIsInMulti(); double increment) {
client.hincrByFloat(key, field, increment); checkIsInMulti();
String relpy = client.getBulkReply(); client.hincrByFloat(key, field, increment);
return (relpy != null ? new Double(relpy) : null); String relpy = client.getBulkReply();
return (relpy != null ? new Double(relpy) : null);
}
public ScanResult<String> scan(int cursor) {
return scan(cursor, new ScanParams());
}
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);
}
public ScanResult<Map.Entry<String, String>> hscan(final String key,
int cursor) {
return hscan(key, cursor, new ScanParams());
}
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);
}
public ScanResult<String> sscan(final String key, int cursor) {
return sscan(key, cursor, new ScanParams());
}
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);
}
public ScanResult<Tuple> zscan(final String key, int cursor) {
return zscan(key, cursor, new ScanParams());
}
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 String clusterNodes() {
checkIsInMulti();
client.clusterNodes();
return client.getBulkReply();
}
public String clusterMeet(final String ip, final int port) {
checkIsInMulti();
client.clusterMeet(ip, port);
return client.getStatusCodeReply();
}
public String clusterAddSlots(final int... slots) {
checkIsInMulti();
client.clusterAddSlots(slots);
return client.getStatusCodeReply();
}
public String clusterDelSlots(final int... slots) {
checkIsInMulti();
client.clusterDelSlots(slots);
return client.getStatusCodeReply();
}
public String clusterInfo() {
checkIsInMulti();
client.clusterInfo();
return client.getStatusCodeReply();
}
public List<String> clusterGetKeysInSlot(final int slot, final int count) {
checkIsInMulti();
client.clusterGetKeysInSlot(slot, count);
return client.getMultiBulkReply();
}
public String clusterSetSlotNode(final int slot, final String nodeId) {
checkIsInMulti();
client.clusterSetSlotNode(slot, nodeId);
return client.getStatusCodeReply();
}
public String clusterSetSlotMigrating(final int slot, final String nodeId) {
checkIsInMulti();
client.clusterSetSlotMigrating(slot, nodeId);
return client.getStatusCodeReply();
}
public String clusterSetSlotImporting(final int slot, final String nodeId) {
checkIsInMulti();
client.clusterSetSlotImporting(slot, nodeId);
return client.getStatusCodeReply();
}
public String asking() {
checkIsInMulti();
client.asking();
return client.getStatusCodeReply();
}
public List<String> pubsubChannels(String pattern) {
checkIsInMulti();
client.pubsubChannels(pattern);
return client.getMultiBulkReply();
}
public Long pubsubNumPat() {
checkIsInMulti();
client.pubsubNumPat();
return client.getIntegerReply();
}
public Map<String, String> pubsubNumSub(String... channels) {
checkIsInMulti();
client.pubsubNumSub(channels);
return BuilderFactory.STRING_MAP
.build(client.getBinaryMultiBulkReply());
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,60 @@
package redis.clients.jedis;
import redis.clients.jedis.exceptions.JedisAskDataException;
import redis.clients.jedis.exceptions.JedisClusterException;
import redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException;
import redis.clients.jedis.exceptions.JedisRedirectionException;
import redis.clients.util.JedisClusterCRC16;
public abstract class JedisClusterCommand<T> {
private boolean asking = false;
private JedisClusterConnectionHandler connectionHandler;
private int commandTimeout;
private int redirections;
// private boolean asking = false;
public JedisClusterCommand(JedisClusterConnectionHandler connectionHandler,
int timeout, int maxRedirections) {
this.connectionHandler = connectionHandler;
this.commandTimeout = timeout;
this.redirections = maxRedirections;
}
public abstract T execute();
public T run(String key) {
try {
if (key == null) {
throw new JedisClusterException(
"No way to dispatch this command to Redis Cluster.");
} else if (redirections == 0) {
throw new JedisClusterMaxRedirectionsException(
"Too many Cluster redirections?");
}
connectionHandler.getConnectionFromSlot(JedisClusterCRC16
.getSlot(key));
if (asking) {
// TODO: Pipeline asking with the original command to make it
// faster....
connectionHandler.getConnection().asking();
}
return execute();
} catch (JedisRedirectionException jre) {
return handleRedirection(jre, key);
}
}
private T handleRedirection(JedisRedirectionException jre, String key) {
if (jre instanceof JedisAskDataException) {
asking = true;
}
redirections--;
this.connectionHandler.assignSlotToNode(jre.getSlot(),
jre.getTargetNode());
return run(key);
}
}

View File

@@ -0,0 +1,92 @@
package redis.clients.jedis;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Set;
public abstract class JedisClusterConnectionHandler {
protected Map<String, JedisPool> nodes = new HashMap<String, JedisPool>();
protected Map<Integer, JedisPool> slots = new HashMap<Integer, JedisPool>();
abstract Jedis getConnection();
abstract Jedis getConnectionFromSlot(int slot);
public JedisClusterConnectionHandler(Set<HostAndPort> nodes) {
initializeSlotsCache(nodes);
}
public Map<String, JedisPool> getNodes() {
return nodes;
}
private void initializeSlotsCache(Set<HostAndPort> nodes) {
for (HostAndPort hostAndPort : nodes) {
JedisPool jp = new JedisPool(hostAndPort.getHost(),
hostAndPort.getPort());
this.nodes.put(hostAndPort.getHost() + hostAndPort.getPort(), jp);
Jedis jedis = jp.getResource();
try {
discoverClusterNodesAndSlots(jedis);
} finally {
jp.returnResource(jedis);
}
}
}
private void discoverClusterNodesAndSlots(Jedis jedis) {
String localNodes = jedis.clusterNodes();
for (String nodeInfo : localNodes.split("\n")) {
HostAndPort node = getHostAndPortFromNodeLine(nodeInfo, jedis);
JedisPool nodePool = new JedisPool(node.getHost(), node.getPort());
this.nodes.put(node.getHost() + node.getPort(), nodePool);
populateNodeSlots(nodeInfo, 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) {
JedisPool targetPool = nodes.get(targetNode.getHost()
+ targetNode.getPort());
slots.put(slot, targetPool);
}
protected JedisPool getRandomConnection() {
Object[] nodeArray = nodes.values().toArray();
return (JedisPool) (nodeArray[new Random().nextInt(nodeArray.length)]);
}
}

View File

@@ -7,8 +7,7 @@ import java.util.Set;
/** /**
* Common interface for sharded and non-sharded Jedis * Common interface for sharded and non-sharded Jedis
*/ */
public interface public interface JedisCommands {
JedisCommands {
String set(String key, String value); String set(String key, String value);
String get(String key); String get(String key);
@@ -114,8 +113,8 @@ public interface
Long strlen(String key); Long strlen(String key);
Long zadd(String key, double score, String member); Long zadd(String key, double score, String member);
Long zadd(String key, Map<Double, String> scoreMembers); Long zadd(String key, Map<String, Double> scoreMembers);
Set<String> zrange(String key, long start, long end); Set<String> zrange(String key, long start, long end);
@@ -152,50 +151,50 @@ public interface
Set<String> zrevrangeByScore(String key, double max, double min); Set<String> zrevrangeByScore(String key, double max, double min);
Set<String> zrangeByScore(String key, double min, double max, int offset, Set<String> zrangeByScore(String key, double min, double max, int offset,
int count); int count);
Set<String> zrevrangeByScore(String key, String max, String min); Set<String> zrevrangeByScore(String key, String max, String min);
Set<String> zrangeByScore(String key, String min, String max, int offset, Set<String> zrangeByScore(String key, String min, String max, int offset,
int count); int count);
Set<String> zrevrangeByScore(String key, double max, double min, Set<String> zrevrangeByScore(String key, double max, double min,
int offset, int count); int offset, int count);
Set<Tuple> zrangeByScoreWithScores(String key, double min, double max); Set<Tuple> zrangeByScoreWithScores(String key, double min, double max);
Set<Tuple> zrevrangeByScoreWithScores(String key, double max, double min); Set<Tuple> zrevrangeByScoreWithScores(String key, double max, double min);
Set<Tuple> zrangeByScoreWithScores(String key, double min, double max, Set<Tuple> zrangeByScoreWithScores(String key, double min, double max,
int offset, int count); int offset, int count);
Set<String> zrevrangeByScore(String key, String max, String min, Set<String> zrevrangeByScore(String key, String max, String min,
int offset, int count); int offset, int count);
Set<Tuple> zrangeByScoreWithScores(String key, String min, String max); Set<Tuple> zrangeByScoreWithScores(String key, String min, String max);
Set<Tuple> zrevrangeByScoreWithScores(String key, String max, String min); Set<Tuple> zrevrangeByScoreWithScores(String key, String max, String min);
Set<Tuple> zrangeByScoreWithScores(String key, String min, String max, Set<Tuple> zrangeByScoreWithScores(String key, String min, String max,
int offset, int count); int offset, int count);
Set<Tuple> zrevrangeByScoreWithScores(String key, double max, double min, Set<Tuple> zrevrangeByScoreWithScores(String key, double max, double min,
int offset, int count); int offset, int count);
Set<Tuple> zrevrangeByScoreWithScores(String key, String max, String min, Set<Tuple> zrevrangeByScoreWithScores(String key, String max, String min,
int offset, int count); int offset, int count);
Long zremrangeByRank(String key, long start, long end); Long zremrangeByRank(String key, long start, long end);
Long zremrangeByScore(String key, double start, double end); Long zremrangeByScore(String key, double start, double end);
Long zremrangeByScore(String key, String start, String end); Long zremrangeByScore(String key, String start, String end);
Long linsert(String key, Client.LIST_POSITION where, String pivot, Long linsert(String key, Client.LIST_POSITION where, String pivot,
String value); String value);
Long lpushx(String key, String... string); Long lpushx(String key, String... string);
Long rpushx(String key, String... string); Long rpushx(String key, String... string);
List<String> blpop(String arg); List<String> blpop(String arg);
@@ -211,4 +210,10 @@ public interface
Long bitcount(final String key); Long bitcount(final String key);
Long bitcount(final String key, long start, long end); Long bitcount(final String key, long start, long end);
ScanResult<Map.Entry<String, String>> hscan(final String key, int cursor);
ScanResult<String> sscan(final String key, int cursor);
ScanResult<Tuple> zscan(final String key, int cursor);
} }

View File

@@ -1,11 +1,13 @@
package redis.clients.jedis; package redis.clients.jedis;
import org.apache.commons.pool.BasePoolableObjectFactory; import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
/** /**
* PoolableObjectFactory custom impl. * PoolableObjectFactory custom impl.
*/ */
class JedisFactory extends BasePoolableObjectFactory { class JedisFactory implements PooledObjectFactory<Jedis> {
private final String host; private final String host;
private final int port; private final int port;
private final int timeout; private final int timeout;
@@ -13,75 +15,80 @@ class JedisFactory extends BasePoolableObjectFactory {
private final int database; private final int database;
private final String clientName; private final String clientName;
public JedisFactory(final String host, final int port, public JedisFactory(final String host, final int port, final int timeout,
final int timeout, final String password, final int database) { final String password, final int database) {
this(host, port, timeout, password, database, null); this(host, port, timeout, password, database, null);
}
public JedisFactory(final String host, final int port,
final int timeout, final String password, final int database, final String clientName) {
super();
this.host = host;
this.port = port;
this.timeout = timeout;
this.password = password;
this.database = database;
this.clientName = clientName;
} }
public Object makeObject() throws Exception { public JedisFactory(final String host, final int port, final int timeout,
final Jedis jedis = new Jedis(this.host, this.port, this.timeout); final String password, final int database, final String clientName) {
super();
jedis.connect(); this.host = host;
if (null != this.password) { this.port = port;
jedis.auth(this.password); this.timeout = timeout;
} this.password = password;
if( database != 0 ) { this.database = database;
jedis.select(database); this.clientName = clientName;
}
if ( clientName != null ) {
jedis.clientSetname(clientName);
}
return jedis;
} }
@Override @Override
public void activateObject(Object obj) throws Exception { public void activateObject(PooledObject<Jedis> pooledJedis)
if (obj instanceof Jedis) { throws Exception {
final Jedis jedis = (Jedis)obj; final BinaryJedis jedis = pooledJedis.getObject();
if (jedis.getDB() != database) { if (jedis.getDB() != database) {
jedis.select(database); jedis.select(database);
} }
}
@Override
public void destroyObject(PooledObject<Jedis> pooledJedis) throws Exception {
final BinaryJedis jedis = pooledJedis.getObject();
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
} }
jedis.disconnect();
} catch (Exception e) {
}
}
} }
public void destroyObject(final Object obj) throws Exception { @Override
if (obj instanceof Jedis) { public PooledObject<Jedis> makeObject() throws Exception {
final Jedis jedis = (Jedis) obj; final Jedis jedis = new Jedis(this.host, this.port, this.timeout);
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
}
jedis.disconnect();
} catch (Exception e) {
} jedis.connect();
} if (null != this.password) {
} jedis.auth(this.password);
}
if (database != 0) {
jedis.select(database);
}
if (clientName != null) {
jedis.clientSetname(clientName);
}
return new DefaultPooledObject<Jedis>(jedis);
} }
public boolean validateObject(final Object obj) { @Override
if (obj instanceof Jedis) { public void passivateObject(PooledObject<Jedis> pooledJedis)
final Jedis jedis = (Jedis) obj; throws Exception {
try { // TODO maybe should select db 0? Not sure right now.
return jedis.isConnected() && jedis.ping().equals("PONG"); }
} catch (final Exception e) {
return false; @Override
} public boolean validateObject(PooledObject<Jedis> pooledJedis) {
} else { final BinaryJedis jedis = pooledJedis.getObject();
return false; try {
} return jedis.isConnected() && jedis.ping().equals("PONG");
} catch (final Exception e) {
return false;
}
} }
} }

View File

@@ -4,12 +4,12 @@ public abstract class JedisMonitor {
protected Client client; protected Client client;
public void proceed(Client client) { public void proceed(Client client) {
this.client = client; this.client = client;
this.client.setTimeoutInfinite(); this.client.setTimeoutInfinite();
do { do {
String command = client.getBulkReply(); String command = client.getBulkReply();
onCommand(command); onCommand(command);
} while (client.isConnected()); } while (client.isConnected());
} }
public abstract void onCommand(String command); public abstract void onCommand(String command);

View File

@@ -2,19 +2,21 @@ package redis.clients.jedis;
import java.net.URI; import java.net.URI;
import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool.Config; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.util.Pool; import redis.clients.util.Pool;
public class JedisPool extends Pool<Jedis> { public class JedisPool extends Pool<Jedis> {
public JedisPool(final Config poolConfig, final String host) { public JedisPool(final GenericObjectPoolConfig poolConfig, final String host) {
this(poolConfig, host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, null); this(poolConfig, host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT,
null, Protocol.DEFAULT_DATABASE, null);
} }
public JedisPool(String host, int port) { public JedisPool(String host, int port) {
this(new Config(), host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, null); this(new GenericObjectPoolConfig(), host, port,
Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, null);
} }
public JedisPool(final String host) { public JedisPool(final String host) {
@@ -24,12 +26,15 @@ public class JedisPool extends Pool<Jedis> {
int port = uri.getPort(); int port = uri.getPort();
String password = uri.getUserInfo().split(":", 2)[1]; String password = uri.getUserInfo().split(":", 2)[1];
int database = Integer.parseInt(uri.getPath().split("/", 2)[1]); int database = Integer.parseInt(uri.getPath().split("/", 2)[1]);
this.internalPool = new GenericObjectPool(new JedisFactory(h, port, this.internalPool = new GenericObjectPool<Jedis>(
Protocol.DEFAULT_TIMEOUT, password, database, null), new Config()); new JedisFactory(h, port, Protocol.DEFAULT_TIMEOUT,
password, database, null),
new GenericObjectPoolConfig());
} else { } else {
this.internalPool = new GenericObjectPool(new JedisFactory(host, this.internalPool = new GenericObjectPool<Jedis>(new JedisFactory(
Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, null, host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT,
Protocol.DEFAULT_DATABASE, null), new Config()); null, Protocol.DEFAULT_DATABASE, null),
new GenericObjectPoolConfig());
} }
} }
@@ -38,39 +43,48 @@ public class JedisPool extends Pool<Jedis> {
int port = uri.getPort(); int port = uri.getPort();
String password = uri.getUserInfo().split(":", 2)[1]; String password = uri.getUserInfo().split(":", 2)[1];
int database = Integer.parseInt(uri.getPath().split("/", 2)[1]); int database = Integer.parseInt(uri.getPath().split("/", 2)[1]);
this.internalPool = new GenericObjectPool(new JedisFactory(h, port, this.internalPool = new GenericObjectPool<Jedis>(new JedisFactory(h,
Protocol.DEFAULT_TIMEOUT, password, database, null), new Config()); port, Protocol.DEFAULT_TIMEOUT, password, database, null),
new GenericObjectPoolConfig());
} }
public JedisPool(final Config poolConfig, final String host, int port, public JedisPool(final GenericObjectPoolConfig poolConfig,
int timeout, final String password) { final String host, int port, int timeout, final String password) {
this(poolConfig, host, port, timeout, password, Protocol.DEFAULT_DATABASE, null); this(poolConfig, host, port, timeout, password,
Protocol.DEFAULT_DATABASE, null);
} }
public JedisPool(final Config poolConfig, final String host, final int port) { public JedisPool(final GenericObjectPoolConfig poolConfig,
this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, null); final String host, final int port) {
this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT, null,
Protocol.DEFAULT_DATABASE, null);
} }
public JedisPool(final Config poolConfig, final String host, final int port, final int timeout) { public JedisPool(final GenericObjectPoolConfig poolConfig,
this(poolConfig, host, port, timeout, null, Protocol.DEFAULT_DATABASE, null); final String host, final int port, final int timeout) {
this(poolConfig, host, port, timeout, null, Protocol.DEFAULT_DATABASE,
null);
} }
public JedisPool(final Config poolConfig, final String host, int port, int timeout, final String password, public JedisPool(final GenericObjectPoolConfig poolConfig,
final int database) { final String host, int port, int timeout, final String password,
this(poolConfig, host, port, timeout, password, database, null); final int database) {
this(poolConfig, host, port, timeout, password, database, null);
} }
public JedisPool(final Config poolConfig, final String host, int port, int timeout, final String password, public JedisPool(final GenericObjectPoolConfig poolConfig,
final int database, final String clientName) { final String host, int port, int timeout, final String password,
super(poolConfig, new JedisFactory(host, port, timeout, password, database, clientName)); final int database, final String clientName) {
super(poolConfig, new JedisFactory(host, port, timeout, password,
database, clientName));
} }
public void returnBrokenResource(final Jedis resource) {
public void returnBrokenResource(final BinaryJedis resource) { returnBrokenResourceObject(resource);
returnBrokenResourceObject(resource);
} }
public void returnResource(final BinaryJedis resource) { public void returnResource(final Jedis resource) {
returnResourceObject(resource); resource.resetState();
returnResourceObject(resource);
} }
} }

View File

@@ -1,132 +1,13 @@
package redis.clients.jedis; package redis.clients.jedis;
import org.apache.commons.pool.impl.GenericObjectPool.Config; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
/** public class JedisPoolConfig extends GenericObjectPoolConfig {
* Subclass of org.apache.commons.pool.impl.GenericObjectPool.Config that
* includes getters/setters so it can be more easily configured by Spring and
* other IoC frameworks.
*
* Spring example:
*
* <bean id="jedisConfig" class="redis.clients.jedis.JedisPoolConfig"> <property
* name="testWhileIdle" value="true"/> </bean>
*
* <bean id="jedisPool" class="redis.clients.jedis.JedisPool"
* destroy-method="destroy"> <constructor-arg ref="jedisConfig" />
* <constructor-arg value="localhost" /> <constructor-arg type="int"
* value="6379" /> </bean>
*
* For information on parameters refer to:
*
* http://commons.apache.org/pool/apidocs/org/apache/commons/pool/impl/
* GenericObjectPool.html
*/
public class JedisPoolConfig extends Config {
public JedisPoolConfig() { public JedisPoolConfig() {
// defaults to make your life with connection pool easier :) // defaults to make your life with connection pool easier :)
setTestWhileIdle(true); setTestWhileIdle(true);
setMinEvictableIdleTimeMillis(60000); setMinEvictableIdleTimeMillis(60000);
setTimeBetweenEvictionRunsMillis(30000); setTimeBetweenEvictionRunsMillis(30000);
setNumTestsPerEvictionRun(-1); setNumTestsPerEvictionRun(-1);
} }
public int getMaxIdle() {
return maxIdle;
}
public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public long getMaxWait() {
return maxWait;
}
public void setMaxWait(long maxWait) {
this.maxWait = maxWait;
}
public byte getWhenExhaustedAction() {
return whenExhaustedAction;
}
public void setWhenExhaustedAction(byte whenExhaustedAction) {
this.whenExhaustedAction = whenExhaustedAction;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public long getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(
long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public int getNumTestsPerEvictionRun() {
return numTestsPerEvictionRun;
}
public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
this.numTestsPerEvictionRun = numTestsPerEvictionRun;
}
public long getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public long getSoftMinEvictableIdleTimeMillis() {
return softMinEvictableIdleTimeMillis;
}
public void setSoftMinEvictableIdleTimeMillis(
long softMinEvictableIdleTimeMillis) {
this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
}
} }

View File

@@ -16,12 +16,12 @@ import redis.clients.util.SafeEncoder;
public abstract class JedisPubSub { public abstract class JedisPubSub {
private int subscribedChannels = 0; private int subscribedChannels = 0;
private Client client; private volatile Client client;
public abstract void onMessage(String channel, String message); public abstract void onMessage(String channel, String message);
public abstract void onPMessage(String pattern, String channel, public abstract void onPMessage(String pattern, String channel,
String message); String message);
public abstract void onSubscribe(String channel, int subscribedChannels); public abstract void onSubscribe(String channel, int subscribedChannels);
@@ -32,115 +32,145 @@ public abstract class JedisPubSub {
public abstract void onPSubscribe(String pattern, int subscribedChannels); public abstract void onPSubscribe(String pattern, int subscribedChannels);
public void unsubscribe() { public void unsubscribe() {
if (client == null) { if (client == null) {
throw new JedisConnectionException( throw new JedisConnectionException(
"JedisPubSub was not subscribed to a Jedis instance."); "JedisPubSub was not subscribed to a Jedis instance.");
} }
client.unsubscribe(); client.unsubscribe();
client.flush(); client.flush();
} }
public void unsubscribe(String... channels) { public void unsubscribe(String... channels) {
client.unsubscribe(channels); if (client == null) {
client.flush(); throw new JedisConnectionException(
"JedisPubSub is not subscribed to a Jedis instance.");
}
client.unsubscribe(channels);
client.flush();
} }
public void subscribe(String... channels) { public void subscribe(String... channels) {
client.subscribe(channels); if (client == null) {
client.flush(); throw new JedisConnectionException(
"JedisPubSub is not subscribed to a Jedis instance.");
}
client.subscribe(channels);
client.flush();
} }
public void psubscribe(String... patterns) { public void psubscribe(String... patterns) {
client.psubscribe(patterns); if (client == null) {
client.flush(); throw new JedisConnectionException(
"JedisPubSub is not subscribed to a Jedis instance.");
}
client.psubscribe(patterns);
client.flush();
} }
public void punsubscribe() { public void punsubscribe() {
client.punsubscribe(); if (client == null) {
client.flush(); throw new JedisConnectionException(
"JedisPubSub is not subscribed to a Jedis instance.");
}
client.punsubscribe();
client.flush();
} }
public void punsubscribe(String... patterns) { public void punsubscribe(String... patterns) {
client.punsubscribe(patterns); if (client == null) {
client.flush(); throw new JedisConnectionException(
"JedisPubSub is not subscribed to a Jedis instance.");
}
client.punsubscribe(patterns);
client.flush();
} }
public boolean isSubscribed() { public boolean isSubscribed() {
return subscribedChannels > 0; return subscribedChannels > 0;
} }
public void proceedWithPatterns(Client client, String... patterns) { public void proceedWithPatterns(Client client, String... patterns) {
this.client = client; this.client = client;
client.psubscribe(patterns); client.psubscribe(patterns);
client.flush(); client.flush();
process(client); process(client);
} }
public void proceed(Client client, String... channels) { public void proceed(Client client, String... channels) {
this.client = client; this.client = client;
client.subscribe(channels); client.subscribe(channels);
client.flush(); client.flush();
process(client); process(client);
} }
private void process(Client client) { private void process(Client client) {
do {
List<Object> reply = client.getObjectMultiBulkReply(); do {
final Object firstObj = reply.get(0); List<Object> reply = client.getRawObjectMultiBulkReply();
if (!(firstObj instanceof byte[])) { final Object firstObj = reply.get(0);
throw new JedisException("Unknown message type: " + firstObj); if (!(firstObj instanceof byte[])) {
} throw new JedisException("Unknown message type: " + firstObj);
final byte[] resp = (byte[]) firstObj; }
if (Arrays.equals(SUBSCRIBE.raw, resp)) { final byte[] resp = (byte[]) firstObj;
subscribedChannels = ((Long) reply.get(2)).intValue(); if (Arrays.equals(SUBSCRIBE.raw, resp)) {
final byte[] bchannel = (byte[]) reply.get(1); subscribedChannels = ((Long) reply.get(2)).intValue();
final String strchannel = (bchannel == null) ? null final byte[] bchannel = (byte[]) reply.get(1);
: SafeEncoder.encode(bchannel); final String strchannel = (bchannel == null) ? null
onSubscribe(strchannel, subscribedChannels); : SafeEncoder.encode(bchannel);
} else if (Arrays.equals(UNSUBSCRIBE.raw, resp)) { onSubscribe(strchannel, subscribedChannels);
subscribedChannels = ((Long) reply.get(2)).intValue(); } else if (Arrays.equals(UNSUBSCRIBE.raw, resp)) {
final byte[] bchannel = (byte[]) reply.get(1); subscribedChannels = ((Long) reply.get(2)).intValue();
final String strchannel = (bchannel == null) ? null final byte[] bchannel = (byte[]) reply.get(1);
: SafeEncoder.encode(bchannel); final String strchannel = (bchannel == null) ? null
onUnsubscribe(strchannel, subscribedChannels); : SafeEncoder.encode(bchannel);
} else if (Arrays.equals(MESSAGE.raw, resp)) { onUnsubscribe(strchannel, subscribedChannels);
final byte[] bchannel = (byte[]) reply.get(1); } else if (Arrays.equals(MESSAGE.raw, resp)) {
final byte[] bmesg = (byte[]) reply.get(2); final byte[] bchannel = (byte[]) reply.get(1);
final String strchannel = (bchannel == null) ? null final byte[] bmesg = (byte[]) reply.get(2);
: SafeEncoder.encode(bchannel); final String strchannel = (bchannel == null) ? null
final String strmesg = (bmesg == null) ? null : SafeEncoder : SafeEncoder.encode(bchannel);
.encode(bmesg); final String strmesg = (bmesg == null) ? null : SafeEncoder
onMessage(strchannel, strmesg); .encode(bmesg);
} else if (Arrays.equals(PMESSAGE.raw, resp)) { onMessage(strchannel, strmesg);
final byte[] bpattern = (byte[]) reply.get(1); } else if (Arrays.equals(PMESSAGE.raw, resp)) {
final byte[] bchannel = (byte[]) reply.get(2); final byte[] bpattern = (byte[]) reply.get(1);
final byte[] bmesg = (byte[]) reply.get(3); final byte[] bchannel = (byte[]) reply.get(2);
final String strpattern = (bpattern == null) ? null final byte[] bmesg = (byte[]) reply.get(3);
: SafeEncoder.encode(bpattern); final String strpattern = (bpattern == null) ? null
final String strchannel = (bchannel == null) ? null : SafeEncoder.encode(bpattern);
: SafeEncoder.encode(bchannel); final String strchannel = (bchannel == null) ? null
final String strmesg = (bmesg == null) ? null : SafeEncoder : SafeEncoder.encode(bchannel);
.encode(bmesg); final String strmesg = (bmesg == null) ? null : SafeEncoder
onPMessage(strpattern, strchannel, strmesg); .encode(bmesg);
} else if (Arrays.equals(PSUBSCRIBE.raw, resp)) { onPMessage(strpattern, strchannel, strmesg);
subscribedChannels = ((Long) reply.get(2)).intValue(); } else if (Arrays.equals(PSUBSCRIBE.raw, resp)) {
final byte[] bpattern = (byte[]) reply.get(1); subscribedChannels = ((Long) reply.get(2)).intValue();
final String strpattern = (bpattern == null) ? null final byte[] bpattern = (byte[]) reply.get(1);
: SafeEncoder.encode(bpattern); final String strpattern = (bpattern == null) ? null
onPSubscribe(strpattern, subscribedChannels); : SafeEncoder.encode(bpattern);
} else if (Arrays.equals(PUNSUBSCRIBE.raw, resp)) { onPSubscribe(strpattern, subscribedChannels);
subscribedChannels = ((Long) reply.get(2)).intValue(); } else if (Arrays.equals(PUNSUBSCRIBE.raw, resp)) {
final byte[] bpattern = (byte[]) reply.get(1); subscribedChannels = ((Long) reply.get(2)).intValue();
final String strpattern = (bpattern == null) ? null final byte[] bpattern = (byte[]) reply.get(1);
: SafeEncoder.encode(bpattern); final String strpattern = (bpattern == null) ? null
onPUnsubscribe(strpattern, subscribedChannels); : SafeEncoder.encode(bpattern);
} else { onPUnsubscribe(strpattern, subscribedChannels);
throw new JedisException("Unknown message type: " + firstObj); } else {
} throw new JedisException("Unknown message type: " + firstObj);
} while (isSubscribed()); }
} while (isSubscribed());
/* Invalidate instance since this thread is no longer listening */
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() {
return subscribedChannels; return subscribedChannels;
} }
} }

View File

@@ -0,0 +1,19 @@
package redis.clients.jedis;
import java.util.Set;
public class JedisRandomConnectionHandler extends JedisClusterConnectionHandler {
public JedisRandomConnectionHandler(Set<HostAndPort> nodes) {
super(nodes);
}
public Jedis getConnection() {
return getRandomConnection().getResource();
}
@Override
Jedis getConnectionFromSlot(int slot) {
return getRandomConnection().getResource();
}
}

View File

@@ -7,14 +7,14 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.apache.commons.pool.impl.GenericObjectPool.Config; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.util.Pool; import redis.clients.util.Pool;
public class JedisSentinelPool extends Pool<Jedis> { public class JedisSentinelPool extends Pool<Jedis> {
protected Config poolConfig; protected GenericObjectPoolConfig poolConfig;
protected int timeout = Protocol.DEFAULT_TIMEOUT; protected int timeout = Protocol.DEFAULT_TIMEOUT;
@@ -27,79 +27,62 @@ public class JedisSentinelPool extends Pool<Jedis> {
protected Logger log = Logger.getLogger(getClass().getName()); protected Logger log = Logger.getLogger(getClass().getName());
public JedisSentinelPool(String masterName, Set<String> sentinels, public JedisSentinelPool(String masterName, Set<String> sentinels,
final Config poolConfig) { final GenericObjectPoolConfig poolConfig) {
this(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT, null, this(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT, null,
Protocol.DEFAULT_DATABASE); Protocol.DEFAULT_DATABASE);
} }
public JedisSentinelPool(String masterName, Set<String> sentinels) { public JedisSentinelPool(String masterName, Set<String> sentinels) {
this(masterName, sentinels, new Config(), Protocol.DEFAULT_TIMEOUT, this(masterName, sentinels, new GenericObjectPoolConfig(),
null, Protocol.DEFAULT_DATABASE); Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
} }
public JedisSentinelPool(String masterName, Set<String> sentinels, public JedisSentinelPool(String masterName, Set<String> sentinels,
String password) { String password) {
this(masterName, sentinels, new Config(), Protocol.DEFAULT_TIMEOUT, this(masterName, sentinels, new GenericObjectPoolConfig(),
password); Protocol.DEFAULT_TIMEOUT, password);
} }
public JedisSentinelPool(String masterName, Set<String> sentinels, public JedisSentinelPool(String masterName, Set<String> sentinels,
final Config poolConfig, int timeout, final String password) { final GenericObjectPoolConfig poolConfig, int timeout,
final String password) {
this(masterName, sentinels, poolConfig, timeout, password, this(masterName, sentinels, poolConfig, timeout, password,
Protocol.DEFAULT_DATABASE); Protocol.DEFAULT_DATABASE);
} }
public JedisSentinelPool(String masterName, Set<String> sentinels, public JedisSentinelPool(String masterName, Set<String> sentinels,
final Config poolConfig, final int timeout) { final GenericObjectPoolConfig poolConfig, final int timeout) {
this(masterName, sentinels, poolConfig, timeout, null, this(masterName, sentinels, poolConfig, timeout, null,
Protocol.DEFAULT_DATABASE); Protocol.DEFAULT_DATABASE);
} }
public JedisSentinelPool(String masterName, Set<String> sentinels, public JedisSentinelPool(String masterName, Set<String> sentinels,
final Config poolConfig, final String password) { final GenericObjectPoolConfig poolConfig, final String password) {
this(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT, this(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT,
password); password);
} }
public JedisSentinelPool(String masterName, Set<String> sentinels, public JedisSentinelPool(String masterName, Set<String> sentinels,
final Config poolConfig, int timeout, final String password, final GenericObjectPoolConfig poolConfig, int timeout,
final int database) { final String password, final int database) {
this.poolConfig = poolConfig; this.poolConfig = poolConfig;
this.timeout = timeout; this.timeout = timeout;
this.password = password; this.password = password;
this.database = database; this.database = database;
HostAndPort master = initSentinels(sentinels, masterName); HostAndPort master = initSentinels(sentinels, masterName);
initPool(master); initPool(master);
} }
public void returnBrokenResource(final BinaryJedis resource) { public void returnBrokenResource(final Jedis resource) {
returnBrokenResourceObject(resource); returnBrokenResourceObject(resource);
} }
public void returnResource(final BinaryJedis resource) { public void returnResource(final Jedis resource) {
resource.resetState();
returnResourceObject(resource); returnResourceObject(resource);
} }
private class HostAndPort {
String host;
int port;
@Override
public boolean equals(Object obj) {
if (obj instanceof HostAndPort) {
HostAndPort hp = (HostAndPort) obj;
return port == hp.port && host.equals(hp.host);
}
return false;
}
@Override
public String toString() {
return host + ":" + port;
}
}
private volatile HostAndPort currentHostMaster; private volatile HostAndPort currentHostMaster;
public void destroy() { public void destroy() {
@@ -118,8 +101,9 @@ public class JedisSentinelPool extends Pool<Jedis> {
if (!master.equals(currentHostMaster)) { if (!master.equals(currentHostMaster)) {
currentHostMaster = master; currentHostMaster = master;
log.info("Created JedisPool to master at " + master); log.info("Created JedisPool to master at " + master);
initPool(poolConfig, new JedisFactory(master.host, master.port, initPool(poolConfig,
timeout, password, database)); new JedisFactory(master.getHost(), master.getPort(),
timeout, password, database));
} }
} }
@@ -141,7 +125,7 @@ public class JedisSentinelPool extends Pool<Jedis> {
log.fine("Connecting to Sentinel " + hap); log.fine("Connecting to Sentinel " + hap);
try { try {
Jedis jedis = new Jedis(hap.host, hap.port); Jedis jedis = new Jedis(hap.getHost(), hap.getPort());
if (master == null) { if (master == null) {
master = toHostAndPort(jedis master = toHostAndPort(jedis
@@ -172,7 +156,7 @@ public class JedisSentinelPool extends Pool<Jedis> {
final HostAndPort hap = toHostAndPort(Arrays.asList(sentinel final HostAndPort hap = toHostAndPort(Arrays.asList(sentinel
.split(":"))); .split(":")));
MasterListener masterListener = new MasterListener(masterName, MasterListener masterListener = new MasterListener(masterName,
hap.host, hap.port); hap.getHost(), hap.getPort());
masterListeners.add(masterListener); masterListeners.add(masterListener);
masterListener.start(); masterListener.start();
} }
@@ -181,10 +165,10 @@ public class JedisSentinelPool extends Pool<Jedis> {
} }
private HostAndPort toHostAndPort(List<String> getMasterAddrByNameResult) { private HostAndPort toHostAndPort(List<String> getMasterAddrByNameResult) {
final HostAndPort hap = new HostAndPort(); String host = getMasterAddrByNameResult.get(0);
hap.host = getMasterAddrByNameResult.get(0); int port = Integer.parseInt(getMasterAddrByNameResult.get(1));
hap.port = Integer.parseInt(getMasterAddrByNameResult.get(1));
return hap; return new HostAndPort(host, port);
} }
protected class JedisPubSubAdapter extends JedisPubSub { protected class JedisPubSubAdapter extends JedisPubSub {

View File

@@ -0,0 +1,46 @@
package redis.clients.jedis;
import java.util.Set;
public class JedisSlotBasedConnectionHandler extends
JedisClusterConnectionHandler {
private Jedis currentConnection;
public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes) {
super(nodes);
}
public Jedis getConnection() {
return currentConnection != null ? currentConnection
: getRandomConnection().getResource();
}
private void returnCurrentConnection() {
if (currentConnection != null) {
nodes.get(
currentConnection.getClient().getHost()
+ currentConnection.getClient().getPort())
.returnResource(currentConnection);
}
}
@Override
public void assignSlotToNode(int slot, HostAndPort targetNode) {
super.assignSlotToNode(slot, targetNode);
getConnectionFromSlot(slot);
}
@Override
public Jedis getConnectionFromSlot(int slot) {
returnCurrentConnection();
JedisPool connectionPool = slots.get(slot);
if (connectionPool == null) {
connectionPool = getRandomConnection();
}
currentConnection = connectionPool.getResource();
return connectionPool.getResource();
}
}

View File

@@ -1,6 +1,5 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;

View File

@@ -1,16 +1,16 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
* Multikey related commands (these are split out because they are non-shardable) * Multikey related commands (these are split out because they are
* non-shardable)
*/ */
public interface MultiKeyBinaryRedisPipeline { public interface MultiKeyBinaryRedisPipeline {
Response<Long> del(byte[]... keys); Response<Long> del(byte[]... keys);
Response<List<byte[]>> blpop(byte[]... args); Response<List<byte[]>> blpop(byte[]... args);
Response<List<byte[]>> brpop(byte[]... args); Response<List<byte[]>> brpop(byte[]... args);
@@ -39,7 +39,8 @@ public interface MultiKeyBinaryRedisPipeline {
Response<Long> smove(byte[] srckey, byte[] dstkey, byte[] member); Response<Long> smove(byte[] srckey, byte[] dstkey, byte[] member);
Response<Long> sort(byte[] key, SortingParams sortingParameters, byte[] dstkey); Response<Long> sort(byte[] key, SortingParams sortingParameters,
byte[] dstkey);
Response<Long> sort(byte[] key, byte[] dstkey); Response<Long> sort(byte[] key, byte[] dstkey);

View File

@@ -1,6 +1,5 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -70,4 +69,6 @@ public interface MultiKeyCommands {
String randomKey(); String randomKey();
Long bitop(BitOP op, final String destKey, String... srcKeys); Long bitop(BitOP op, final String destKey, String... srcKeys);
ScanResult<String> scan(int cursor);
} }

View File

@@ -1,12 +1,11 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
* Multikey related commands (these are split out because they are non-shardable) * Multikey related commands (these are split out because they are
* non-shardable)
*/ */
public interface MultiKeyCommandsPipeline { public interface MultiKeyCommandsPipeline {
Response<Long> del(String... keys); Response<Long> del(String... keys);
@@ -39,7 +38,8 @@ public interface MultiKeyCommandsPipeline {
Response<Long> smove(String srckey, String dstkey, String member); Response<Long> smove(String srckey, String dstkey, String member);
Response<Long> sort(String key, SortingParams sortingParameters, String dstkey); Response<Long> sort(String key, SortingParams sortingParameters,
String dstkey);
Response<Long> sort(String key, String dstkey); Response<Long> sort(String key, String dstkey);

View File

@@ -5,397 +5,445 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
abstract class MultiKeyPipelineBase extends PipelineBase implements abstract class MultiKeyPipelineBase extends PipelineBase implements
BasicRedisPipeline, BasicRedisPipeline, MultiKeyBinaryRedisPipeline,
MultiKeyBinaryRedisPipeline, MultiKeyCommandsPipeline, ClusterPipeline {
MultiKeyCommandsPipeline {
protected Client client = null; protected Client client = null;
public Response<List<String>> brpop(String... args) { public Response<List<String>> brpop(String... args) {
client.brpop(args); client.brpop(args);
return getResponse(BuilderFactory.STRING_LIST); return getResponse(BuilderFactory.STRING_LIST);
} }
public Response<List<String>> brpop(int timeout, String... keys) { public Response<List<String>> brpop(int timeout, String... keys) {
client.brpop(timeout, keys); client.brpop(timeout, keys);
return getResponse(BuilderFactory.STRING_LIST); return getResponse(BuilderFactory.STRING_LIST);
} }
public Response<List<String>> blpop(String... args) { public Response<List<String>> blpop(String... args) {
client.blpop(args); client.blpop(args);
return getResponse(BuilderFactory.STRING_LIST); return getResponse(BuilderFactory.STRING_LIST);
} }
public Response<List<String>> blpop(int timeout, String... keys) { public Response<List<String>> blpop(int timeout, String... keys) {
client.blpop(timeout, keys); client.blpop(timeout, keys);
return getResponse(BuilderFactory.STRING_LIST); return getResponse(BuilderFactory.STRING_LIST);
} }
public Response<Map<String, String>> blpopMap(int timeout, String... keys) { public Response<Map<String, String>> blpopMap(int timeout, String... keys) {
client.blpop(timeout, keys); client.blpop(timeout, keys);
return getResponse(BuilderFactory.STRING_MAP); return getResponse(BuilderFactory.STRING_MAP);
} }
public Response<List<byte[]>> brpop(byte[]... args) { public Response<List<byte[]>> brpop(byte[]... args) {
client.brpop(args); client.brpop(args);
return getResponse(BuilderFactory.BYTE_ARRAY_LIST); return getResponse(BuilderFactory.BYTE_ARRAY_LIST);
} }
public Response<List<String>> brpop(int timeout, byte[]... keys) { public Response<List<String>> brpop(int timeout, byte[]... keys) {
client.brpop(timeout, keys); client.brpop(timeout, keys);
return getResponse(BuilderFactory.STRING_LIST); return getResponse(BuilderFactory.STRING_LIST);
} }
public Response<Map<String, String>> brpopMap(int timeout, String... keys) { public Response<Map<String, String>> brpopMap(int timeout, String... keys) {
client.blpop(timeout, keys); client.blpop(timeout, keys);
return getResponse(BuilderFactory.STRING_MAP); return getResponse(BuilderFactory.STRING_MAP);
} }
public Response<List<byte[]>> blpop(byte[]... args) { public Response<List<byte[]>> blpop(byte[]... args) {
client.blpop(args); client.blpop(args);
return getResponse(BuilderFactory.BYTE_ARRAY_LIST); return getResponse(BuilderFactory.BYTE_ARRAY_LIST);
} }
public Response<List<String>> blpop(int timeout, byte[]... keys) { public Response<List<String>> blpop(int timeout, byte[]... keys) {
client.blpop(timeout, keys); client.blpop(timeout, keys);
return getResponse(BuilderFactory.STRING_LIST); return getResponse(BuilderFactory.STRING_LIST);
} }
public Response<Long> del(String... keys) { public Response<Long> del(String... keys) {
client.del(keys); client.del(keys);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> del(byte[]... keys) { public Response<Long> del(byte[]... keys) {
client.del(keys); client.del(keys);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Set<String>> keys(String pattern) { public Response<Set<String>> keys(String pattern) {
getClient(pattern).keys(pattern); getClient(pattern).keys(pattern);
return getResponse(BuilderFactory.STRING_SET); return getResponse(BuilderFactory.STRING_SET);
} }
public Response<Set<byte[]>> keys(byte[] pattern) { public Response<Set<byte[]>> keys(byte[] pattern) {
getClient(pattern).keys(pattern); getClient(pattern).keys(pattern);
return getResponse(BuilderFactory.BYTE_ARRAY_ZSET); return getResponse(BuilderFactory.BYTE_ARRAY_ZSET);
} }
public Response<List<String>> mget(String... keys) { public Response<List<String>> mget(String... keys) {
client.mget(keys); client.mget(keys);
return getResponse(BuilderFactory.STRING_LIST); return getResponse(BuilderFactory.STRING_LIST);
} }
public Response<List<byte[]>> mget(byte[]... keys) { public Response<List<byte[]>> mget(byte[]... keys) {
client.mget(keys); client.mget(keys);
return getResponse(BuilderFactory.BYTE_ARRAY_LIST); return getResponse(BuilderFactory.BYTE_ARRAY_LIST);
} }
public Response<String> mset(String... keysvalues) { public Response<String> mset(String... keysvalues) {
client.mset(keysvalues); client.mset(keysvalues);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> mset(byte[]... keysvalues) { public Response<String> mset(byte[]... keysvalues) {
client.mset(keysvalues); client.mset(keysvalues);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<Long> msetnx(String... keysvalues) { public Response<Long> msetnx(String... keysvalues) {
client.msetnx(keysvalues); client.msetnx(keysvalues);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> msetnx(byte[]... keysvalues) { public Response<Long> msetnx(byte[]... keysvalues) {
client.msetnx(keysvalues); client.msetnx(keysvalues);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<String> rename(String oldkey, String newkey) { public Response<String> rename(String oldkey, String newkey) {
client.rename(oldkey, newkey); client.rename(oldkey, newkey);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> rename(byte[] oldkey, byte[] newkey) { public Response<String> rename(byte[] oldkey, byte[] newkey) {
client.rename(oldkey, newkey); client.rename(oldkey, newkey);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<Long> renamenx(String oldkey, String newkey) { public Response<Long> renamenx(String oldkey, String newkey) {
client.renamenx(oldkey, newkey); client.renamenx(oldkey, newkey);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> renamenx(byte[] oldkey, byte[] newkey) { public Response<Long> renamenx(byte[] oldkey, byte[] newkey) {
client.renamenx(oldkey, newkey); client.renamenx(oldkey, newkey);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<String> rpoplpush(String srckey, String dstkey) { public Response<String> rpoplpush(String srckey, String dstkey) {
client.rpoplpush(srckey, dstkey); client.rpoplpush(srckey, dstkey);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<byte[]> rpoplpush(byte[] srckey, byte[] dstkey) { public Response<byte[]> rpoplpush(byte[] srckey, byte[] dstkey) {
client.rpoplpush(srckey, dstkey); client.rpoplpush(srckey, dstkey);
return getResponse(BuilderFactory.BYTE_ARRAY); return getResponse(BuilderFactory.BYTE_ARRAY);
} }
public Response<Set<String>> sdiff(String... keys) { public Response<Set<String>> sdiff(String... keys) {
client.sdiff(keys); client.sdiff(keys);
return getResponse(BuilderFactory.STRING_SET); return getResponse(BuilderFactory.STRING_SET);
} }
public Response<Set<byte[]>> sdiff(byte[]... keys) { public Response<Set<byte[]>> sdiff(byte[]... keys) {
client.sdiff(keys); client.sdiff(keys);
return getResponse(BuilderFactory.BYTE_ARRAY_ZSET); return getResponse(BuilderFactory.BYTE_ARRAY_ZSET);
} }
public Response<Long> sdiffstore(String dstkey, String... keys) { public Response<Long> sdiffstore(String dstkey, String... keys) {
client.sdiffstore(dstkey, keys); client.sdiffstore(dstkey, keys);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> sdiffstore(byte[] dstkey, byte[]... keys) { public Response<Long> sdiffstore(byte[] dstkey, byte[]... keys) {
client.sdiffstore(dstkey, keys); client.sdiffstore(dstkey, keys);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Set<String>> sinter(String... keys) { public Response<Set<String>> sinter(String... keys) {
client.sinter(keys); client.sinter(keys);
return getResponse(BuilderFactory.STRING_SET); return getResponse(BuilderFactory.STRING_SET);
} }
public Response<Set<byte[]>> sinter(byte[]... keys) { public Response<Set<byte[]>> sinter(byte[]... keys) {
client.sinter(keys); client.sinter(keys);
return getResponse(BuilderFactory.BYTE_ARRAY_ZSET); return getResponse(BuilderFactory.BYTE_ARRAY_ZSET);
} }
public Response<Long> sinterstore(String dstkey, String... keys) { public Response<Long> sinterstore(String dstkey, String... keys) {
client.sinterstore(dstkey, keys); client.sinterstore(dstkey, keys);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> sinterstore(byte[] dstkey, byte[]... keys) { public Response<Long> sinterstore(byte[] dstkey, byte[]... keys) {
client.sinterstore(dstkey, keys); client.sinterstore(dstkey, keys);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> smove(String srckey, String dstkey, String member) { public Response<Long> smove(String srckey, String dstkey, String member) {
client.smove(srckey, dstkey, member); client.smove(srckey, dstkey, member);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> smove(byte[] srckey, byte[] dstkey, byte[] member) { public Response<Long> smove(byte[] srckey, byte[] dstkey, byte[] member) {
client.smove(srckey, dstkey, member); client.smove(srckey, dstkey, member);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> sort(String key, public Response<Long> sort(String key, SortingParams sortingParameters,
SortingParams sortingParameters, String dstkey) { String dstkey) {
client.sort(key, sortingParameters, dstkey); client.sort(key, sortingParameters, dstkey);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> sort(byte[] key, public Response<Long> sort(byte[] key, SortingParams sortingParameters,
SortingParams sortingParameters, byte[] dstkey) { byte[] dstkey) {
client.sort(key, sortingParameters, dstkey); client.sort(key, sortingParameters, dstkey);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> sort(String key, String dstkey) { public Response<Long> sort(String key, String dstkey) {
client.sort(key, dstkey); client.sort(key, dstkey);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> sort(byte[] key, byte[] dstkey) { public Response<Long> sort(byte[] key, byte[] dstkey) {
client.sort(key, dstkey); client.sort(key, dstkey);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Set<String>> sunion(String... keys) { public Response<Set<String>> sunion(String... keys) {
client.sunion(keys); client.sunion(keys);
return getResponse(BuilderFactory.STRING_SET); return getResponse(BuilderFactory.STRING_SET);
} }
public Response<Set<byte[]>> sunion(byte[]... keys) { public Response<Set<byte[]>> sunion(byte[]... keys) {
client.sunion(keys); client.sunion(keys);
return getResponse(BuilderFactory.BYTE_ARRAY_ZSET); return getResponse(BuilderFactory.BYTE_ARRAY_ZSET);
} }
public Response<Long> sunionstore(String dstkey, String... keys) { public Response<Long> sunionstore(String dstkey, String... keys) {
client.sunionstore(dstkey, keys); client.sunionstore(dstkey, keys);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> sunionstore(byte[] dstkey, byte[]... keys) { public Response<Long> sunionstore(byte[] dstkey, byte[]... keys) {
client.sunionstore(dstkey, keys); client.sunionstore(dstkey, keys);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<String> watch(String... keys) { public Response<String> watch(String... keys) {
client.watch(keys); client.watch(keys);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> watch(byte[]... keys) { public Response<String> watch(byte[]... keys) {
client.watch(keys); client.watch(keys);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<Long> zinterstore(String dstkey, String... sets) { public Response<Long> zinterstore(String dstkey, String... sets) {
client.zinterstore(dstkey, sets); client.zinterstore(dstkey, sets);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> zinterstore(byte[] dstkey, byte[]... sets) { public Response<Long> zinterstore(byte[] dstkey, byte[]... sets) {
client.zinterstore(dstkey, sets); client.zinterstore(dstkey, sets);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> zinterstore(String dstkey, ZParams params, public Response<Long> zinterstore(String dstkey, ZParams params,
String... sets) { String... sets) {
client.zinterstore(dstkey, params, sets); client.zinterstore(dstkey, params, sets);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> zinterstore(byte[] dstkey, ZParams params, public Response<Long> zinterstore(byte[] dstkey, ZParams params,
byte[]... sets) { byte[]... sets) {
client.zinterstore(dstkey, params, sets); client.zinterstore(dstkey, params, sets);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> zunionstore(String dstkey, String... sets) { public Response<Long> zunionstore(String dstkey, String... sets) {
client.zunionstore(dstkey, sets); client.zunionstore(dstkey, sets);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> zunionstore(byte[] dstkey, byte[]... sets) { public Response<Long> zunionstore(byte[] dstkey, byte[]... sets) {
client.zunionstore(dstkey, sets); client.zunionstore(dstkey, sets);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> zunionstore(String dstkey, ZParams params, public Response<Long> zunionstore(String dstkey, ZParams params,
String... sets) { String... sets) {
client.zunionstore(dstkey, params, sets); client.zunionstore(dstkey, params, sets);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> zunionstore(byte[] dstkey, ZParams params, public Response<Long> zunionstore(byte[] dstkey, ZParams params,
byte[]... sets) { byte[]... sets) {
client.zunionstore(dstkey, params, sets); client.zunionstore(dstkey, params, sets);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<String> bgrewriteaof() { public Response<String> bgrewriteaof() {
client.bgrewriteaof(); client.bgrewriteaof();
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> bgsave() { public Response<String> bgsave() {
client.bgsave(); client.bgsave();
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> configGet(String pattern) { public Response<String> configGet(String pattern) {
client.configGet(pattern); client.configGet(pattern);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> configSet(String parameter, String value) { public Response<String> configSet(String parameter, String value) {
client.configSet(parameter, value); client.configSet(parameter, value);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> brpoplpush(String source, String destination, public Response<String> brpoplpush(String source, String destination,
int timeout) { int timeout) {
client.brpoplpush(source, destination, timeout); client.brpoplpush(source, destination, timeout);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<byte[]> brpoplpush(byte[] source, byte[] destination, public Response<byte[]> brpoplpush(byte[] source, byte[] destination,
int timeout) { int timeout) {
client.brpoplpush(source, destination, timeout); client.brpoplpush(source, destination, timeout);
return getResponse(BuilderFactory.BYTE_ARRAY); return getResponse(BuilderFactory.BYTE_ARRAY);
} }
public Response<String> configResetStat() { public Response<String> configResetStat() {
client.configResetStat(); client.configResetStat();
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> save() { public Response<String> save() {
client.save(); client.save();
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<Long> lastsave() { public Response<Long> lastsave() {
client.lastsave(); client.lastsave();
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> publish(String channel, String message) { public Response<Long> publish(String channel, String message) {
client.publish(channel, message); client.publish(channel, message);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> publish(byte[] channel, byte[] message) { public Response<Long> publish(byte[] channel, byte[] message) {
client.publish(channel, message); client.publish(channel, message);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<String> randomKey() { public Response<String> randomKey() {
client.randomKey(); client.randomKey();
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<byte[]> randomKeyBinary() { public Response<byte[]> randomKeyBinary() {
client.randomKey(); client.randomKey();
return getResponse(BuilderFactory.BYTE_ARRAY); return getResponse(BuilderFactory.BYTE_ARRAY);
} }
public Response<String> flushDB() { public Response<String> flushDB() {
client.flushDB(); client.flushDB();
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> flushAll() { public Response<String> flushAll() {
client.flushAll(); client.flushAll();
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> info() { public Response<String> info() {
client.info(); client.info();
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<Long> dbSize() { public Response<Long> dbSize() {
client.dbSize(); client.dbSize();
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<String> shutdown() { public Response<String> shutdown() {
client.shutdown(); client.shutdown();
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> ping() { public Response<String> ping() {
client.ping(); client.ping();
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<String> select(int index) { public Response<String> select(int index) {
client.select(index); client.select(index);
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<Long> bitop(BitOP op, byte[] destKey, byte[]... srcKeys) { public Response<Long> bitop(BitOP op, byte[] destKey, byte[]... srcKeys) {
client.bitop(op, destKey, srcKeys); client.bitop(op, destKey, srcKeys);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
} }
public Response<Long> bitop(BitOP op, String destKey, String... srcKeys) { public Response<Long> bitop(BitOP op, String destKey, String... srcKeys) {
client.bitop(op, destKey, srcKeys); client.bitop(op, destKey, srcKeys);
return getResponse(BuilderFactory.LONG); return getResponse(BuilderFactory.LONG);
}
public Response<String> clusterNodes() {
client.clusterNodes();
return getResponse(BuilderFactory.STRING);
}
public Response<String> clusterMeet(final String ip, final int port) {
client.clusterMeet(ip, port);
return getResponse(BuilderFactory.STRING);
}
public Response<String> clusterAddSlots(final int... slots) {
client.clusterAddSlots(slots);
return getResponse(BuilderFactory.STRING);
}
public Response<String> clusterDelSlots(final int... slots) {
client.clusterDelSlots(slots);
return getResponse(BuilderFactory.STRING);
}
public Response<String> clusterInfo() {
client.clusterInfo();
return getResponse(BuilderFactory.STRING);
}
public Response<List<String>> clusterGetKeysInSlot(final int slot,
final int count) {
client.clusterGetKeysInSlot(slot, count);
return getResponse(BuilderFactory.STRING_LIST);
}
public Response<String> clusterSetSlotNode(final int slot,
final String nodeId) {
client.clusterSetSlotNode(slot, nodeId);
return getResponse(BuilderFactory.STRING);
}
public Response<String> clusterSetSlotMigrating(final int slot,
final String nodeId) {
client.clusterSetSlotMigrating(slot, nodeId);
return getResponse(BuilderFactory.STRING);
}
public Response<String> clusterSetSlotImporting(final int slot,
final String nodeId) {
client.clusterSetSlotImporting(slot, nodeId);
return getResponse(BuilderFactory.STRING);
} }
} }

View File

@@ -1,66 +1,66 @@
package redis.clients.jedis; package redis.clients.jedis;
import redis.clients.jedis.exceptions.JedisDataException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class Pipeline extends MultiKeyPipelineBase { import redis.clients.jedis.exceptions.JedisDataException;
private MultiResponseBuilder currentMulti;
private class MultiResponseBuilder extends Builder<List<Object>>{
private List<Response<?>> responses = new ArrayList<Response<?>>();
@Override
public List<Object> build(Object data) {
@SuppressWarnings("unchecked")
List<Object> list = (List<Object>)data;
List<Object> values = new ArrayList<Object>();
if(list.size() != responses.size()){
throw new JedisDataException("Expected data size " + responses.size() + " but was " + list.size());
}
for(int i=0;i<list.size();i++){
Response<?> response = responses.get(i);
response.set(list.get(i));
values.add(response.get());
}
return values;
}
public void addResponse(Response<?> response){ public class Pipeline extends MultiKeyPipelineBase {
responses.add(response);
} private MultiResponseBuilder currentMulti;
private class MultiResponseBuilder extends Builder<List<Object>> {
private List<Response<?>> responses = new ArrayList<Response<?>>();
@Override
public List<Object> build(Object data) {
@SuppressWarnings("unchecked")
List<Object> list = (List<Object>) data;
List<Object> values = new ArrayList<Object>();
if (list.size() != responses.size()) {
throw new JedisDataException("Expected data size "
+ responses.size() + " but was " + list.size());
}
for (int i = 0; i < list.size(); i++) {
Response<?> response = responses.get(i);
response.set(list.get(i));
values.add(response.get());
}
return values;
}
public void addResponse(Response<?> response) {
responses.add(response);
}
} }
@Override @Override
protected <T> Response<T> getResponse(Builder<T> builder) { protected <T> Response<T> getResponse(Builder<T> builder) {
if(currentMulti != null){ if (currentMulti != null) {
super.getResponse(BuilderFactory.STRING); //Expected QUEUED super.getResponse(BuilderFactory.STRING); // Expected QUEUED
Response<T> lr = new Response<T>(builder); Response<T> lr = new Response<T>(builder);
currentMulti.addResponse(lr); currentMulti.addResponse(lr);
return lr; return lr;
} } else {
else{ return super.getResponse(builder);
return super.getResponse(builder); }
}
} }
public void setClient(Client client) { public void setClient(Client client) {
this.client = client; this.client = client;
} }
@Override @Override
protected Client getClient(byte[] key) { protected Client getClient(byte[] key) {
return client; return client;
} }
@Override @Override
protected Client getClient(String key) { protected Client getClient(String key) {
return client; return client;
} }
/** /**
@@ -69,10 +69,10 @@ public class Pipeline extends MultiKeyPipelineBase {
* 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.getAll();
for (Object o : unformatted) { for (Object o : unformatted) {
generateResponse(o); generateResponse(o);
} }
} }
/** /**
@@ -84,37 +84,38 @@ 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.getAll();
List<Object> formatted = new ArrayList<Object>(); List<Object> formatted = new ArrayList<Object>();
for (Object o : unformatted) { for (Object o : unformatted) {
try { try {
formatted.add(generateResponse(o).get()); formatted.add(generateResponse(o).get());
} catch (JedisDataException e) { } catch (JedisDataException e) {
formatted.add(e); formatted.add(e);
} }
} }
return formatted; return formatted;
} }
public Response<String> discard() { public Response<String> discard() {
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() {
client.exec(); client.exec();
Response<List<Object>> response = super.getResponse(currentMulti); Response<List<Object>> response = super.getResponse(currentMulti);
currentMulti = null; currentMulti = null;
return response; return response;
} }
public Response<String> multi() { public Response<String> multi() {
client.multi(); client.multi();
Response<String> response = getResponse(BuilderFactory.STRING); //Expecting OK Response<String> response = getResponse(BuilderFactory.STRING); // Expecting
currentMulti = new MultiResponseBuilder(); // OK
return response; currentMulti = new MultiResponseBuilder();
return response;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,5 @@
package redis.clients.jedis; package redis.clients.jedis;
public abstract class PipelineBlock extends Pipeline { public abstract class PipelineBlock extends Pipeline {
public abstract void execute(); public abstract void execute();
} }

View File

@@ -4,14 +4,18 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import redis.clients.jedis.exceptions.JedisAskDataException;
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.JedisMovedDataException;
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;
public final class Protocol { public final class Protocol {
private static final String ASK_RESPONSE = "ASK";
private static final String MOVED_RESPONSE = "MOVED";
public static final int DEFAULT_PORT = 6379; public static final int DEFAULT_PORT = 6379;
public static final int DEFAULT_SENTINEL_PORT = 26379; public static final int DEFAULT_SENTINEL_PORT = 26379;
public static final int DEFAULT_TIMEOUT = 2000; public static final int DEFAULT_TIMEOUT = 2000;
@@ -29,7 +33,20 @@ public final class Protocol {
public static final String SENTINEL_GET_MASTER_ADDR_BY_NAME = "get-master-addr-by-name"; public static final String SENTINEL_GET_MASTER_ADDR_BY_NAME = "get-master-addr-by-name";
public static final String SENTINEL_RESET = "reset"; public static final String SENTINEL_RESET = "reset";
public static final String SENTINEL_SLAVES = "slaves"; public static final String SENTINEL_SLAVES = "slaves";
public static final String SENTINEL_IS_MASTER_DOWN_BY_ADDR = "is-master-down-by-addr";
public static final String CLUSTER_NODES = "nodes";
public static final String CLUSTER_MEET = "meet";
public static final String CLUSTER_ADDSLOTS = "addslots";
public static final String CLUSTER_DELSLOTS = "delslots";
public static final String CLUSTER_INFO = "info";
public static final String CLUSTER_GETKEYSINSLOT = "getkeysinslot";
public static final String CLUSTER_SETSLOT = "setslot";
public static final String CLUSTER_SETSLOT_NODE = "node";
public static final String CLUSTER_SETSLOT_MIGRATING = "migrating";
public static final String CLUSTER_SETSLOT_IMPORTING = "importing";
public static final String PUBSUB_CHANNELS= "channels";
public static final String PUBSUB_NUMSUB = "numsub";
public static final String PUBSUB_NUM_PAT = "numpat";
private Protocol() { private Protocol() {
// this prevent the class from instantiation // this prevent the class from instantiation
@@ -63,9 +80,33 @@ public final class Protocol {
private static void processError(final RedisInputStream is) { private static void processError(final RedisInputStream is) {
String message = is.readLine(); String message = is.readLine();
// TODO: I'm not sure if this is the best way to do this.
// Maybe Read only first 5 bytes instead?
if (message.startsWith(MOVED_RESPONSE)) {
String[] movedInfo = parseTargetHostAndSlot(message);
throw new JedisMovedDataException(message, new HostAndPort(
movedInfo[1], Integer.valueOf(movedInfo[2])),
Integer.valueOf(movedInfo[0]));
} else if (message.startsWith(ASK_RESPONSE)) {
String[] askInfo = parseTargetHostAndSlot(message);
throw new JedisAskDataException(message, new HostAndPort(
askInfo[1], Integer.valueOf(askInfo[2])),
Integer.valueOf(askInfo[0]));
}
throw new JedisDataException(message); throw new JedisDataException(message);
} }
private static String[] parseTargetHostAndSlot(
String clusterRedirectResponse) {
String[] response = new String[3];
String[] messageInfo = clusterRedirectResponse.split(" ");
String[] targetHostAndPort = messageInfo[2].split(":");
response[0] = messageInfo[1];
response[1] = targetHostAndPort[0];
response[2] = targetHostAndPort[1];
return response;
}
private static Object process(final RedisInputStream is) { private static Object process(final RedisInputStream is) {
try { try {
byte b = is.readByte(); byte b = is.readByte();
@@ -101,7 +142,11 @@ public final class Protocol {
int offset = 0; int offset = 0;
try { try {
while (offset < len) { while (offset < len) {
offset += is.read(read, offset, (len - offset)); int size = is.read(read, offset, (len - offset));
if (size == -1)
throw new JedisConnectionException(
"It seems like server has closed the connection.");
offset += size;
} }
// read 2 more bytes for the command delimiter // read 2 more bytes for the command delimiter
is.readByte(); is.readByte();
@@ -155,8 +200,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, ZCOUNT, ZRANGEBYSCORE, ZREVRANGEBYSCORE, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZUNIONSTORE, ZINTERSTORE, 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, 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, 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;
DUMP, RESTORE, PEXPIRE, PEXPIREAT, PTTL, INCRBYFLOAT, PSETEX, CLIENT, TIME, MIGRATE, HINCRBYFLOAT;
public final byte[] raw; public final byte[] raw;
@@ -166,8 +210,7 @@ public final class Protocol {
} }
public static enum Keyword { public static enum Keyword {
AGGREGATE, ALPHA, ASC, BY, DESC, GET, LIMIT, MESSAGE, NO, NOSORT, PMESSAGE, PSUBSCRIBE, PUNSUBSCRIBE, OK, ONE, QUEUED, SET, STORE, SUBSCRIBE, UNSUBSCRIBE, WEIGHTS, WITHSCORES, RESETSTAT, RESET, FLUSH, EXISTS, LOAD, KILL, LEN, REFCOUNT, ENCODING, IDLETIME, AND, OR, XOR, NOT, AGGREGATE, ALPHA, ASC, BY, DESC, GET, LIMIT, MESSAGE, NO, NOSORT, PMESSAGE, PSUBSCRIBE, PUNSUBSCRIBE, OK, ONE, QUEUED, SET, STORE, SUBSCRIBE, UNSUBSCRIBE, WEIGHTS, WITHSCORES, RESETSTAT, RESET, FLUSH, EXISTS, LOAD, KILL, LEN, REFCOUNT, ENCODING, IDLETIME, AND, OR, XOR, NOT, GETNAME, SETNAME, LIST, MATCH, COUNT;
GETNAME, SETNAME,LIST;
public final byte[] raw; public final byte[] raw;
Keyword() { Keyword() {

View File

@@ -7,21 +7,21 @@ public class Queable {
private Queue<Response<?>> pipelinedResponses = new LinkedList<Response<?>>(); private Queue<Response<?>> pipelinedResponses = new LinkedList<Response<?>>();
protected void clean() { protected void clean() {
pipelinedResponses.clear(); pipelinedResponses.clear();
} }
protected Response<?> generateResponse(Object data) { protected Response<?> generateResponse(Object data) {
Response<?> response = pipelinedResponses.poll(); Response<?> response = pipelinedResponses.poll();
if (response != null) { if (response != null) {
response.set(data); response.set(data);
} }
return response; return response;
} }
protected <T> Response<T> getResponse(Builder<T> builder) { protected <T> Response<T> getResponse(Builder<T> builder) {
Response<T> lr = new Response<T>(builder); Response<T> lr = new Response<T>(builder);
pipelinedResponses.add(lr); pipelinedResponses.add(lr);
return lr; return lr;
} }
} }

View File

@@ -32,10 +32,7 @@ public interface RedisPipeline {
Response<Boolean> getbit(String key, long offset); Response<Boolean> getbit(String key, long offset);
Response<String> getrange(String key, long startOffset, long endOffset);
Response<String> getrange(String key, long startOffset,
long endOffset);
Response<String> getSet(String key, String value); Response<String> getSet(String key, String value);
@@ -70,7 +67,7 @@ public interface RedisPipeline {
Response<String> lindex(String key, long index); Response<String> lindex(String key, long index);
Response<Long> linsert(String key, BinaryClient.LIST_POSITION where, Response<Long> linsert(String key, BinaryClient.LIST_POSITION where,
String pivot, String value); String pivot, String value);
Response<Long> llen(String key); Response<Long> llen(String key);
@@ -118,8 +115,7 @@ public interface RedisPipeline {
Response<List<String>> sort(String key); Response<List<String>> sort(String key);
Response<List<String>> sort(String key, Response<List<String>> sort(String key, SortingParams sortingParameters);
SortingParams sortingParameters);
Response<String> spop(String key); Response<String> spop(String key);
@@ -145,35 +141,31 @@ public interface RedisPipeline {
Response<Set<String>> zrange(String key, long start, long end); Response<Set<String>> zrange(String key, long start, long end);
Response<Set<String>> zrangeByScore(String key, double min, Response<Set<String>> zrangeByScore(String key, double min, double max);
double max);
Response<Set<String>> zrangeByScore(String key, String min, Response<Set<String>> zrangeByScore(String key, String min, String max);
String max);
Response<Set<String>> zrangeByScore(String key, double min, Response<Set<String>> zrangeByScore(String key, double min, double max,
double max, int offset, int count); int offset, int count);
Response<Set<Tuple>> zrangeByScoreWithScores(String key, double min, Response<Set<Tuple>> zrangeByScoreWithScores(String key, double min,
double max); double max);
Response<Set<Tuple>> zrangeByScoreWithScores(String key, double min, Response<Set<Tuple>> zrangeByScoreWithScores(String key, double min,
double max, int offset, int count); double max, int offset, int count);
Response<Set<String>> zrevrangeByScore(String key, double max, Response<Set<String>> zrevrangeByScore(String key, double max, double min);
double min);
Response<Set<String>> zrevrangeByScore(String key, String max, Response<Set<String>> zrevrangeByScore(String key, String max, String min);
String min);
Response<Set<String>> zrevrangeByScore(String key, double max, Response<Set<String>> zrevrangeByScore(String key, double max, double min,
double min, int offset, int count); int offset, int count);
Response<Set<Tuple>> zrevrangeByScoreWithScores(String key, Response<Set<Tuple>> zrevrangeByScoreWithScores(String key, double max,
double max, double min); double min);
Response<Set<Tuple>> zrevrangeByScoreWithScores(String key, Response<Set<Tuple>> zrevrangeByScoreWithScores(String key, double max,
double max, double min, int offset, int count); double min, int offset, int count);
Response<Set<Tuple>> zrangeWithScores(String key, long start, long end); Response<Set<Tuple>> zrangeWithScores(String key, long start, long end);
@@ -187,8 +179,7 @@ public interface RedisPipeline {
Response<Set<String>> zrevrange(String key, long start, long end); Response<Set<String>> zrevrange(String key, long start, long end);
Response<Set<Tuple>> zrevrangeWithScores(String key, long start, Response<Set<Tuple>> zrevrangeWithScores(String key, long start, long end);
long end);
Response<Long> zrevrank(String key, String member); Response<Long> zrevrank(String key, String member);

View File

@@ -10,34 +10,34 @@ public class Response<T> {
private Object data; private Object data;
public Response(Builder<T> b) { public Response(Builder<T> b) {
this.builder = b; this.builder = b;
} }
public void set(Object data) { public void set(Object data) {
this.data = data; this.data = data;
set = true; set = true;
} }
public T get() { public T get() {
if (!set) { if (!set) {
throw new JedisDataException( throw new JedisDataException(
"Please close pipeline or multi block before calling this method."); "Please close pipeline or multi block before calling this method.");
} }
if (!built) { if (!built) {
if(data != null ){ if (data != null) {
if (data instanceof JedisDataException){ if (data instanceof JedisDataException) {
throw new JedisDataException((JedisDataException)data); throw new JedisDataException((JedisDataException) data);
} }
response = builder.build(data); response = builder.build(data);
} }
this.data = null; this.data = null;
built = true; built = true;
} }
return response; return response;
} }
public String toString() { public String toString() {
return "Response " + builder.toString(); return "Response " + builder.toString();
} }
} }

View File

@@ -0,0 +1,29 @@
package redis.clients.jedis;
import static redis.clients.jedis.Protocol.Keyword.COUNT;
import static redis.clients.jedis.Protocol.Keyword.MATCH;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import redis.clients.util.SafeEncoder;
public class ScanParams {
private List<byte[]> params = new ArrayList<byte[]>();
public void match(final String pattern) {
params.add(MATCH.raw);
params.add(SafeEncoder.encode(pattern));
}
public void count(final int count) {
params.add(COUNT.raw);
params.add(Protocol.toByteArray(count));
}
public Collection<byte[]> getParams() {
return Collections.unmodifiableCollection(params);
}
}

View File

@@ -0,0 +1,21 @@
package redis.clients.jedis;
import java.util.List;
public class ScanResult<T> {
private int cursor;
private List<T> results;
public ScanResult(int cursor, List<T> results) {
this.cursor = cursor;
this.results = results;
}
public int getCursor() {
return cursor;
}
public List<T> getResult() {
return results;
}
}

View File

@@ -1,13 +1,14 @@
package redis.clients.jedis; package redis.clients.jedis;
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.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.Hashing;
public class ShardedJedis extends BinaryShardedJedis implements JedisCommands { public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
public ShardedJedis(List<JedisShardInfo> shards) { public ShardedJedis(List<JedisShardInfo> shards) {
super(shards); super(shards);
@@ -37,8 +38,8 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
} }
public String echo(String string) { public String echo(String string) {
Jedis j = getShard(string); Jedis j = getShard(string);
return j.echo(string); return j.echo(string);
} }
public Boolean exists(String key) { public Boolean exists(String key) {
@@ -72,8 +73,8 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
} }
public Boolean setbit(String key, long offset, String value) { public Boolean setbit(String key, long offset, String value) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.setbit(key, offset, value); return j.setbit(key, offset, value);
} }
public Boolean getbit(String key, long offset) { public Boolean getbit(String key, long offset) {
@@ -107,13 +108,13 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
} }
public List<String> blpop(String arg) { public List<String> blpop(String arg) {
Jedis j = getShard(arg); Jedis j = getShard(arg);
return j.blpop(arg); return j.blpop(arg);
} }
public List<String> brpop(String arg) { public List<String> brpop(String arg) {
Jedis j = getShard(arg); Jedis j = getShard(arg);
return j.brpop(arg); return j.brpop(arg);
} }
public Long decrBy(String key, long integer) { public Long decrBy(String key, long integer) {
@@ -227,13 +228,13 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
} }
public Long strlen(final String key) { public Long strlen(final String key) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.strlen(key); return j.strlen(key);
} }
public Long move(String key, int dbIndex) { public Long move(String key, int dbIndex) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.move(key, dbIndex); return j.move(key, dbIndex);
} }
public Long rpushx(String key, String... string) { public Long rpushx(String key, String... string) {
@@ -242,8 +243,8 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
} }
public Long persist(final String key) { public Long persist(final String key) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.persist(key); return j.persist(key);
} }
public Long llen(String key) { public Long llen(String key) {
@@ -326,7 +327,7 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
return j.zadd(key, score, member); return j.zadd(key, score, member);
} }
public Long zadd(String key, Map<Double, String> scoreMembers) { public Long zadd(String key, Map<String, Double> scoreMembers) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.zadd(key, scoreMembers); return j.zadd(key, scoreMembers);
} }
@@ -522,5 +523,18 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
return j.bitcount(key, start, end); return j.bitcount(key, start, end);
} }
public ScanResult<Entry<String, String>> hscan(String key, int cursor) {
Jedis j = getShard(key);
return j.hscan(key, cursor);
}
public ScanResult<String> sscan(String key, int cursor) {
Jedis j = getShard(key);
return j.sscan(key, cursor);
}
public ScanResult<Tuple> zscan(String key, int cursor) {
Jedis j = getShard(key);
return j.zscan(key, cursor);
}
} }

View File

@@ -11,27 +11,27 @@ public class ShardedJedisPipeline extends PipelineBase {
private Queue<Client> clients = new LinkedList<Client>(); private Queue<Client> clients = new LinkedList<Client>();
private static class FutureResult { private static class FutureResult {
private Client client; private Client client;
public FutureResult(Client client) { public FutureResult(Client client) {
this.client = client; this.client = client;
} }
public Object get() { public Object get() {
return client.getOne(); return client.getOne();
} }
} }
public void setShardedJedis(BinaryShardedJedis jedis) { public void setShardedJedis(BinaryShardedJedis jedis) {
this.jedis = jedis; this.jedis = jedis;
} }
public List<Object> getResults() { public List<Object> getResults() {
List<Object> r = new ArrayList<Object>(); List<Object> r = new ArrayList<Object>();
for (FutureResult fr : results) { for (FutureResult fr : results) {
r.add(fr.get()); r.add(fr.get());
} }
return r; return r;
} }
/** /**
@@ -40,30 +40,30 @@ public class ShardedJedisPipeline extends PipelineBase {
* the different Response&lt;?&gt; of the commands you execute. * the different Response&lt;?&gt; of the commands you execute.
*/ */
public void sync() { public void sync() {
for (Client client : clients) { for (Client client : clients) {
generateResponse(client.getOne()); generateResponse(client.getOne());
} }
} }
/** /**
* Syncronize pipeline by reading all responses. This operation closes the * Syncronize pipeline by reading all responses. This operation closes the
* pipeline. Whenever possible try to avoid using this version and use * pipeline. Whenever possible try to avoid using this version and use
* ShardedJedisPipeline.sync() as it won't go through all the responses and generate the * ShardedJedisPipeline.sync() as it won't go through all the responses and
* right response type (usually it is a waste of time). * generate the right response type (usually it is a waste of time).
* *
* @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> formatted = new ArrayList<Object>(); List<Object> formatted = new ArrayList<Object>();
for (Client client : clients) { for (Client client : clients) {
formatted.add(generateResponse(client.getOne()).get()); formatted.add(generateResponse(client.getOne()).get());
} }
return formatted; return formatted;
} }
/** /**
* This method will be removed in Jedis 3.0. Use the methods that return Response's and call * This method will be removed in Jedis 3.0. Use the methods that return
* sync(). * Response's and call sync().
*/ */
@Deprecated @Deprecated
public void execute() { public void execute() {
@@ -71,17 +71,17 @@ public class ShardedJedisPipeline extends PipelineBase {
@Override @Override
protected Client getClient(String key) { protected Client getClient(String key) {
Client client = jedis.getShard(key).getClient(); Client client = jedis.getShard(key).getClient();
clients.add(client); clients.add(client);
results.add(new FutureResult(client)); results.add(new FutureResult(client));
return client; return client;
} }
@Override @Override
protected Client getClient(byte[] key) { protected Client getClient(byte[] key) {
Client client = jedis.getShard(key).getClient(); Client client = jedis.getShard(key).getClient();
clients.add(client); clients.add(client);
results.add(new FutureResult(client)); results.add(new FutureResult(client));
return client; return client;
} }
} }

View File

@@ -3,83 +3,101 @@ package redis.clients.jedis;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.pool.BasePoolableObjectFactory; import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.util.Hashing; import redis.clients.util.Hashing;
import redis.clients.util.Pool; import redis.clients.util.Pool;
public class ShardedJedisPool extends Pool<ShardedJedis> { public class ShardedJedisPool extends Pool<ShardedJedis> {
public ShardedJedisPool(final GenericObjectPool.Config poolConfig, public ShardedJedisPool(final GenericObjectPoolConfig poolConfig,
List<JedisShardInfo> shards) { List<JedisShardInfo> shards) {
this(poolConfig, shards, Hashing.MURMUR_HASH); this(poolConfig, shards, Hashing.MURMUR_HASH);
} }
public ShardedJedisPool(final GenericObjectPool.Config poolConfig, public ShardedJedisPool(final GenericObjectPoolConfig poolConfig,
List<JedisShardInfo> shards, Hashing algo) { List<JedisShardInfo> shards, Hashing algo) {
this(poolConfig, shards, algo, null); this(poolConfig, shards, algo, null);
} }
public ShardedJedisPool(final GenericObjectPool.Config poolConfig, public ShardedJedisPool(final GenericObjectPoolConfig poolConfig,
List<JedisShardInfo> shards, Pattern keyTagPattern) { List<JedisShardInfo> shards, Pattern keyTagPattern) {
this(poolConfig, shards, Hashing.MURMUR_HASH, keyTagPattern); this(poolConfig, shards, Hashing.MURMUR_HASH, keyTagPattern);
} }
public ShardedJedisPool(final GenericObjectPool.Config poolConfig, public ShardedJedisPool(final GenericObjectPoolConfig poolConfig,
List<JedisShardInfo> shards, Hashing algo, Pattern keyTagPattern) { List<JedisShardInfo> shards, Hashing algo, Pattern keyTagPattern) {
super(poolConfig, new ShardedJedisFactory(shards, algo, keyTagPattern)); super(poolConfig, new ShardedJedisFactory(shards, algo, keyTagPattern));
} }
/** /**
* PoolableObjectFactory custom impl. * PoolableObjectFactory custom impl.
*/ */
private static class ShardedJedisFactory extends BasePoolableObjectFactory { private static class ShardedJedisFactory implements
private List<JedisShardInfo> shards; PooledObjectFactory<ShardedJedis> {
private Hashing algo; private List<JedisShardInfo> shards;
private Pattern keyTagPattern; private Hashing algo;
private Pattern keyTagPattern;
public ShardedJedisFactory(List<JedisShardInfo> shards, Hashing algo, public ShardedJedisFactory(List<JedisShardInfo> shards, Hashing algo,
Pattern keyTagPattern) { Pattern keyTagPattern) {
this.shards = shards; this.shards = shards;
this.algo = algo; this.algo = algo;
this.keyTagPattern = keyTagPattern; this.keyTagPattern = keyTagPattern;
} }
public Object makeObject() throws Exception { @Override
ShardedJedis jedis = new ShardedJedis(shards, algo, keyTagPattern); public PooledObject<ShardedJedis> makeObject() throws Exception {
return jedis; ShardedJedis jedis = new ShardedJedis(shards, algo, keyTagPattern);
} return new DefaultPooledObject<ShardedJedis>(jedis);
}
public void destroyObject(final Object obj) throws Exception { @Override
if ((obj != null) && (obj instanceof ShardedJedis)) { public void destroyObject(PooledObject<ShardedJedis> pooledShardedJedis)
ShardedJedis shardedJedis = (ShardedJedis) obj; throws Exception {
for (Jedis jedis : shardedJedis.getAllShards()) { final ShardedJedis shardedJedis = pooledShardedJedis.getObject();
try { for (Jedis jedis : shardedJedis.getAllShards()) {
try { try {
jedis.quit(); try {
} catch (Exception e) { jedis.quit();
} catch (Exception e) {
} }
jedis.disconnect(); jedis.disconnect();
} catch (Exception e) { } catch (Exception e) {
} }
} }
} }
}
public boolean validateObject(final Object obj) { @Override
try { public boolean validateObject(
ShardedJedis jedis = (ShardedJedis) obj; PooledObject<ShardedJedis> pooledShardedJedis) {
for (Jedis shard : jedis.getAllShards()) { try {
if (!shard.ping().equals("PONG")) { ShardedJedis jedis = pooledShardedJedis.getObject();
return false; for (Jedis shard : jedis.getAllShards()) {
} if (!shard.ping().equals("PONG")) {
} return false;
return true; }
} catch (Exception ex) { }
return false; return true;
} } catch (Exception ex) {
} return false;
}
}
@Override
public void activateObject(PooledObject<ShardedJedis> p)
throws Exception {
}
@Override
public void passivateObject(PooledObject<ShardedJedis> p)
throws Exception {
}
} }
} }

View File

@@ -36,7 +36,7 @@ public class SortingParams {
* @return the SortingParams Object * @return the SortingParams Object
*/ */
public SortingParams by(final String pattern) { public SortingParams by(final String pattern) {
return by(SafeEncoder.encode(pattern)); return by(SafeEncoder.encode(pattern));
} }
/** /**
@@ -53,9 +53,9 @@ public class SortingParams {
* @return the SortingParams Object * @return the SortingParams Object
*/ */
public SortingParams by(final byte[] pattern) { public SortingParams by(final byte[] pattern) {
params.add(BY.raw); params.add(BY.raw);
params.add(pattern); params.add(pattern);
return this; return this;
} }
/** /**
@@ -67,13 +67,13 @@ public class SortingParams {
* @return the SortingParams Object * @return the SortingParams Object
*/ */
public SortingParams nosort() { public SortingParams nosort() {
params.add(BY.raw); params.add(BY.raw);
params.add(NOSORT.raw); params.add(NOSORT.raw);
return this; return this;
} }
public Collection<byte[]> getParams() { public Collection<byte[]> getParams() {
return Collections.unmodifiableCollection(params); return Collections.unmodifiableCollection(params);
} }
/** /**
@@ -82,8 +82,8 @@ public class SortingParams {
* @return the sortingParams Object * @return the sortingParams Object
*/ */
public SortingParams desc() { public SortingParams desc() {
params.add(DESC.raw); params.add(DESC.raw);
return this; return this;
} }
/** /**
@@ -92,8 +92,8 @@ public class SortingParams {
* @return the SortingParams Object * @return the SortingParams Object
*/ */
public SortingParams asc() { public SortingParams asc() {
params.add(ASC.raw); params.add(ASC.raw);
return this; return this;
} }
/** /**
@@ -105,10 +105,10 @@ public class SortingParams {
* @return the SortingParams Object * @return the SortingParams Object
*/ */
public SortingParams limit(final int start, final int count) { public SortingParams limit(final int start, final int count) {
params.add(LIMIT.raw); params.add(LIMIT.raw);
params.add(Protocol.toByteArray(start)); params.add(Protocol.toByteArray(start));
params.add(Protocol.toByteArray(count)); params.add(Protocol.toByteArray(count));
return this; return this;
} }
/** /**
@@ -118,8 +118,8 @@ public class SortingParams {
* @return the SortingParams Object * @return the SortingParams Object
*/ */
public SortingParams alpha() { public SortingParams alpha() {
params.add(ALPHA.raw); params.add(ALPHA.raw);
return this; return this;
} }
/** /**
@@ -138,11 +138,11 @@ public class SortingParams {
* @return the SortingParams Object * @return the SortingParams Object
*/ */
public SortingParams get(String... patterns) { public SortingParams get(String... patterns) {
for (final String pattern : patterns) { for (final String pattern : patterns) {
params.add(GET.raw); params.add(GET.raw);
params.add(SafeEncoder.encode(pattern)); params.add(SafeEncoder.encode(pattern));
} }
return this; return this;
} }
/** /**
@@ -161,10 +161,10 @@ public class SortingParams {
* @return the SortingParams Object * @return the SortingParams Object
*/ */
public SortingParams get(byte[]... patterns) { public SortingParams get(byte[]... patterns) {
for (final byte[] pattern : patterns) { for (final byte[] pattern : patterns) {
params.add(GET.raw); params.add(GET.raw);
params.add(pattern); params.add(pattern);
} }
return this; return this;
} }
} }

View File

@@ -6,70 +6,71 @@ import java.util.List;
import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisDataException;
/** /**
* Transaction is nearly identical to Pipeline, only differences are the multi/discard behaviors * Transaction is nearly identical to Pipeline, only differences are the
* multi/discard behaviors
*/ */
public class Transaction extends MultiKeyPipelineBase { public class Transaction extends MultiKeyPipelineBase {
protected boolean inTransaction = true; protected boolean inTransaction = true;
protected Transaction(){ protected Transaction() {
// client will be set later in transaction block // client will be set later in transaction block
} }
public Transaction(final Client client) { public Transaction(final Client client) {
this.client = client; this.client = client;
} }
@Override @Override
protected Client getClient(String key) { protected Client getClient(String key) {
return client; return client;
} }
@Override @Override
protected Client getClient(byte[] key) { protected Client getClient(byte[] key) {
return client; return client;
} }
public List<Object> exec() { public List<Object> exec() {
client.exec(); client.exec();
client.getAll(1); // Discard all but the last reply 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) {
return null; return null;
} }
List<Object> formatted = new ArrayList<Object>(); List<Object> formatted = new ArrayList<Object>();
for (Object o : unformatted) { for (Object o : unformatted) {
try { try {
formatted.add(generateResponse(o).get()); formatted.add(generateResponse(o).get());
} catch (JedisDataException e) { } catch (JedisDataException e) {
formatted.add(e); formatted.add(e);
} }
} }
return formatted; return formatted;
} }
public List<Response<?>> execGetResponse() { public List<Response<?>> execGetResponse() {
client.exec(); client.exec();
client.getAll(1); // Discard all but the last reply 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) {
return null; return null;
} }
List<Response<?>> response = new ArrayList<Response<?>>(); List<Response<?>> response = new ArrayList<Response<?>>();
for (Object o : unformatted) { for (Object o : unformatted) {
response.add(generateResponse(o)); response.add(generateResponse(o));
} }
return response; return response;
} }
public String discard() { public String discard() {
client.discard(); client.discard();
client.getAll(1); // Discard all but the last reply client.getAll(1); // Discard all but the last reply
inTransaction = false; inTransaction = false;
clean(); clean();
return client.getStatusCodeReply(); return client.getStatusCodeReply();
} }
} }

View File

@@ -13,6 +13,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; this.client = client;
} }
} }

View File

@@ -9,72 +9,72 @@ public class Tuple implements Comparable<Tuple> {
private Double score; private Double score;
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result; result = prime * result;
if (null != element) { if (null != element) {
for (final byte b : element) { for (final byte b : element) {
result = prime * result + b; result = prime * result + b;
} }
} }
long temp; long temp;
temp = Double.doubleToLongBits(score); temp = Double.doubleToLongBits(score);
result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + (int) (temp ^ (temp >>> 32));
return result; return result;
} }
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj)
return true; return true;
if (obj == null) if (obj == null)
return false; return false;
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
Tuple other = (Tuple) obj; Tuple other = (Tuple) obj;
if (element == null) { if (element == null) {
if (other.element != null) if (other.element != null)
return false; return false;
} else if (!Arrays.equals(element, other.element)) } else if (!Arrays.equals(element, other.element))
return false; return false;
return true; return true;
} }
public int compareTo(Tuple other) { public int compareTo(Tuple other) {
if (Arrays.equals(this.element, other.element)) if (Arrays.equals(this.element, other.element))
return 0; return 0;
else else
return this.score < other.getScore() ? -1 : 1; return this.score < other.getScore() ? -1 : 1;
} }
public Tuple(String element, Double score) { public Tuple(String element, Double score) {
super(); super();
this.element = SafeEncoder.encode(element); this.element = SafeEncoder.encode(element);
this.score = score; this.score = score;
} }
public Tuple(byte[] element, Double score) { public Tuple(byte[] element, Double score) {
super(); super();
this.element = element; this.element = element;
this.score = score; this.score = score;
} }
public String getElement() { public String getElement() {
if (null != element) { if (null != element) {
return SafeEncoder.encode(element); return SafeEncoder.encode(element);
} else { } else {
return null; return null;
} }
} }
public byte[] getBinaryElement() { public byte[] getBinaryElement() {
return element; return element;
} }
public double getScore() { public double getScore() {
return score; return score;
} }
public String toString() { public String toString() {
return '[' + Arrays.toString(element) + ',' + score + ']'; return '[' + Arrays.toString(element) + ',' + score + ']';
} }
} }

View File

@@ -12,33 +12,33 @@ import redis.clients.util.SafeEncoder;
public class ZParams { public class ZParams {
public enum Aggregate { public enum Aggregate {
SUM, MIN, MAX; SUM, MIN, MAX;
public final byte[] raw; public final byte[] raw;
Aggregate() { Aggregate() {
raw = SafeEncoder.encode(name()); raw = SafeEncoder.encode(name());
} }
} }
private List<byte[]> params = new ArrayList<byte[]>(); private List<byte[]> params = new ArrayList<byte[]>();
public ZParams weights(final int... weights) { public ZParams weights(final int... weights) {
params.add(WEIGHTS.raw); params.add(WEIGHTS.raw);
for (final int weight : weights) { for (final int weight : weights) {
params.add(Protocol.toByteArray(weight)); params.add(Protocol.toByteArray(weight));
} }
return this; return this;
} }
public Collection<byte[]> getParams() { public Collection<byte[]> getParams() {
return Collections.unmodifiableCollection(params); return Collections.unmodifiableCollection(params);
} }
public ZParams aggregate(final Aggregate aggregate) { public ZParams aggregate(final Aggregate aggregate) {
params.add(AGGREGATE.raw); params.add(AGGREGATE.raw);
params.add(aggregate.raw); params.add(aggregate.raw);
return this; return this;
} }
} }

View File

@@ -0,0 +1,23 @@
package redis.clients.jedis.exceptions;
import redis.clients.jedis.HostAndPort;
public class JedisAskDataException extends JedisRedirectionException {
private static final long serialVersionUID = 3878126572474819403L;
public JedisAskDataException(Throwable cause, HostAndPort targetHost,
int slot) {
super(cause, targetHost, slot);
}
public JedisAskDataException(String message, Throwable cause,
HostAndPort targetHost, int slot) {
super(message, cause, targetHost, slot);
}
public JedisAskDataException(String message, HostAndPort targetHost,
int slot) {
super(message, targetHost, slot);
}
}

View File

@@ -0,0 +1,17 @@
package redis.clients.jedis.exceptions;
public class JedisClusterException extends JedisDataException {
private static final long serialVersionUID = 3878126572474819403L;
public JedisClusterException(Throwable cause) {
super(cause);
}
public JedisClusterException(String message, Throwable cause) {
super(message, cause);
}
public JedisClusterException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,17 @@
package redis.clients.jedis.exceptions;
public class JedisClusterMaxRedirectionsException extends JedisDataException {
private static final long serialVersionUID = 3878126572474819403L;
public JedisClusterMaxRedirectionsException(Throwable cause) {
super(cause);
}
public JedisClusterMaxRedirectionsException(String message, Throwable cause) {
super(message, cause);
}
public JedisClusterMaxRedirectionsException(String message) {
super(message);
}
}

View File

@@ -4,14 +4,14 @@ public class JedisConnectionException extends JedisException {
private static final long serialVersionUID = 3878126572474819403L; private static final long serialVersionUID = 3878126572474819403L;
public JedisConnectionException(String message) { public JedisConnectionException(String message) {
super(message); super(message);
} }
public JedisConnectionException(Throwable cause) { public JedisConnectionException(Throwable cause) {
super(cause); super(cause);
} }
public JedisConnectionException(String message, Throwable cause) { public JedisConnectionException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
} }

View File

@@ -4,14 +4,14 @@ public class JedisDataException extends JedisException {
private static final long serialVersionUID = 3878126572474819403L; private static final long serialVersionUID = 3878126572474819403L;
public JedisDataException(String message) { public JedisDataException(String message) {
super(message); super(message);
} }
public JedisDataException(Throwable cause) { public JedisDataException(Throwable cause) {
super(cause); super(cause);
} }
public JedisDataException(String message, Throwable cause) { public JedisDataException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
} }

View File

@@ -1,18 +1,17 @@
package redis.clients.jedis.exceptions; package redis.clients.jedis.exceptions;
public class JedisException extends RuntimeException { public class JedisException extends RuntimeException {
private static final long serialVersionUID = -2946266495682282677L; private static final long serialVersionUID = -2946266495682282677L;
public JedisException(String message) { public JedisException(String message) {
super(message); super(message);
} }
public JedisException(Throwable e) { public JedisException(Throwable e) {
super(e); super(e);
} }
public JedisException(String message, Throwable cause) { public JedisException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
} }

View File

@@ -0,0 +1,22 @@
package redis.clients.jedis.exceptions;
import redis.clients.jedis.HostAndPort;
public class JedisMovedDataException extends JedisRedirectionException {
private static final long serialVersionUID = 3878126572474819403L;
public JedisMovedDataException(String message, HostAndPort targetNode,
int slot) {
super(message, targetNode, slot);
}
public JedisMovedDataException(Throwable cause, HostAndPort targetNode,
int slot) {
super(cause, targetNode, slot);
}
public JedisMovedDataException(String message, Throwable cause,
HostAndPort targetNode, int slot) {
super(message, cause, targetNode, slot);
}
}

View File

@@ -0,0 +1,39 @@
package redis.clients.jedis.exceptions;
import redis.clients.jedis.HostAndPort;
public class JedisRedirectionException extends JedisDataException {
private static final long serialVersionUID = 3878126572474819403L;
private HostAndPort targetNode;
private int slot;
public JedisRedirectionException(String message, HostAndPort targetNode,
int slot) {
super(message);
this.targetNode = targetNode;
this.slot = slot;
}
public JedisRedirectionException(Throwable cause, HostAndPort targetNode,
int slot) {
super(cause);
this.targetNode = targetNode;
this.slot = slot;
}
public JedisRedirectionException(String message, Throwable cause,
HostAndPort targetNode, int slot) {
super(message, cause);
this.targetNode = targetNode;
this.slot = slot;
}
public HostAndPort getTargetNode() {
return targetNode;
}
public int getSlot() {
return slot;
}
}

View File

@@ -8,28 +8,28 @@ public interface Hashing {
public ThreadLocal<MessageDigest> md5Holder = new ThreadLocal<MessageDigest>(); public ThreadLocal<MessageDigest> md5Holder = new ThreadLocal<MessageDigest>();
public static final Hashing MD5 = new Hashing() { public static final Hashing MD5 = new Hashing() {
public long hash(String key) { public long hash(String key) {
return hash(SafeEncoder.encode(key)); return hash(SafeEncoder.encode(key));
} }
public long hash(byte[] key) { public long hash(byte[] key) {
try { try {
if (md5Holder.get() == null) { if (md5Holder.get() == null) {
md5Holder.set(MessageDigest.getInstance("MD5")); md5Holder.set(MessageDigest.getInstance("MD5"));
} }
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("++++ no md5 algorythm found"); throw new IllegalStateException("++++ no md5 algorythm found");
} }
MessageDigest md5 = md5Holder.get(); MessageDigest md5 = md5Holder.get();
md5.reset(); md5.reset();
md5.update(key); md5.update(key);
byte[] bKey = md5.digest(); byte[] bKey = md5.digest();
long res = ((long) (bKey[3] & 0xFF) << 24) long res = ((long) (bKey[3] & 0xFF) << 24)
| ((long) (bKey[2] & 0xFF) << 16) | ((long) (bKey[2] & 0xFF) << 16)
| ((long) (bKey[1] & 0xFF) << 8) | (long) (bKey[0] & 0xFF); | ((long) (bKey[1] & 0xFF) << 8) | (long) (bKey[0] & 0xFF);
return res; return res;
} }
}; };
public long hash(String key); public long hash(String key);

View File

@@ -10,127 +10,127 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
public class JedisByteHashMap implements Map<byte[], byte[]>, Cloneable, public class JedisByteHashMap implements Map<byte[], byte[]>, Cloneable,
Serializable { Serializable {
private static final long serialVersionUID = -6971431362627219416L; private static final long serialVersionUID = -6971431362627219416L;
private Map<ByteArrayWrapper, byte[]> internalMap = new HashMap<ByteArrayWrapper, byte[]>(); private Map<ByteArrayWrapper, byte[]> internalMap = new HashMap<ByteArrayWrapper, byte[]>();
public void clear() { public void clear() {
internalMap.clear(); internalMap.clear();
} }
public boolean containsKey(Object key) { public boolean containsKey(Object key) {
if (key instanceof byte[]) if (key instanceof byte[])
return internalMap.containsKey(new ByteArrayWrapper((byte[]) key)); return internalMap.containsKey(new ByteArrayWrapper((byte[]) key));
return internalMap.containsKey(key); return internalMap.containsKey(key);
} }
public boolean containsValue(Object value) { public boolean containsValue(Object value) {
return internalMap.containsValue(value); return internalMap.containsValue(value);
} }
public Set<java.util.Map.Entry<byte[], byte[]>> entrySet() { public Set<java.util.Map.Entry<byte[], byte[]>> entrySet() {
Iterator<java.util.Map.Entry<ByteArrayWrapper, byte[]>> iterator = internalMap Iterator<java.util.Map.Entry<ByteArrayWrapper, byte[]>> iterator = internalMap
.entrySet().iterator(); .entrySet().iterator();
HashSet<Entry<byte[], byte[]>> hashSet = new HashSet<java.util.Map.Entry<byte[], byte[]>>(); HashSet<Entry<byte[], byte[]>> hashSet = new HashSet<java.util.Map.Entry<byte[], byte[]>>();
while (iterator.hasNext()) { while (iterator.hasNext()) {
Entry<ByteArrayWrapper, byte[]> entry = iterator.next(); Entry<ByteArrayWrapper, byte[]> entry = iterator.next();
hashSet.add(new JedisByteEntry(entry.getKey().data, entry hashSet.add(new JedisByteEntry(entry.getKey().data, entry
.getValue())); .getValue()));
} }
return hashSet; return hashSet;
} }
public byte[] get(Object key) { public byte[] get(Object key) {
if (key instanceof byte[]) if (key instanceof byte[])
return internalMap.get(new ByteArrayWrapper((byte[]) key)); return internalMap.get(new ByteArrayWrapper((byte[]) key));
return internalMap.get(key); return internalMap.get(key);
} }
public boolean isEmpty() { public boolean isEmpty() {
return internalMap.isEmpty(); return internalMap.isEmpty();
} }
public Set<byte[]> keySet() { public Set<byte[]> keySet() {
Set<byte[]> keySet = new HashSet<byte[]>(); Set<byte[]> keySet = new HashSet<byte[]>();
Iterator<ByteArrayWrapper> iterator = internalMap.keySet().iterator(); Iterator<ByteArrayWrapper> iterator = internalMap.keySet().iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
keySet.add(iterator.next().data); keySet.add(iterator.next().data);
} }
return keySet; return keySet;
} }
public byte[] put(byte[] key, byte[] value) { public byte[] put(byte[] key, byte[] value) {
return internalMap.put(new ByteArrayWrapper(key), value); return internalMap.put(new ByteArrayWrapper(key), value);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void putAll(Map<? extends byte[], ? extends byte[]> m) { public void putAll(Map<? extends byte[], ? extends byte[]> m) {
Iterator<?> iterator = m.entrySet().iterator(); Iterator<?> iterator = m.entrySet().iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
Entry<? extends byte[], ? extends byte[]> next = (Entry<? extends byte[], ? extends byte[]>) iterator Entry<? extends byte[], ? extends byte[]> next = (Entry<? extends byte[], ? extends byte[]>) iterator
.next(); .next();
internalMap.put(new ByteArrayWrapper(next.getKey()), next internalMap.put(new ByteArrayWrapper(next.getKey()),
.getValue()); next.getValue());
} }
} }
public byte[] remove(Object key) { public byte[] remove(Object key) {
if (key instanceof byte[]) if (key instanceof byte[])
return internalMap.remove(new ByteArrayWrapper((byte[]) key)); return internalMap.remove(new ByteArrayWrapper((byte[]) key));
return internalMap.remove(key); return internalMap.remove(key);
} }
public int size() { public int size() {
return internalMap.size(); return internalMap.size();
} }
public Collection<byte[]> values() { public Collection<byte[]> values() {
return internalMap.values(); return internalMap.values();
} }
private static final class ByteArrayWrapper { private static final class ByteArrayWrapper {
private final byte[] data; private final byte[] data;
public ByteArrayWrapper(byte[] data) { public ByteArrayWrapper(byte[] data) {
if (data == null) { if (data == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
this.data = data; this.data = data;
} }
public boolean equals(Object other) { public boolean equals(Object other) {
if (!(other instanceof ByteArrayWrapper)) { if (!(other instanceof ByteArrayWrapper)) {
return false; return false;
} }
return Arrays.equals(data, ((ByteArrayWrapper) other).data); return Arrays.equals(data, ((ByteArrayWrapper) other).data);
} }
public int hashCode() { public int hashCode() {
return Arrays.hashCode(data); return Arrays.hashCode(data);
} }
} }
private static final class JedisByteEntry implements Entry<byte[], byte[]> { private static final class JedisByteEntry implements Entry<byte[], byte[]> {
private byte[] value; private byte[] value;
private byte[] key; private byte[] key;
public JedisByteEntry(byte[] key, byte[] value) { public JedisByteEntry(byte[] key, byte[] value) {
this.key = key; this.key = key;
this.value = value; this.value = value;
} }
public byte[] getKey() { public byte[] getKey() {
return this.key; return this.key;
} }
public byte[] getValue() { public byte[] getValue() {
return this.value; return this.value;
} }
public byte[] setValue(byte[] value) { public byte[] setValue(byte[] value) {
this.value = value; this.value = value;
return value; return value;
} }
} }
} }

View File

@@ -0,0 +1,23 @@
package redis.clients.util;
public class JedisClusterCRC16 {
public final static int polynomial = 0x1021; // Represents x^16+x^12+x^5+1
static int crc;
public static int getSlot(String key) {
crc = 0x0000;
for (byte b : key.getBytes()) {
for (int i = 0; i < 8; i++) {
boolean bit = ((b >> (7 - i) & 1) == 1);
boolean c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
// If coefficient of bit and remainder polynomial = 1 xor crc
// with polynomial
if (c15 ^ bit)
crc ^= polynomial;
}
}
return crc &= 0xffff % 16384;
}
}

View File

@@ -40,7 +40,7 @@ public class MurmurHash implements Hashing {
* @return The 32 bit hash of the bytes in question. * @return The 32 bit hash of the bytes in question.
*/ */
public static int hash(byte[] data, int seed) { public static int hash(byte[] data, int seed) {
return hash(ByteBuffer.wrap(data), seed); return hash(ByteBuffer.wrap(data), seed);
} }
/** /**
@@ -57,7 +57,7 @@ public class MurmurHash implements Hashing {
* @return The 32-bit hash of the data in question. * @return The 32-bit hash of the data in question.
*/ */
public static int hash(byte[] data, int offset, int length, int seed) { public static int hash(byte[] data, int offset, int length, int seed) {
return hash(ByteBuffer.wrap(data, offset, length), seed); return hash(ByteBuffer.wrap(data, offset, length), seed);
} }
/** /**
@@ -70,97 +70,97 @@ public class MurmurHash implements Hashing {
* @return The 32 bit murmur hash of the bytes in the buffer. * @return The 32 bit murmur hash of the bytes in the buffer.
*/ */
public static int hash(ByteBuffer buf, int seed) { public static int hash(ByteBuffer buf, int seed) {
// save byte order for later restoration // save byte order for later restoration
ByteOrder byteOrder = buf.order(); ByteOrder byteOrder = buf.order();
buf.order(ByteOrder.LITTLE_ENDIAN); buf.order(ByteOrder.LITTLE_ENDIAN);
int m = 0x5bd1e995; int m = 0x5bd1e995;
int r = 24; int r = 24;
int h = seed ^ buf.remaining(); int h = seed ^ buf.remaining();
int k; int k;
while (buf.remaining() >= 4) { while (buf.remaining() >= 4) {
k = buf.getInt(); k = buf.getInt();
k *= m; k *= m;
k ^= k >>> r; k ^= k >>> r;
k *= m; k *= m;
h *= m; h *= m;
h ^= k; h ^= k;
} }
if (buf.remaining() > 0) { if (buf.remaining() > 0) {
ByteBuffer finish = ByteBuffer.allocate(4).order( ByteBuffer finish = ByteBuffer.allocate(4).order(
ByteOrder.LITTLE_ENDIAN); ByteOrder.LITTLE_ENDIAN);
// for big-endian version, use this first: // for big-endian version, use this first:
// finish.position(4-buf.remaining()); // finish.position(4-buf.remaining());
finish.put(buf).rewind(); finish.put(buf).rewind();
h ^= finish.getInt(); h ^= finish.getInt();
h *= m; h *= m;
} }
h ^= h >>> 13; h ^= h >>> 13;
h *= m; h *= m;
h ^= h >>> 15; h ^= h >>> 15;
buf.order(byteOrder); buf.order(byteOrder);
return h; return h;
} }
public static long hash64A(byte[] data, int seed) { public static long hash64A(byte[] data, int seed) {
return hash64A(ByteBuffer.wrap(data), seed); return hash64A(ByteBuffer.wrap(data), seed);
} }
public static long hash64A(byte[] data, int offset, int length, int seed) { public static long hash64A(byte[] data, int offset, int length, int seed) {
return hash64A(ByteBuffer.wrap(data, offset, length), seed); return hash64A(ByteBuffer.wrap(data, offset, length), seed);
} }
public static long hash64A(ByteBuffer buf, int seed) { public static long hash64A(ByteBuffer buf, int seed) {
ByteOrder byteOrder = buf.order(); ByteOrder byteOrder = buf.order();
buf.order(ByteOrder.LITTLE_ENDIAN); buf.order(ByteOrder.LITTLE_ENDIAN);
long m = 0xc6a4a7935bd1e995L; long m = 0xc6a4a7935bd1e995L;
int r = 47; int r = 47;
long h = seed ^ (buf.remaining() * m); long h = seed ^ (buf.remaining() * m);
long k; long k;
while (buf.remaining() >= 8) { while (buf.remaining() >= 8) {
k = buf.getLong(); k = buf.getLong();
k *= m; k *= m;
k ^= k >>> r; k ^= k >>> r;
k *= m; k *= m;
h ^= k; h ^= k;
h *= m; h *= m;
} }
if (buf.remaining() > 0) { if (buf.remaining() > 0) {
ByteBuffer finish = ByteBuffer.allocate(8).order( ByteBuffer finish = ByteBuffer.allocate(8).order(
ByteOrder.LITTLE_ENDIAN); ByteOrder.LITTLE_ENDIAN);
// for big-endian version, do this first: // for big-endian version, do this first:
// finish.position(8-buf.remaining()); // finish.position(8-buf.remaining());
finish.put(buf).rewind(); finish.put(buf).rewind();
h ^= finish.getLong(); h ^= finish.getLong();
h *= m; h *= m;
} }
h ^= h >>> r; h ^= h >>> r;
h *= m; h *= m;
h ^= h >>> r; h ^= h >>> r;
buf.order(byteOrder); buf.order(byteOrder);
return h; return h;
} }
public long hash(byte[] key) { public long hash(byte[] key) {
return hash64A(key, 0x1234ABCD); return hash64A(key, 0x1234ABCD);
} }
public long hash(String key) { public long hash(String key) {
return hash(SafeEncoder.encode(key)); return hash(SafeEncoder.encode(key));
} }
} }

View File

@@ -1,82 +1,84 @@
package redis.clients.util; package redis.clients.util;
import org.apache.commons.pool.PoolableObjectFactory; import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisException; import redis.clients.jedis.exceptions.JedisException;
public abstract class Pool<T> { public abstract class Pool<T> {
protected GenericObjectPool internalPool; protected GenericObjectPool<T> internalPool;
/** /**
* Using this constructor means you have to set * Using this constructor means you have to set and initialize the
* and initialize the internalPool yourself. * internalPool yourself.
*/ */
public Pool() {} public Pool() {
public Pool(final GenericObjectPool.Config poolConfig,
PoolableObjectFactory factory) {
initPool(poolConfig, factory);
} }
public void initPool(final GenericObjectPool.Config poolConfig, PoolableObjectFactory factory) { public Pool(final GenericObjectPoolConfig poolConfig,
PooledObjectFactory<T> factory) {
if (this.internalPool != null) { initPool(poolConfig, factory);
try {
closeInternalPool();
} catch (Exception e) {
}
}
this.internalPool = new GenericObjectPool(factory, poolConfig);
} }
@SuppressWarnings("unchecked") public void initPool(final GenericObjectPoolConfig poolConfig,
PooledObjectFactory<T> factory) {
if (this.internalPool != null) {
try {
closeInternalPool();
} catch (Exception e) {
}
}
this.internalPool = new GenericObjectPool<T>(factory, poolConfig);
}
public T getResource() { public T getResource() {
try { try {
return (T) internalPool.borrowObject(); return internalPool.borrowObject();
} catch (Exception e) { } catch (Exception e) {
throw new JedisConnectionException( throw new JedisConnectionException(
"Could not get a resource from the pool", e); "Could not get a resource from the pool", e);
} }
} }
public void returnResourceObject(final Object resource) { public void returnResourceObject(final T resource) {
try { try {
internalPool.returnObject(resource); internalPool.returnObject(resource);
} catch (Exception e) { } catch (Exception e) {
throw new JedisException( throw new JedisException(
"Could not return the resource to the pool", e); "Could not return the resource to the pool", e);
} }
} }
public void returnBrokenResource(final T resource) { public void returnBrokenResource(final T resource) {
returnBrokenResourceObject(resource); returnBrokenResourceObject(resource);
} }
public void returnResource(final T resource) { public void returnResource(final T resource) {
returnResourceObject(resource); returnResourceObject(resource);
} }
public void destroy() { public void destroy() {
closeInternalPool(); closeInternalPool();
} }
protected void returnBrokenResourceObject(final Object resource) { protected void returnBrokenResourceObject(final T resource) {
try { try {
internalPool.invalidateObject(resource); internalPool.invalidateObject(resource);
} catch (Exception e) { } catch (Exception e) {
throw new JedisException( throw new JedisException(
"Could not return the resource to the pool", e); "Could not return the resource to the pool", e);
} }
} }
protected void closeInternalPool() { protected void closeInternalPool() {
try { try {
internalPool.close(); internalPool.close();
} catch (Exception e) { } catch (Exception e) {
throw new JedisException("Could not destroy the pool", e); throw new JedisException("Could not destroy the pool", e);
} }
} }
} }

View File

@@ -29,84 +29,84 @@ public class RedisInputStream extends FilterInputStream {
protected int count, limit; protected int count, limit;
public RedisInputStream(InputStream in, int size) { public RedisInputStream(InputStream in, int size) {
super(in); super(in);
if (size <= 0) { if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0"); throw new IllegalArgumentException("Buffer size <= 0");
} }
buf = new byte[size]; buf = new byte[size];
} }
public RedisInputStream(InputStream in) { public RedisInputStream(InputStream in) {
this(in, 8192); this(in, 8192);
} }
public byte readByte() throws IOException { public byte readByte() throws IOException {
if (count == limit) { if (count == limit) {
fill(); fill();
} }
return buf[count++]; return buf[count++];
} }
public String readLine() { public String readLine() {
int b; int b;
byte c; byte c;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
try { try {
while (true) { while (true) {
if (count == limit) { if (count == limit) {
fill(); fill();
} }
if (limit == -1) if (limit == -1)
break; break;
b = buf[count++]; b = buf[count++];
if (b == '\r') { if (b == '\r') {
if (count == limit) { if (count == limit) {
fill(); fill();
} }
if (limit == -1) { if (limit == -1) {
sb.append((char) b); sb.append((char) b);
break; break;
} }
c = buf[count++]; c = buf[count++];
if (c == '\n') { if (c == '\n') {
break; break;
} }
sb.append((char) b); sb.append((char) b);
sb.append((char) c); sb.append((char) c);
} else { } else {
sb.append((char) b); sb.append((char) b);
} }
} }
} catch (IOException e) { } catch (IOException e) {
throw new JedisConnectionException(e); throw new JedisConnectionException(e);
} }
String reply = sb.toString(); String reply = sb.toString();
if (reply.length() == 0) { if (reply.length() == 0) {
throw new JedisConnectionException( throw new JedisConnectionException(
"It seems like server has closed the connection."); "It seems like server has closed the connection.");
} }
return reply; return reply;
} }
public int read(byte[] b, int off, int len) throws IOException { public int read(byte[] b, int off, int len) throws IOException {
if (count == limit) { if (count == limit) {
fill(); fill();
if (limit == -1) if (limit == -1)
return -1; return -1;
} }
final int length = Math.min(limit - count, len); final int length = Math.min(limit - count, len);
System.arraycopy(buf, count, b, off, length); System.arraycopy(buf, count, b, off, length);
count += length; count += length;
return length; return length;
} }
private void fill() throws IOException { private void fill() throws IOException {
limit = in.read(buf); limit = in.read(buf);
count = 0; count = 0;
} }
} }

View File

@@ -1,11 +1,13 @@
package redis.clients.util; package redis.clients.util;
import java.io.*; import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/** /**
* The class implements a buffered output stream without synchronization * The class implements a buffered output stream without synchronization There
* There are also special operations like in-place string encoding. * are also special operations like in-place string encoding. This stream fully
* This stream fully ignore mark/reset and should not be used outside Jedis * ignore mark/reset and should not be used outside Jedis
*/ */
public final class RedisOutputStream extends FilterOutputStream { public final class RedisOutputStream extends FilterOutputStream {
protected final byte buf[]; protected final byte buf[];
@@ -13,218 +15,212 @@ public final class RedisOutputStream extends FilterOutputStream {
protected int count; protected int count;
public RedisOutputStream(final OutputStream out) { public RedisOutputStream(final OutputStream out) {
this(out, 8192); this(out, 8192);
} }
public RedisOutputStream(final OutputStream out, final int size) { public RedisOutputStream(final OutputStream out, final int size) {
super(out); super(out);
if (size <= 0) { if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0"); throw new IllegalArgumentException("Buffer size <= 0");
} }
buf = new byte[size]; buf = new byte[size];
} }
private void flushBuffer() throws IOException { private void flushBuffer() throws IOException {
if (count > 0) { if (count > 0) {
out.write(buf, 0, count); out.write(buf, 0, count);
count = 0; count = 0;
} }
} }
public void write(final byte b) throws IOException { public void write(final byte b) throws IOException {
buf[count++] = b; buf[count++] = b;
if (count == buf.length) { if (count == buf.length) {
flushBuffer(); flushBuffer();
} }
} }
public void write(final byte[] b) throws IOException { public void write(final byte[] b) throws IOException {
write(b, 0, b.length); write(b, 0, b.length);
} }
public void write(final byte b[], final int off, final int len) throws IOException { public void write(final byte b[], final int off, final int len)
if (len >= buf.length) { throws IOException {
flushBuffer(); if (len >= buf.length) {
out.write(b, off, len); flushBuffer();
} else { out.write(b, off, len);
if (len >= buf.length - count) { } else {
flushBuffer(); if (len >= buf.length - count) {
} flushBuffer();
}
System.arraycopy(b, off, buf, count, len); System.arraycopy(b, off, buf, count, len);
count += len; count += len;
} }
} }
public void writeAsciiCrLf(final String in) throws IOException { public void writeAsciiCrLf(final String in) throws IOException {
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); buf[count++] = (byte) in.charAt(i);
if (count == buf.length) { if (count == buf.length) {
flushBuffer(); flushBuffer();
} }
} }
writeCrLf(); writeCrLf();
} }
public static boolean isSurrogate(final char ch) { public static boolean isSurrogate(final char ch) {
return ch >= Character.MIN_SURROGATE && ch <= Character.MAX_SURROGATE; return ch >= Character.MIN_SURROGATE && ch <= Character.MAX_SURROGATE;
} }
public static int utf8Length (final String str) { public static int utf8Length(final String str) {
int strLen = str.length(), utfLen = 0; int strLen = str.length(), utfLen = 0;
for(int i = 0; i != strLen; ++i) { for (int i = 0; i != strLen; ++i) {
char c = str.charAt(i); char c = str.charAt(i);
if (c < 0x80) { if (c < 0x80) {
utfLen++; utfLen++;
} else if (c < 0x800) { } else if (c < 0x800) {
utfLen += 2; utfLen += 2;
} else if (isSurrogate(c)) { } else if (isSurrogate(c)) {
i++; i++;
utfLen += 4; utfLen += 4;
} else { } else {
utfLen += 3; utfLen += 3;
} }
} }
return utfLen; return utfLen;
} }
public void writeCrLf() throws IOException { public void writeCrLf() throws IOException {
if (2 >= buf.length - count) { if (2 >= buf.length - count) {
flushBuffer(); flushBuffer();
} }
buf[count++] = '\r'; buf[count++] = '\r';
buf[count++] = '\n'; buf[count++] = '\n';
} }
public void writeUtf8CrLf(final String str) throws IOException { public void writeUtf8CrLf(final String str) throws IOException {
int strLen = str.length(); int strLen = str.length();
int i; int i;
for (i = 0; i < strLen; i++) { for (i = 0; i < strLen; i++) {
char c = str.charAt(i); char c = str.charAt(i);
if (!(c < 0x80)) break; if (!(c < 0x80))
buf[count++] = (byte) c; break;
if(count == buf.length) { buf[count++] = (byte) c;
flushBuffer(); if (count == buf.length) {
} flushBuffer();
} }
}
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; buf[count++] = (byte) c;
if(count == buf.length) { if (count == buf.length) {
flushBuffer(); flushBuffer();
} }
} else if (c < 0x800) { } else if (c < 0x800) {
if(2 >= buf.length - count) { if (2 >= buf.length - count) {
flushBuffer(); flushBuffer();
} }
buf[count++] = (byte)(0xc0 | (c >> 6)); buf[count++] = (byte) (0xc0 | (c >> 6));
buf[count++] = (byte)(0x80 | (c & 0x3f)); buf[count++] = (byte) (0x80 | (c & 0x3f));
} else if (isSurrogate(c)) { } else if (isSurrogate(c)) {
if(4 >= buf.length - count) { if (4 >= buf.length - count) {
flushBuffer(); flushBuffer();
} }
int uc = Character.toCodePoint(c, str.charAt(i++)); int uc = Character.toCodePoint(c, str.charAt(i++));
buf[count++] = ((byte)(0xf0 | ((uc >> 18)))); buf[count++] = ((byte) (0xf0 | ((uc >> 18))));
buf[count++] = ((byte)(0x80 | ((uc >> 12) & 0x3f))); buf[count++] = ((byte) (0x80 | ((uc >> 12) & 0x3f)));
buf[count++] = ((byte)(0x80 | ((uc >> 6) & 0x3f))); buf[count++] = ((byte) (0x80 | ((uc >> 6) & 0x3f)));
buf[count++] = ((byte)(0x80 | (uc & 0x3f))); buf[count++] = ((byte) (0x80 | (uc & 0x3f)));
} else { } else {
if(3 >= buf.length - count) { if (3 >= buf.length - count) {
flushBuffer(); flushBuffer();
} }
buf[count++] =((byte)(0xe0 | ((c >> 12)))); buf[count++] = ((byte) (0xe0 | ((c >> 12))));
buf[count++] =((byte)(0x80 | ((c >> 6) & 0x3f))); buf[count++] = ((byte) (0x80 | ((c >> 6) & 0x3f)));
buf[count++] =((byte)(0x80 | (c & 0x3f))); buf[count++] = ((byte) (0x80 | (c & 0x3f)));
} }
} }
writeCrLf(); writeCrLf();
} }
private final static int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE}; private final static int[] sizeTable = { 9, 99, 999, 9999, 99999, 999999,
9999999, 99999999, 999999999, Integer.MAX_VALUE };
private final static byte[] DigitTens = { private final static byte[] DigitTens = { '0', '0', '0', '0', '0', '0',
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3',
'2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4',
'3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5',
'4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7',
'5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '7', '7', '7', '7', '7', '7', '7', '7', '7', '8', '8', '8', '8',
'6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '8', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9', '9', '9',
'7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '9', '9', '9', };
'8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
'9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
};
private final static byte[] DigitOnes = { private final static byte[] DigitOnes = { '0', '1', '2', '3', '4', '5',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '7', '8', '9', };
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
};
private final static byte[] digits = { private final static byte[] digits = { '0', '1', '2', '3', '4', '5', '6',
'0', '1', '2', '3', '4', '5', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'6', '7', '8', '9', 'a', 'b', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'c', 'd', 'e', 'f', 'g', 'h', 'x', 'y', 'z' };
'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'
};
public void writeIntCrLf(int value) throws IOException { public void writeIntCrLf(int value) throws IOException {
if (value < 0) { if (value < 0) {
write('-'); write((byte) '-');
value = -value; value = -value;
} }
int size = 0; int size = 0;
while (value > sizeTable[size]) while (value > sizeTable[size])
size++; size++;
size++; size++;
if (size >= buf.length - count) { if (size >= buf.length - count) {
flushBuffer(); flushBuffer();
} }
int q, r; int q, r;
int charPos = count + size; int charPos = count + size;
while (value >= 65536) { while (value >= 65536) {
q = value / 100; q = value / 100;
r = value - ((q << 6) + (q << 5) + (q << 2)); r = value - ((q << 6) + (q << 5) + (q << 2));
value = q; value = q;
buf[--charPos] = DigitOnes[r]; buf[--charPos] = DigitOnes[r];
buf[--charPos] = DigitTens[r]; buf[--charPos] = DigitTens[r];
} }
for (; ;) { for (;;) {
q = (value * 52429) >>> (16 + 3); q = (value * 52429) >>> (16 + 3);
r = value - ((q << 3) + (q << 1)); r = value - ((q << 3) + (q << 1));
buf[--charPos] = digits[r]; buf[--charPos] = digits[r];
value = q; value = q;
if (value == 0) break; if (value == 0)
} break;
count += size; }
count += size;
writeCrLf(); writeCrLf();
} }
public void flush() throws IOException { public void flush() throws IOException {
flushBuffer(); flushBuffer();
out.flush(); out.flush();
} }
} }

View File

@@ -11,31 +11,31 @@ import redis.clients.jedis.exceptions.JedisException;
* *
*/ */
public class SafeEncoder { public class SafeEncoder {
public static byte[][] encodeMany(final String... strs){ public static byte[][] encodeMany(final String... strs) {
byte[][] many = new byte[strs.length][]; byte[][] many = new byte[strs.length][];
for(int i=0;i<strs.length;i++){ for (int i = 0; i < strs.length; i++) {
many[i] = encode(strs[i]); many[i] = encode(strs[i]);
}
return many;
} }
return many;
}
public static byte[] encode(final String str) { public static byte[] encode(final String str) {
try { try {
if (str == null) { if (str == null) {
throw new JedisDataException( throw new JedisDataException(
"value sent to redis cannot be null"); "value sent to redis cannot be null");
} }
return str.getBytes(Protocol.CHARSET); return str.getBytes(Protocol.CHARSET);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new JedisException(e); throw new JedisException(e);
} }
} }
public static String encode(final byte[] data) { public static String encode(final byte[] data) {
try { try {
return new String(data, Protocol.CHARSET); return new String(data, Protocol.CHARSET);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new JedisException(e); throw new JedisException(e);
} }
} }
} }

View File

@@ -7,14 +7,14 @@ public abstract class ShardInfo<T> {
} }
public ShardInfo(int weight) { public ShardInfo(int weight) {
this.weight = weight; this.weight = weight;
} }
public int getWeight() { public int getWeight() {
return this.weight; return this.weight;
} }
protected abstract T createResource(); protected abstract T createResource();
public abstract String getName(); public abstract String getName();
} }

View File

@@ -26,91 +26,93 @@ public class Sharded<R, S extends ShardInfo<R>> {
private Pattern tagPattern = null; private Pattern tagPattern = null;
// the tag is anything between {} // the tag is anything between {}
public static final Pattern DEFAULT_KEY_TAG_PATTERN = Pattern public static final Pattern DEFAULT_KEY_TAG_PATTERN = Pattern
.compile("\\{(.+?)\\}"); .compile("\\{(.+?)\\}");
public Sharded(List<S> shards) { public Sharded(List<S> shards) {
this(shards, Hashing.MURMUR_HASH); // MD5 is really not good as we works this(shards, Hashing.MURMUR_HASH); // MD5 is really not good as we works
// with 64-bits not 128 // with 64-bits not 128
} }
public Sharded(List<S> shards, Hashing algo) { public Sharded(List<S> shards, Hashing algo) {
this.algo = algo; this.algo = algo;
initialize(shards); initialize(shards);
} }
public Sharded(List<S> shards, Pattern tagPattern) { public Sharded(List<S> shards, Pattern tagPattern) {
this(shards, Hashing.MURMUR_HASH, tagPattern); // MD5 is really not good this(shards, Hashing.MURMUR_HASH, tagPattern); // MD5 is really not good
// as we works with // as we works with
// 64-bits not 128 // 64-bits not 128
} }
public Sharded(List<S> shards, Hashing algo, Pattern tagPattern) { public Sharded(List<S> shards, Hashing algo, Pattern tagPattern) {
this.algo = algo; this.algo = algo;
this.tagPattern = tagPattern; this.tagPattern = tagPattern;
initialize(shards); initialize(shards);
} }
private void initialize(List<S> shards) { private void initialize(List<S> shards) {
nodes = new TreeMap<Long, S>(); nodes = new TreeMap<Long, S>();
for (int i = 0; i != shards.size(); ++i) { for (int i = 0; i != shards.size(); ++i) {
final S shardInfo = shards.get(i); final S shardInfo = shards.get(i);
if (shardInfo.getName() == null) if (shardInfo.getName() == null)
for (int n = 0; n < 160 * shardInfo.getWeight(); n++) { for (int n = 0; n < 160 * shardInfo.getWeight(); n++) {
nodes.put(this.algo.hash("SHARD-" + i + "-NODE-" + n), shardInfo); nodes.put(this.algo.hash("SHARD-" + i + "-NODE-" + n),
} shardInfo);
else }
for (int n = 0; n < 160 * shardInfo.getWeight(); n++) { else
nodes.put(this.algo.hash(shardInfo.getName() + "*" + shardInfo.getWeight() + n), shardInfo); for (int n = 0; n < 160 * shardInfo.getWeight(); n++) {
} nodes.put(
resources.put(shardInfo, shardInfo.createResource()); this.algo.hash(shardInfo.getName() + "*"
} + shardInfo.getWeight() + n), shardInfo);
}
resources.put(shardInfo, shardInfo.createResource());
}
} }
public R getShard(byte[] key) { public R getShard(byte[] key) {
return resources.get(getShardInfo(key)); return resources.get(getShardInfo(key));
} }
public R getShard(String key) { public R getShard(String key) {
return resources.get(getShardInfo(key)); return resources.get(getShardInfo(key));
} }
public S getShardInfo(byte[] key) { public S getShardInfo(byte[] key) {
SortedMap<Long, S> tail = nodes.tailMap(algo.hash(key)); SortedMap<Long, S> tail = nodes.tailMap(algo.hash(key));
if (tail.isEmpty()) { if (tail.isEmpty()) {
return nodes.get(nodes.firstKey()); return nodes.get(nodes.firstKey());
} }
return tail.get(tail.firstKey()); return tail.get(tail.firstKey());
} }
public S getShardInfo(String key) { public S getShardInfo(String key) {
return getShardInfo(SafeEncoder.encode(getKeyTag(key))); return getShardInfo(SafeEncoder.encode(getKeyTag(key)));
} }
/** /**
* A key tag is a special pattern inside a key that, if preset, is the only * A key tag is a special pattern inside a key that, if preset, is the only
* part of the key hashed in order to select the server for this key. * part of the key hashed in order to select the server for this key.
* *
* @see http://code.google.com/p/redis/wiki/FAQ#I * @see http://code.google.com/p/redis/wiki/FAQ#I
* 'm_using_some_form_of_key_hashing_for_partitioning,_but_wh * 'm_using_some_form_of_key_hashing_for_partitioning,_but_wh
* @param key * @param key
* @return The tag if it exists, or the original key * @return The tag if it exists, or the original key
*/ */
public String getKeyTag(String key) { public String getKeyTag(String key) {
if (tagPattern != null) { if (tagPattern != null) {
Matcher m = tagPattern.matcher(key); Matcher m = tagPattern.matcher(key);
if (m.find()) if (m.find())
return m.group(1); return m.group(1);
} }
return key; return key;
} }
public Collection<S> getAllShardInfo() { public Collection<S> getAllShardInfo() {
return Collections.unmodifiableCollection(nodes.values()); return Collections.unmodifiableCollection(nodes.values());
} }
public Collection<R> getAllShards() { public Collection<R> getAllShards() {
return Collections.unmodifiableCollection(resources.values()); return Collections.unmodifiableCollection(resources.values());
} }
} }

View File

@@ -4,50 +4,50 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class Slowlog { public class Slowlog {
private final long id; private final long id;
private final long timeStamp; private final long timeStamp;
private final long executionTime; private final long executionTime;
private final List<String> args; private final List<String> args;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static List<Slowlog> from(List<Object> nestedMultiBulkReply){ public static List<Slowlog> from(List<Object> nestedMultiBulkReply) {
List<Slowlog> logs = new ArrayList<Slowlog>(nestedMultiBulkReply.size()); List<Slowlog> logs = new ArrayList<Slowlog>(nestedMultiBulkReply.size());
for(Object obj : nestedMultiBulkReply){ for (Object obj : nestedMultiBulkReply) {
List<Object> properties = (List<Object>)obj; List<Object> properties = (List<Object>) obj;
logs.add(new Slowlog(properties)); logs.add(new Slowlog(properties));
}
return logs;
}
@SuppressWarnings("unchecked")
private Slowlog(List<Object> properties) {
super();
this.id = (Long)properties.get(0);
this.timeStamp = (Long)properties.get(1);
this.executionTime = (Long)properties.get(2);
List<byte[]> bargs = (List<byte[]>)properties.get(3);
this.args = new ArrayList<String>(bargs.size());
for(byte[] barg:bargs){
this.args.add(SafeEncoder.encode(barg));
}
} }
public long getId() { return logs;
return id; }
}
public long getTimeStamp() { @SuppressWarnings("unchecked")
return timeStamp; private Slowlog(List<Object> properties) {
} super();
this.id = (Long) properties.get(0);
this.timeStamp = (Long) properties.get(1);
this.executionTime = (Long) properties.get(2);
public long getExecutionTime() { List<byte[]> bargs = (List<byte[]>) properties.get(3);
return executionTime; this.args = new ArrayList<String>(bargs.size());
}
public List<String> getArgs() { for (byte[] barg : bargs) {
return args; this.args.add(SafeEncoder.encode(barg));
} }
}
public long getId() {
return id;
}
public long getTimeStamp() {
return timeStamp;
}
public long getExecutionTime() {
return executionTime;
}
public List<String> getArgs() {
return args;
}
} }

View File

@@ -8,7 +8,7 @@ import redis.clients.jedis.BuilderFactory;
public class BuilderFactoryTest extends Assert { public class BuilderFactoryTest extends Assert {
@Test @Test
public void buildDouble() { public void buildDouble() {
Double build = BuilderFactory.DOUBLE.build("1.0".getBytes()); Double build = BuilderFactory.DOUBLE.build("1.0".getBytes());
assertEquals(new Double(1.0), build); assertEquals(new Double(1.0), build);
} }
} }

View File

@@ -13,31 +13,31 @@ public class ConnectionTest extends Assert {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
client = new Connection(); client = new Connection();
} }
@After @After
public void tearDown() throws Exception { public void tearDown() throws Exception {
client.disconnect(); client.disconnect();
} }
@Test(expected = JedisConnectionException.class) @Test(expected = JedisConnectionException.class)
public void checkUnkownHost() { public void checkUnkownHost() {
client.setHost("someunknownhost"); client.setHost("someunknownhost");
client.connect(); client.connect();
} }
@Test(expected = JedisConnectionException.class) @Test(expected = JedisConnectionException.class)
public void checkWrongPort() { public void checkWrongPort() {
client.setHost("localhost"); client.setHost("localhost");
client.setPort(55665); client.setPort(55665);
client.connect(); client.connect();
} }
@Test @Test
public void connectIfNotConnectedWhenSettingTimeoutInfinite() { public void connectIfNotConnectedWhenSettingTimeoutInfinite() {
client.setHost("localhost"); client.setHost("localhost");
client.setPort(6379); client.setPort(6379);
client.setTimeoutInfinite(); client.setTimeoutInfinite();
} }

View File

@@ -9,22 +9,22 @@ public class FragmentedByteArrayInputStream extends ByteArrayInputStream {
private int readMethodCallCount = 0; private int readMethodCallCount = 0;
public FragmentedByteArrayInputStream(final byte[] buf) { public FragmentedByteArrayInputStream(final byte[] buf) {
super(buf); super(buf);
} }
public synchronized int read(final byte[] b, final int off, final int len) { public synchronized int read(final byte[] b, final int off, final int len) {
readMethodCallCount++; readMethodCallCount++;
if (len <= 10) { if (len <= 10) {
// if the len <= 10, return as usual .. // if the len <= 10, return as usual ..
return super.read(b, off, len); return super.read(b, off, len);
} else { } else {
// else return the first half .. // else return the first half ..
return super.read(b, off, len / 2); return super.read(b, off, len / 2);
} }
} }
public int getReadMethodCallCount() { public int getReadMethodCallCount() {
return readMethodCallCount; return readMethodCallCount;
} }
} }

View File

@@ -3,112 +3,112 @@ package redis.clients.jedis.tests;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Protocol; import redis.clients.jedis.Protocol;
public class HostAndPortUtil { public class HostAndPortUtil {
private static List<HostAndPort> redisHostAndPortList = new ArrayList<HostAndPortUtil.HostAndPort>(); private static List<HostAndPort> redisHostAndPortList = new ArrayList<HostAndPort>();
private static List<HostAndPort> sentinelHostAndPortList = new ArrayList<HostAndPortUtil.HostAndPort>(); private static List<HostAndPort> sentinelHostAndPortList = new ArrayList<HostAndPort>();
private static List<HostAndPort> clusterHostAndPortList = new ArrayList<HostAndPort>();
static { static {
HostAndPort defaulthnp1 = new HostAndPort();
defaulthnp1.host = "localhost";
defaulthnp1.port = Protocol.DEFAULT_PORT;
redisHostAndPortList.add(defaulthnp1);
HostAndPort defaulthnp2 = new HostAndPort(); HostAndPort defaulthnp1 = new HostAndPort("localhost",
defaulthnp2.host = "localhost"; Protocol.DEFAULT_PORT);
defaulthnp2.port = Protocol.DEFAULT_PORT + 1; redisHostAndPortList.add(defaulthnp1);
redisHostAndPortList.add(defaulthnp2);
HostAndPort defaulthnp3 = new HostAndPort();
defaulthnp3.host = "localhost";
defaulthnp3.port = Protocol.DEFAULT_PORT + 2;
redisHostAndPortList.add(defaulthnp3);
HostAndPort defaulthnp4 = new HostAndPort();
defaulthnp4.host = "localhost";
defaulthnp4.port = Protocol.DEFAULT_PORT + 3;
redisHostAndPortList.add(defaulthnp4);
HostAndPort defaulthnp5 = new HostAndPort();
defaulthnp5.host = "localhost";
defaulthnp5.port = Protocol.DEFAULT_PORT + 4;
redisHostAndPortList.add(defaulthnp5);
HostAndPort defaulthnp6 = new HostAndPort();
defaulthnp6.host = "localhost";
defaulthnp6.port = Protocol.DEFAULT_SENTINEL_PORT;
sentinelHostAndPortList.add(defaulthnp6);
HostAndPort defaulthnp7 = new HostAndPort();
defaulthnp7.host = "localhost";
defaulthnp7.port = Protocol.DEFAULT_SENTINEL_PORT + 1;
sentinelHostAndPortList.add(defaulthnp7);
HostAndPort defaulthnp8 = new HostAndPort();
defaulthnp8.host = "localhost";
defaulthnp8.port = Protocol.DEFAULT_SENTINEL_PORT + 2;
sentinelHostAndPortList.add(defaulthnp8);
String envRedisHosts = System.getProperty("redis-hosts"); HostAndPort defaulthnp2 = new HostAndPort("localhost",
String envSentinelHosts = System.getProperty("sentinel-hosts"); Protocol.DEFAULT_PORT + 1);
redisHostAndPortList.add(defaulthnp2);
redisHostAndPortList = parseHosts(envRedisHosts, redisHostAndPortList);
sentinelHostAndPortList = parseHosts(envSentinelHosts, sentinelHostAndPortList); HostAndPort defaulthnp3 = new HostAndPort("localhost",
Protocol.DEFAULT_PORT + 2);
redisHostAndPortList.add(defaulthnp3);
HostAndPort defaulthnp4 = new HostAndPort("localhost",
Protocol.DEFAULT_PORT + 3);
redisHostAndPortList.add(defaulthnp4);
HostAndPort defaulthnp5 = new HostAndPort("localhost",
Protocol.DEFAULT_PORT + 4);
redisHostAndPortList.add(defaulthnp5);
HostAndPort defaulthnp6 = new HostAndPort("localhost",
Protocol.DEFAULT_PORT + 5);
redisHostAndPortList.add(defaulthnp6);
HostAndPort defaulthnp7 = new HostAndPort("localhost",
Protocol.DEFAULT_SENTINEL_PORT);
sentinelHostAndPortList.add(defaulthnp7);
HostAndPort defaulthnp8 = new HostAndPort("localhost",
Protocol.DEFAULT_SENTINEL_PORT + 1);
sentinelHostAndPortList.add(defaulthnp8);
HostAndPort defaulthnp9 = new HostAndPort("localhost",
Protocol.DEFAULT_SENTINEL_PORT + 2);
sentinelHostAndPortList.add(defaulthnp9);
clusterHostAndPortList.add(new HostAndPort("localhost", 7379));
clusterHostAndPortList.add(new HostAndPort("localhost", 7380));
clusterHostAndPortList.add(new HostAndPort("localhost", 7381));
String envRedisHosts = System.getProperty("redis-hosts");
String envSentinelHosts = System.getProperty("sentinel-hosts");
String envClusterHosts = System.getProperty("cluster-hosts");
redisHostAndPortList = parseHosts(envRedisHosts, redisHostAndPortList);
sentinelHostAndPortList = parseHosts(envSentinelHosts,
sentinelHostAndPortList);
clusterHostAndPortList = parseHosts(envClusterHosts,
clusterHostAndPortList);
} }
public static List<HostAndPort> parseHosts(String envHosts, List<HostAndPort> existingHostsAndPorts) { public static List<HostAndPort> parseHosts(String envHosts,
List<HostAndPort> existingHostsAndPorts) {
if (null != envHosts && 0 < envHosts.length()) {
if (null != envHosts && 0 < envHosts.length()) {
String[] hostDefs = envHosts.split(",");
String[] hostDefs = envHosts.split(",");
if (null != hostDefs && 2 <= hostDefs.length) {
if (null != hostDefs && 2 <= hostDefs.length) {
List<HostAndPort> envHostsAndPorts = new ArrayList<HostAndPortUtil.HostAndPort>(hostDefs.length);
List<HostAndPort> envHostsAndPorts = new ArrayList<HostAndPort>(
for (String hostDef : hostDefs) { hostDefs.length);
String[] hostAndPort = hostDef.split(":"); for (String hostDef : hostDefs) {
if (null != hostAndPort && 2 == hostAndPort.length) { String[] hostAndPort = hostDef.split(":");
HostAndPort hnp = new HostAndPort(); if (null != hostAndPort && 2 == hostAndPort.length) {
hnp.host = hostAndPort[0]; String host = hostAndPort[0];
int port = Protocol.DEFAULT_PORT;
try {
hnp.port = Integer.parseInt(hostAndPort[1]); try {
} catch (final NumberFormatException nfe) { port = Integer.parseInt(hostAndPort[1]);
hnp.port = Protocol.DEFAULT_PORT; } catch (final NumberFormatException nfe) {
} }
envHostsAndPorts.add(hnp); envHostsAndPorts.add(new HostAndPort(host, port));
} }
} }
return envHostsAndPorts; return envHostsAndPorts;
} }
} }
return existingHostsAndPorts; return existingHostsAndPorts;
} }
public static List<HostAndPort> getRedisServers() { public static List<HostAndPort> getRedisServers() {
return redisHostAndPortList; return redisHostAndPortList;
}
public static List<HostAndPort> getSentinelServers() {
return sentinelHostAndPortList;
} }
public static class HostAndPort { public static List<HostAndPort> getSentinelServers() {
public String host; return sentinelHostAndPortList;
public int port; }
@Override public static List<HostAndPort> getClusterServers() {
public String toString() { return clusterHostAndPortList;
return host + ":" + port;
}
} }
} }

View File

@@ -0,0 +1,195 @@
package redis.clients.jedis.tests;
import java.util.HashSet;
import java.util.Set;
import org.junit.After;
import org.junit.Assert;
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.Pipeline;
import redis.clients.jedis.exceptions.JedisAskDataException;
import redis.clients.jedis.exceptions.JedisClusterException;
import redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException;
import redis.clients.jedis.exceptions.JedisMovedDataException;
import redis.clients.util.JedisClusterCRC16;
public class JedisClusterTest extends Assert {
private Jedis node1;
private Jedis node2;
private Jedis node3;
private HostAndPort nodeInfo1 = HostAndPortUtil.getClusterServers().get(0);
private HostAndPort nodeInfo2 = HostAndPortUtil.getClusterServers().get(1);
private HostAndPort nodeInfo3 = HostAndPortUtil.getClusterServers().get(2);
@Before
public void setUp() throws InterruptedException {
node1 = new Jedis(nodeInfo1.getHost(), nodeInfo1.getPort());
node1.connect();
node1.flushAll();
node2 = new Jedis(nodeInfo2.getHost(), nodeInfo2.getPort());
node2.connect();
node2.flushAll();
node3 = new Jedis(nodeInfo3.getHost(), nodeInfo3.getPort());
node3.connect();
node3.flushAll();
// ---- configure cluster
// add nodes to cluster
node1.clusterMeet("127.0.0.1", nodeInfo2.getPort());
node1.clusterMeet("127.0.0.1", nodeInfo3.getPort());
// split available slots across the three nodes
int slotsPerNode = JedisCluster.HASHSLOTS / 3;
Pipeline pipeline1 = node1.pipelined();
Pipeline pipeline2 = node2.pipelined();
Pipeline pipeline3 = node3.pipelined();
for (int i = 0; i < JedisCluster.HASHSLOTS; i++) {
if (i < slotsPerNode) {
pipeline1.clusterAddSlots(i);
} else if (i > slotsPerNode * 2) {
pipeline3.clusterAddSlots(i);
} else {
pipeline2.clusterAddSlots(i);
}
}
pipeline1.sync();
pipeline2.sync();
pipeline3.sync();
waitForClusterReady();
}
@After
public void tearDown() {
// clear all slots
int[] slotsToDelete = new int[JedisCluster.HASHSLOTS];
for (int i = 0; i < JedisCluster.HASHSLOTS; i++) {
slotsToDelete[i] = i;
}
node1.clusterDelSlots(slotsToDelete);
node2.clusterDelSlots(slotsToDelete);
node3.clusterDelSlots(slotsToDelete);
}
@Test(expected = JedisMovedDataException.class)
public void testThrowMovedException() {
node1.set("foo", "bar");
}
@Test
public void testMovedExceptionParameters() {
try {
node1.set("foo", "bar");
} catch (JedisMovedDataException jme) {
assertEquals(12182, jme.getSlot());
assertEquals(new HostAndPort("127.0.0.1", 7381),
jme.getTargetNode());
return;
}
fail();
}
@Test(expected = JedisAskDataException.class)
public void testThrowAskException() {
int keySlot = JedisClusterCRC16.getSlot("test");
String node3Id = getNodeId(node3.clusterNodes());
node2.clusterSetSlotMigrating(keySlot, node3Id);
node2.get("test");
}
@Test
public void testDiscoverNodesAutomatically() {
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
assertEquals(jc.getClusterNodes().size(), 3);
}
@Test
public void testCalculateConnectionPerSlot() {
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
jc.set("foo", "bar");
jc.set("test", "test");
assertEquals("bar", node3.get("foo"));
assertEquals("test", node2.get("test"));
}
@Test
public void testRecalculateSlotsWhenMoved() throws InterruptedException {
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
int slot51 = JedisClusterCRC16.getSlot("51");
node2.clusterDelSlots(slot51);
node3.clusterDelSlots(slot51);
node3.clusterAddSlots(slot51);
waitForClusterReady();
jc.set("51", "foo");
assertEquals("foo", jc.get("51"));
}
@Test
public void testAskResponse() throws InterruptedException {
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
int slot51 = JedisClusterCRC16.getSlot("51");
node3.clusterSetSlotImporting(slot51, getNodeId(node2.clusterNodes()));
node2.clusterSetSlotMigrating(slot51, getNodeId(node3.clusterNodes()));
jc.set("51", "foo");
assertEquals("foo", jc.get("51"));
}
@Test(expected = JedisClusterException.class)
public void testThrowExceptionWithoutKey() {
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
jc.ping();
}
@Test(expected = JedisClusterMaxRedirectionsException.class)
public void testRedisClusterMaxRedirections() {
Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
jedisClusterNode.add(new HostAndPort("127.0.0.1", 7379));
JedisCluster jc = new JedisCluster(jedisClusterNode);
int slot51 = JedisClusterCRC16.getSlot("51");
// This will cause an infinite redirection loop
node2.clusterSetSlotMigrating(slot51, getNodeId(node3.clusterNodes()));
jc.set("51", "foo");
}
private String getNodeId(String infoOutput) {
for (String infoLine : infoOutput.split("\n")) {
if (infoLine.contains("myself")) {
return infoLine.split(" ")[0];
}
}
return "";
}
private void waitForClusterReady() throws InterruptedException {
boolean clusterOk = false;
while (!clusterOk) {
if (node1.clusterInfo().split("\n")[0].contains("ok")
&& node2.clusterInfo().split("\n")[0].contains("ok")
&& node3.clusterInfo().split("\n")[0].contains("ok")) {
clusterOk = true;
}
Thread.sleep(50);
}
}
}

View File

@@ -3,128 +3,120 @@ package redis.clients.jedis.tests;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.BinaryJedis; import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
public class JedisPoolTest extends Assert { public class JedisPoolTest extends Assert {
private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0); private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);
@Test @Test
public void checkConnections() { public void checkConnections() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.host, JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.port, 2000); hnp.getPort(), 2000);
Jedis jedis = pool.getResource(); Jedis jedis = pool.getResource();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.set("foo", "bar"); jedis.set("foo", "bar");
assertEquals("bar", jedis.get("foo")); assertEquals("bar", jedis.get("foo"));
pool.returnResource(jedis); pool.returnResource(jedis);
pool.destroy(); pool.destroy();
} }
@Test @Test
public void checkConnectionWithDefaultPort() { public void checkConnectionWithDefaultPort() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.host, JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.port); hnp.getPort());
Jedis jedis = pool.getResource(); Jedis jedis = pool.getResource();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.set("foo", "bar"); jedis.set("foo", "bar");
assertEquals("bar", jedis.get("foo")); assertEquals("bar", jedis.get("foo"));
pool.returnResource(jedis); pool.returnResource(jedis);
pool.destroy(); pool.destroy();
} }
@Test @Test
public void checkJedisIsReusedWhenReturned() { public void checkJedisIsReusedWhenReturned() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.host,
hnp.port);
Jedis jedis = pool.getResource();
jedis.auth("foobared");
jedis.set("foo", "0");
pool.returnResource(jedis);
jedis = pool.getResource(); JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
jedis.auth("foobared"); hnp.getPort());
jedis.incr("foo"); Jedis jedis = pool.getResource();
pool.returnResource(jedis); jedis.auth("foobared");
pool.destroy(); jedis.set("foo", "0");
pool.returnResource(jedis);
jedis = pool.getResource();
jedis.auth("foobared");
jedis.incr("foo");
pool.returnResource(jedis);
pool.destroy();
} }
@Test @Test
public void checkPoolRepairedWhenJedisIsBroken() { public void checkPoolRepairedWhenJedisIsBroken() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.host, JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.port); hnp.getPort());
Jedis jedis = pool.getResource(); Jedis jedis = pool.getResource();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.quit(); jedis.quit();
pool.returnBrokenResource(jedis); pool.returnBrokenResource(jedis);
jedis = pool.getResource(); jedis = pool.getResource();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.incr("foo"); jedis.incr("foo");
pool.returnResource(jedis); pool.returnResource(jedis);
pool.destroy(); pool.destroy();
} }
@Test(expected = JedisConnectionException.class) @Test(expected = JedisConnectionException.class)
public void checkPoolOverflow() { public void checkPoolOverflow() {
Config config = new Config(); GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.maxActive = 1; config.setMaxTotal(1);
config.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_FAIL; config.setBlockWhenExhausted(false);
JedisPool pool = new JedisPool(config, hnp.host, hnp.port); JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort());
Jedis jedis = pool.getResource(); Jedis jedis = pool.getResource();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.set("foo", "0"); jedis.set("foo", "0");
Jedis newJedis = pool.getResource(); Jedis newJedis = pool.getResource();
newJedis.auth("foobared"); newJedis.auth("foobared");
newJedis.incr("foo"); newJedis.incr("foo");
} }
@Test @Test
public void securePool() { public void securePool() {
JedisPoolConfig config = new JedisPoolConfig(); JedisPoolConfig config = new JedisPoolConfig();
config.setTestOnBorrow(true); config.setTestOnBorrow(true);
JedisPool pool = new JedisPool(config, hnp.host, hnp.port, 2000, "foobared"); JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort(),
Jedis jedis = pool.getResource(); 2000, "foobared");
jedis.set("foo", "bar"); Jedis jedis = pool.getResource();
pool.returnResource(jedis); jedis.set("foo", "bar");
pool.destroy(); pool.returnResource(jedis);
pool.destroy();
} }
@Test @Test
public void nonDefaultDatabase() { public void nonDefaultDatabase() {
JedisPool pool0 = new JedisPool(new JedisPoolConfig(), hnp.host, JedisPool pool0 = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.port, 2000, "foobared"); hnp.getPort(), 2000, "foobared");
Jedis jedis0 = pool0.getResource(); Jedis jedis0 = pool0.getResource();
jedis0.set("foo", "bar"); jedis0.set("foo", "bar");
assertEquals( "bar", jedis0.get("foo") ); assertEquals("bar", jedis0.get("foo"));
pool0.returnResource(jedis0); pool0.returnResource(jedis0);
pool0.destroy(); pool0.destroy();
JedisPool pool1 = new JedisPool(new JedisPoolConfig(), hnp.host, JedisPool pool1 = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.port, 2000, "foobared", 1); hnp.getPort(), 2000, "foobared", 1);
Jedis jedis1 = pool1.getResource(); Jedis jedis1 = pool1.getResource();
assertNull( jedis1.get("foo") ); assertNull(jedis1.get("foo"));
pool1.returnResource(jedis0); pool1.returnResource(jedis1);
pool1.destroy(); pool1.destroy();
}
@Test
public void returnBinary() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.host,
hnp.port, 2000);
BinaryJedis jedis = pool.getResource();
pool.returnResource(jedis);
pool.destroy();
} }
@Test @Test
@@ -145,43 +137,65 @@ public class JedisPoolTest extends Assert {
j.auth("foobared"); j.auth("foobared");
j.select(2); j.select(2);
j.set("foo", "bar"); j.set("foo", "bar");
JedisPool pool = new JedisPool(new URI("redis://:foobared@localhost:6380/2")); JedisPool pool = new JedisPool(new URI(
"redis://:foobared@localhost:6380/2"));
Jedis jedis = pool.getResource(); Jedis jedis = pool.getResource();
assertEquals("PONG", jedis.ping()); assertEquals("PONG", jedis.ping());
assertEquals("bar", jedis.get("foo")); assertEquals("bar", jedis.get("foo"));
} }
@Test @Test
public void selectDatabaseOnActivation() { public void selectDatabaseOnActivation() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.host, hnp.port, 2000, "foobared"); JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.getPort(), 2000, "foobared");
Jedis jedis0 = pool.getResource(); Jedis jedis0 = pool.getResource();
assertEquals(0L, jedis0.getDB().longValue()); assertEquals(0L, jedis0.getDB().longValue());
jedis0.select(1);
assertEquals(1L, jedis0.getDB().longValue());
pool.returnResource(jedis0); jedis0.select(1);
assertEquals(1L, jedis0.getDB().longValue());
Jedis jedis1 = pool.getResource(); pool.returnResource(jedis0);
assertTrue("Jedis instance was not reused", jedis1 == jedis0);
assertEquals(0L, jedis1.getDB().longValue());
pool.returnResource(jedis1); Jedis jedis1 = pool.getResource();
pool.destroy(); assertTrue("Jedis instance was not reused", jedis1 == jedis0);
} assertEquals(0L, jedis1.getDB().longValue());
pool.returnResource(jedis1);
pool.destroy();
}
@Test @Test
public void customClientName() { public void customClientName() {
JedisPool pool0 = new JedisPool(new JedisPoolConfig(), hnp.host, JedisPool pool0 = new JedisPool(new JedisPoolConfig(), hnp.getHost(),
hnp.port, 2000, "foobared", 0, "my_shiny_client_name"); hnp.getPort(), 2000, "foobared", 0, "my_shiny_client_name");
Jedis jedis = pool0.getResource(); Jedis jedis = pool0.getResource();
assertEquals("my_shiny_client_name", jedis.clientGetname()); assertEquals("my_shiny_client_name", jedis.clientGetname());
pool0.returnResource(jedis); pool0.returnResource(jedis);
pool0.destroy(); pool0.destroy();
}
@Test
public void returnResourceShouldResetState() {
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();
jedis.set("hello", "jedis");
Transaction t = jedis.multi();
t.set("hello", "world");
pool.returnResource(jedis);
Jedis jedis2 = pool.getResource();
assertTrue(jedis == jedis2);
assertEquals("jedis", jedis2.get("hello"));
pool.returnResource(jedis2);
pool.destroy();
} }
} }

View File

@@ -2,97 +2,173 @@ package redis.clients.jedis.tests;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.pool.impl.GenericObjectPool.Config; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.DebugParams; import redis.clients.jedis.DebugParams;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.JedisSentinelPool; import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort; import redis.clients.jedis.Transaction;
public class JedisSentinelPoolTest extends JedisTestBase { public class JedisSentinelPoolTest extends JedisTestBase {
private static final String MASTER_NAME = "mymaster";
protected static HostAndPort master = HostAndPortUtil.getRedisServers() protected static HostAndPort master = HostAndPortUtil.getRedisServers()
.get(2); .get(2);
protected static HostAndPort slave1 = HostAndPortUtil.getRedisServers() protected static HostAndPort slave1 = HostAndPortUtil.getRedisServers()
.get(3); .get(3);
protected static HostAndPort slave2 = HostAndPortUtil.getRedisServers() protected static HostAndPort slave2 = HostAndPortUtil.getRedisServers()
.get(4); .get(4);
protected static HostAndPort sentinel1 = HostAndPortUtil protected static HostAndPort sentinel1 = HostAndPortUtil
.getSentinelServers().get(1); .getSentinelServers().get(1);
protected static HostAndPort sentinel2 = HostAndPortUtil protected static HostAndPort sentinel2 = HostAndPortUtil
.getSentinelServers().get(2); .getSentinelServers().get(2);
protected static Jedis masterJedis; protected static Jedis sentinelJedis1;
protected static Jedis slaveJedis1;
protected static Jedis slaveJedis2;
protected static int slaveCount = 0;
protected Set<String> sentinels = new HashSet<String>(); protected Set<String> sentinels = new HashSet<String>();
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
// set up master and slaves
masterJedis = new Jedis(master.host, master.port);
masterJedis.auth("foobared");
masterJedis.slaveofNoOne();
slaveJedis1 = new Jedis(slave1.host, slave1.port);
slaveJedis1.auth("foobared");
slaveJedis1.slaveof(master.host, master.port);
slaveCount++;
slaveJedis2 = new Jedis(slave2.host, slave2.port);
slaveJedis2.auth("foobared");
slaveJedis2.slaveof(master.host, master.port);
slaveCount++;
sentinels.add(sentinel1.toString()); sentinels.add(sentinel1.toString());
sentinels.add(sentinel2.toString()); sentinels.add(sentinel2.toString());
// FIXME: The following allows the master/slave relationship to sentinelJedis1 = new Jedis(sentinel1.getHost(), sentinel1.getPort());
// be established, and let sentinels know about this relationship.
// We can do this more elegantly.
Thread.sleep(10000);
} }
@Test @Test
public void ensureSafeTwiceFailover() throws InterruptedException { public void ensureSafeTwiceFailover() throws InterruptedException {
JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels, JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels,
new Config(), 1000, "foobared", 2); new GenericObjectPoolConfig(), 1000, "foobared", 2);
// perform failover // perform failover
doSegFaultMaster(pool); doSegFaultMaster(pool);
// perform failover once again // perform failover once again
doSegFaultMaster(pool); doSegFaultMaster(pool);
// you can test failover as much as possible // you can test failover as much as possible
// but you need to prepare additional slave per failover // but you need to prepare additional slave per failover
} }
private void doSegFaultMaster(JedisSentinelPool pool) throws InterruptedException {
// jedis connection should be master
Jedis jedis = pool.getResource();
assertEquals("PONG", jedis.ping());
try { private void doSegFaultMaster(JedisSentinelPool pool)
jedis.debug(DebugParams.SEGFAULT()); throws InterruptedException {
} catch (Exception e) { HostAndPort oldMaster = pool.getCurrentHostMaster();
}
// wait for the sentinel to promote a master // jedis connection should be master
// FIXME: we can query the sentinel and sleep Jedis jedis = pool.getResource();
// right until the master is promoted assertEquals("PONG", jedis.ping());
Thread.sleep(35000);
jedis = pool.getResource(); try {
assertEquals("PONG", jedis.ping()); jedis.debug(DebugParams.SEGFAULT());
assertEquals("foobared", jedis.configGet("requirepass").get(1)); } catch (Exception e) {
assertEquals(2, jedis.getDB().intValue()); }
waitForFailover(pool, oldMaster);
Thread.sleep(100);
jedis = pool.getResource();
assertEquals("PONG", jedis.ping());
assertEquals("foobared", jedis.configGet("requirepass").get(1));
assertEquals(2, jedis.getDB().intValue());
}
private void waitForFailover(JedisSentinelPool pool, HostAndPort oldMaster)
throws InterruptedException {
waitForJedisSentinelPoolRecognizeNewMaster(pool);
}
private void waitForJedisSentinelPoolRecognizeNewMaster(
JedisSentinelPool pool) throws InterruptedException {
final AtomicReference<String> newmaster = new AtomicReference<String>(
"");
sentinelJedis1.psubscribe(new JedisPubSub() {
@Override
public void onMessage(String channel, String message) {
// TODO Auto-generated method stub
}
@Override
public void onPMessage(String pattern, String channel,
String message) {
if (channel.equals("+switch-master")) {
newmaster.set(message);
punsubscribe();
}
// TODO Auto-generated method stub
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
// TODO Auto-generated method stub
}
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
// TODO Auto-generated method stub
}
@Override
public void onPUnsubscribe(String pattern, int subscribedChannels) {
// TODO Auto-generated method stub
}
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
// TODO Auto-generated method stub
}
}, "*");
String[] chunks = newmaster.get().split(" ");
HostAndPort newMaster = new HostAndPort(chunks[3],
Integer.parseInt(chunks[4]));
while (true) {
String host = pool.getCurrentHostMaster().getHost();
int port = pool.getCurrentHostMaster().getPort();
if (host.equals(newMaster.getHost()) && port == newMaster.getPort())
break;
System.out
.println("JedisSentinelPool's master is not yet changed, sleep...");
Thread.sleep(100);
}
}
@Test
public void returnResourceShouldResetState() {
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();
jedis.set("hello", "jedis");
Transaction t = jedis.multi();
t.set("hello", "world");
pool.returnResource(jedis);
Jedis jedis2 = pool.getResource();
assertTrue(jedis == jedis2);
assertEquals("jedis", jedis2.get("hello"));
pool.returnResource(jedis2);
pool.destroy();
} }
} }

View File

@@ -1,9 +1,5 @@
package redis.clients.jedis.tests; package redis.clients.jedis.tests;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -11,33 +7,40 @@ import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
public class JedisSentinelTest { public class JedisSentinelTest extends JedisTestBase {
private static final String MASTER_NAME = "mymaster"; private static final String MASTER_NAME = "mymaster";
protected static HostAndPort master = HostAndPortUtil.getRedisServers()
.get(0);
protected static HostAndPort slave = HostAndPortUtil.getRedisServers().get(
5);
protected static HostAndPort sentinel = HostAndPortUtil
.getSentinelServers().get(0);
protected static Jedis masterJedis;
protected static Jedis slaveJedis;
protected static Jedis sentinelJedis;
@Before @Before
public void setup() throws InterruptedException { public void setup() throws InterruptedException {
Jedis j = new Jedis("localhost", 6380);
j.auth("foobared");
j.configSet("masterauth", "foobared");
j.slaveof("localhost", 6379);
// TODO: The sleep is to give time to the slave to synchronize with the
// master and also let know the sentinels about this new topology. We
// should find a better way to do this.
Thread.sleep(10000);
} }
@After @After
public void clear() { public void clear() throws InterruptedException {
Jedis j = new Jedis("localhost", 6380); // New Sentinel (after 2.8.1)
j.auth("foobared"); // when slave promoted to master (slave of no one), New Sentinel force
j.slaveofNoOne(); // to restore it (demote)
// so, promote(slaveof) slave to master has no effect, not same to old
// Sentinel's behavior
} }
@Test @Test
public void sentinel() { public void sentinel() {
Jedis j = new Jedis("localhost", 26379); Jedis j = new Jedis(sentinel.getHost(), sentinel.getPort());
List<Map<String, String>> masters = j.sentinelMasters(); List<Map<String, String>> masters = j.sentinelMasters();
final String masterName = masters.get(0).get("name"); final String masterName = masters.get(0).get("name");
@@ -45,25 +48,18 @@ public class JedisSentinelTest {
List<String> masterHostAndPort = j List<String> masterHostAndPort = j
.sentinelGetMasterAddrByName(masterName); .sentinelGetMasterAddrByName(masterName);
assertEquals("127.0.0.1", masterHostAndPort.get(0)); HostAndPort masterFromSentinel = new HostAndPort(
assertEquals("6379", masterHostAndPort.get(1)); masterHostAndPort.get(0), Integer.parseInt(masterHostAndPort
.get(1)));
assertEquals(master, masterFromSentinel);
List<Map<String, String>> slaves = j.sentinelSlaves(masterName); List<Map<String, String>> slaves = j.sentinelSlaves(masterName);
assertTrue(slaves.size() > 0); assertTrue(slaves.size() > 0);
assertEquals("6379", slaves.get(0).get("master-port")); assertEquals(master.getPort(),
Integer.parseInt(slaves.get(0).get("master-port")));
List<? extends Object> isMasterDownByAddr = j
.sentinelIsMasterDownByAddr("127.0.0.1", 6379);
assertEquals(Long.valueOf(0), (Long) isMasterDownByAddr.get(0));
assertFalse("?".equals(isMasterDownByAddr.get(1)));
isMasterDownByAddr = j.sentinelIsMasterDownByAddr("127.0.0.1", 1);
assertEquals(Long.valueOf(0), (Long) isMasterDownByAddr.get(0));
assertTrue("?".equals(isMasterDownByAddr.get(1)));
// DO NOT RE-RUN TEST TOO FAST, RESET TAKES SOME TIME TO... RESET // DO NOT RE-RUN TEST TOO FAST, RESET TAKES SOME TIME TO... RESET
assertEquals(Long.valueOf(1), j.sentinelReset(masterName)); assertEquals(Long.valueOf(1), j.sentinelReset(masterName));
assertEquals(Long.valueOf(0), j.sentinelReset("woof" + masterName)); assertEquals(Long.valueOf(0), j.sentinelReset("woof" + masterName));
} }
} }

View File

@@ -52,9 +52,7 @@ public class JedisTest extends JedisCommandTestBase {
jedis = new Jedis("localhost", 6379, 15000); jedis = new Jedis("localhost", 6379, 15000);
jedis.auth("foobared"); jedis.auth("foobared");
jedis.configSet("timeout", "1"); jedis.configSet("timeout", "1");
// we need to sleep a long time since redis check for idle connections Thread.sleep(2000);
// every 10 seconds or so
Thread.sleep(20000);
jedis.hmget("foobar", "foo"); jedis.hmget("foobar", "foo");
} }

View File

@@ -8,18 +8,18 @@ import org.junit.Assert;
public abstract class JedisTestBase extends Assert { public abstract class JedisTestBase extends Assert {
protected void assertEquals(List<byte[]> expected, List<byte[]> actual) { protected void assertEquals(List<byte[]> expected, List<byte[]> actual) {
assertEquals(expected.size(), actual.size()); assertEquals(expected.size(), actual.size());
for (int n = 0; n < expected.size(); n++) { for (int n = 0; n < expected.size(); n++) {
assertArrayEquals(expected.get(n), actual.get(n)); assertArrayEquals(expected.get(n), actual.get(n));
} }
} }
protected void assertEquals(Set<byte[]> expected, Set<byte[]> actual) { protected void assertEquals(Set<byte[]> expected, Set<byte[]> actual) {
assertEquals(expected.size(), actual.size()); assertEquals(expected.size(), actual.size());
Iterator<byte[]> iterator = expected.iterator(); Iterator<byte[]> iterator = expected.iterator();
Iterator<byte[]> iterator2 = actual.iterator(); Iterator<byte[]> iterator2 = actual.iterator();
while (iterator.hasNext() || iterator2.hasNext()) { while (iterator.hasNext() || iterator2.hasNext()) {
assertArrayEquals(iterator.next(), iterator2.next()); assertArrayEquals(iterator.next(), iterator2.next());
} }
} }
} }

View File

@@ -1,14 +1,24 @@
package redis.clients.jedis.tests; package redis.clients.jedis.tests;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import redis.clients.jedis.*;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
import java.io.UnsupportedEncodingException; import redis.clients.jedis.HostAndPort;
import java.util.*; import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.PipelineBlock;
import redis.clients.jedis.Response;
import redis.clients.jedis.Tuple;
import redis.clients.jedis.exceptions.JedisDataException;
public class PipeliningTest extends Assert { public class PipeliningTest extends Assert {
private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0); private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);
@@ -17,307 +27,321 @@ public class PipeliningTest extends Assert {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
jedis = new Jedis(hnp.host, hnp.port, 500); jedis = new Jedis(hnp.getHost(), hnp.getPort(), 500);
jedis.connect(); jedis.connect();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.flushAll(); jedis.flushAll();
} }
@Test @Test
public void pipeline() throws UnsupportedEncodingException { public void pipeline() throws UnsupportedEncodingException {
List<Object> results = jedis.pipelined(new PipelineBlock() { List<Object> results = jedis.pipelined(new PipelineBlock() {
public void execute() { public void execute() {
set("foo", "bar"); set("foo", "bar");
get("foo"); get("foo");
} }
}); });
assertEquals(2, results.size()); assertEquals(2, results.size());
assertEquals("OK", results.get(0)); assertEquals("OK", results.get(0));
assertEquals("bar", results.get(1)); assertEquals("bar", results.get(1));
Pipeline p = jedis.pipelined(); Pipeline p = jedis.pipelined();
p.set("foo", "bar"); p.set("foo", "bar");
p.get("foo"); p.get("foo");
results = p.syncAndReturnAll(); results = p.syncAndReturnAll();
assertEquals(2, results.size()); assertEquals(2, results.size());
assertEquals("OK", results.get(0)); assertEquals("OK", results.get(0));
assertEquals("bar", results.get(1)); assertEquals("bar", results.get(1));
} }
@Test @Test
public void pipelineResponse() { public void pipelineResponse() {
jedis.set("string", "foo"); jedis.set("string", "foo");
jedis.lpush("list", "foo"); jedis.lpush("list", "foo");
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");
Pipeline p = jedis.pipelined(); Pipeline p = jedis.pipelined();
Response<String> string = p.get("string"); Response<String> string = p.get("string");
Response<String> list = p.lpop("list"); Response<String> list = p.lpop("list");
Response<String> hash = p.hget("hash", "foo"); Response<String> hash = p.hget("hash", "foo");
Response<Set<String>> zset = p.zrange("zset", 0, -1); Response<Set<String>> zset = p.zrange("zset", 0, -1);
Response<String> set = p.spop("set"); Response<String> set = p.spop("set");
Response<Boolean> blist = p.exists("list"); Response<Boolean> blist = p.exists("list");
Response<Double> zincrby = p.zincrby("zset", 1, "foo"); Response<Double> zincrby = p.zincrby("zset", 1, "foo");
Response<Long> zcard = p.zcard("zset"); Response<Long> zcard = p.zcard("zset");
p.lpush("list", "bar"); p.lpush("list", "bar");
Response<List<String>> lrange = p.lrange("list", 0, -1); Response<List<String>> lrange = p.lrange("list", 0, -1);
Response<Map<String, String>> hgetAll = p.hgetAll("hash"); Response<Map<String, String>> hgetAll = p.hgetAll("hash");
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(); p.sync();
assertEquals("foo", string.get()); assertEquals("foo", string.get());
assertEquals("foo", list.get()); assertEquals("foo", list.get());
assertEquals("bar", hash.get()); assertEquals("bar", hash.get());
assertEquals("foo", zset.get().iterator().next()); assertEquals("foo", zset.get().iterator().next());
assertEquals("foo", set.get()); assertEquals("foo", set.get());
assertEquals(false, blist.get()); assertEquals(false, blist.get());
assertEquals(Double.valueOf(2), zincrby.get()); assertEquals(Double.valueOf(2), zincrby.get());
assertEquals(Long.valueOf(1), zcard.get()); assertEquals(Long.valueOf(1), zcard.get());
assertEquals(1, lrange.get().size()); assertEquals(1, lrange.get().size());
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());
} }
@Test @Test
public void pipelineResponseWithData() { public void pipelineResponseWithData() {
jedis.zadd("zset", 1, "foo"); jedis.zadd("zset", 1, "foo");
Pipeline p = jedis.pipelined();
Response<Double> score = p.zscore("zset", "foo");
p.sync();
assertNotNull(score.get()); Pipeline p = jedis.pipelined();
Response<Double> score = p.zscore("zset", "foo");
p.sync();
assertNotNull(score.get());
} }
@Test @Test
public void pipelineBinarySafeHashCommands() { public void pipelineBinarySafeHashCommands() {
jedis.hset("key".getBytes(), "f1".getBytes(), "v111".getBytes()); jedis.hset("key".getBytes(), "f1".getBytes(), "v111".getBytes());
jedis.hset("key".getBytes(), "f22".getBytes(), "v2222".getBytes()); jedis.hset("key".getBytes(), "f22".getBytes(), "v2222".getBytes());
Pipeline p = jedis.pipelined(); Pipeline p = jedis.pipelined();
Response<Map<byte[],byte[]>> fmap = p.hgetAll("key".getBytes()); Response<Map<byte[], byte[]>> fmap = p.hgetAll("key".getBytes());
Response<Set<byte[]>> fkeys = p.hkeys("key".getBytes()); Response<Set<byte[]>> fkeys = p.hkeys("key".getBytes());
Response<List<byte[]>> fordered = p.hmget("key".getBytes(), "f22".getBytes(), "f1".getBytes()); Response<List<byte[]>> fordered = p.hmget("key".getBytes(),
Response<List<byte[]>> fvals = p.hvals("key".getBytes()); "f22".getBytes(), "f1".getBytes());
p.sync(); Response<List<byte[]>> fvals = p.hvals("key".getBytes());
p.sync();
assertNotNull(fmap.get()); assertNotNull(fmap.get());
// we have to do these strange contortions because byte[] is not a very good key // we have to do these strange contortions because byte[] is not a very
// for a java Map. It only works with equality (you need the exact key object to retrieve // good key
// the value) I recommend we switch to using ByteBuffer or something similar: // for a java Map. It only works with equality (you need the exact key
// http://stackoverflow.com/questions/1058149/using-a-byte-array-as-hashmap-key-java // object to retrieve
Map<byte[],byte[]> map = fmap.get(); // the value) I recommend we switch to using ByteBuffer or something
Set<byte[]> mapKeys = map.keySet(); // similar:
Iterator<byte[]> iterMap = mapKeys.iterator(); // http://stackoverflow.com/questions/1058149/using-a-byte-array-as-hashmap-key-java
byte[] firstMapKey = iterMap.next(); Map<byte[], byte[]> map = fmap.get();
byte[] secondMapKey = iterMap.next(); Set<byte[]> mapKeys = map.keySet();
assertFalse(iterMap.hasNext()); Iterator<byte[]> iterMap = mapKeys.iterator();
verifyHasBothValues(firstMapKey, secondMapKey, "f1".getBytes(), "f22".getBytes()); byte[] firstMapKey = iterMap.next();
byte[] firstMapValue = map.get(firstMapKey); byte[] secondMapKey = iterMap.next();
byte[] secondMapValue = map.get(secondMapKey); assertFalse(iterMap.hasNext());
verifyHasBothValues(firstMapValue, secondMapValue, "v111".getBytes(), "v2222".getBytes()); verifyHasBothValues(firstMapKey, secondMapKey, "f1".getBytes(),
"f22".getBytes());
byte[] firstMapValue = map.get(firstMapKey);
byte[] secondMapValue = map.get(secondMapKey);
verifyHasBothValues(firstMapValue, secondMapValue, "v111".getBytes(),
"v2222".getBytes());
assertNotNull(fkeys.get()); assertNotNull(fkeys.get());
Iterator<byte[]> iter = fkeys.get().iterator(); Iterator<byte[]> iter = fkeys.get().iterator();
byte[] firstKey = iter.next(); byte[] firstKey = iter.next();
byte[] secondKey = iter.next(); byte[] secondKey = iter.next();
assertFalse(iter.hasNext()); assertFalse(iter.hasNext());
verifyHasBothValues(firstKey, secondKey, "f1".getBytes(), "f22".getBytes()); verifyHasBothValues(firstKey, secondKey, "f1".getBytes(),
"f22".getBytes());
assertNotNull(fordered.get()); assertNotNull(fordered.get());
assertArrayEquals("v2222".getBytes(), fordered.get().get(0)); assertArrayEquals("v2222".getBytes(), fordered.get().get(0));
assertArrayEquals("v111".getBytes(), fordered.get().get(1)); assertArrayEquals("v111".getBytes(), fordered.get().get(1));
assertNotNull(fvals.get()); assertNotNull(fvals.get());
assertEquals(2, fvals.get().size()); assertEquals(2, fvals.get().size());
byte[] firstValue = fvals.get().get(0); byte[] firstValue = fvals.get().get(0);
byte[] secondValue = fvals.get().get(1); byte[] secondValue = fvals.get().get(1);
verifyHasBothValues(firstValue, secondValue, "v111".getBytes(), "v2222".getBytes()); verifyHasBothValues(firstValue, secondValue, "v111".getBytes(),
"v2222".getBytes());
} }
private void verifyHasBothValues(byte[] firstKey, byte[] secondKey, byte[] value1, byte[] value2) { private void verifyHasBothValues(byte[] firstKey, byte[] secondKey,
assertFalse(Arrays.equals(firstKey, secondKey)); byte[] value1, byte[] value2) {
assertTrue(Arrays.equals(firstKey, value1) || Arrays.equals(firstKey, value2)); assertFalse(Arrays.equals(firstKey, secondKey));
assertTrue(Arrays.equals(secondKey, value1) || Arrays.equals(secondKey, value2)); assertTrue(Arrays.equals(firstKey, value1)
|| Arrays.equals(firstKey, value2));
assertTrue(Arrays.equals(secondKey, value1)
|| Arrays.equals(secondKey, value2));
} }
@Test @Test
public void pipelineSelect() { public void pipelineSelect() {
Pipeline p = jedis.pipelined(); Pipeline p = jedis.pipelined();
p.select(1); p.select(1);
p.sync(); p.sync();
} }
@Test @Test
public void pipelineResponseWithoutData() { public void pipelineResponseWithoutData() {
jedis.zadd("zset", 1, "foo"); jedis.zadd("zset", 1, "foo");
Pipeline p = jedis.pipelined();
Response<Double> score = p.zscore("zset", "bar");
p.sync();
assertNull(score.get()); Pipeline p = jedis.pipelined();
Response<Double> score = p.zscore("zset", "bar");
p.sync();
assertNull(score.get());
} }
@Test(expected = JedisDataException.class) @Test(expected = JedisDataException.class)
public void pipelineResponseWithinPipeline() { public void pipelineResponseWithinPipeline() {
jedis.set("string", "foo"); jedis.set("string", "foo");
Pipeline p = jedis.pipelined(); Pipeline p = jedis.pipelined();
Response<String> string = p.get("string"); Response<String> string = p.get("string");
string.get(); string.get();
p.sync(); p.sync();
} }
@Test @Test
public void pipelineWithPubSub() { public void pipelineWithPubSub() {
Pipeline pipelined = jedis.pipelined(); Pipeline pipelined = jedis.pipelined();
Response<Long> p1 = pipelined.publish("foo", "bar"); Response<Long> p1 = pipelined.publish("foo", "bar");
Response<Long> p2 = pipelined.publish("foo".getBytes(), "bar" Response<Long> p2 = pipelined.publish("foo".getBytes(),
.getBytes()); "bar".getBytes());
pipelined.sync(); pipelined.sync();
assertEquals(0, p1.get().longValue()); assertEquals(0, p1.get().longValue());
assertEquals(0, p2.get().longValue()); assertEquals(0, p2.get().longValue());
} }
@Test @Test
public void canRetrieveUnsetKey() { public void canRetrieveUnsetKey() {
Pipeline p = jedis.pipelined(); Pipeline p = jedis.pipelined();
Response<String> shouldNotExist = p.get(UUID.randomUUID().toString()); Response<String> shouldNotExist = p.get(UUID.randomUUID().toString());
p.sync(); p.sync();
assertNull(shouldNotExist.get()); assertNull(shouldNotExist.get());
}
@Test
public void piplineWithError(){
Pipeline p = jedis.pipelined();
p.set("foo", "bar");
Response<Set<String>> error = p.smembers("foo");
Response<String> r = p.get("foo");
p.sync();
try{
error.get();
fail();
}catch(JedisDataException e){
//that is fine we should be here
}
assertEquals(r.get(), "bar");
} }
@Test @Test
public void multi(){ public void piplineWithError() {
Pipeline p = jedis.pipelined(); Pipeline p = jedis.pipelined();
p.multi(); p.set("foo", "bar");
Response<Long> r1 = p.hincrBy("a", "f1", -1); Response<Set<String>> error = p.smembers("foo");
Response<Long> r2 = p.hincrBy("a", "f1", -2); Response<String> r = p.get("foo");
Response<List<Object>> r3 = p.exec(); p.sync();
List<Object> result = p.syncAndReturnAll(); try {
error.get();
assertEquals(new Long(-1), r1.get()); fail();
assertEquals(new Long(-3), r2.get()); } catch (JedisDataException e) {
// that is fine we should be here
assertEquals(4, result.size()); }
assertEquals(r.get(), "bar");
assertEquals("OK", result.get(0)); }
assertEquals("QUEUED", result.get(1));
assertEquals("QUEUED", result.get(2)); @Test
public void multi() {
//4th result is a list with the results from the multi Pipeline p = jedis.pipelined();
@SuppressWarnings("unchecked") p.multi();
List<Object> multiResult = (List<Object>) result.get(3); Response<Long> r1 = p.hincrBy("a", "f1", -1);
assertEquals(new Long(-1), multiResult.get(0)); Response<Long> r2 = p.hincrBy("a", "f1", -2);
assertEquals(new Long(-3), multiResult.get(1)); Response<List<Object>> r3 = p.exec();
List<Object> result = p.syncAndReturnAll();
assertEquals(new Long(-1), r3.get().get(0));
assertEquals(new Long(-3), r3.get().get(1)); assertEquals(new Long(-1), r1.get());
assertEquals(new Long(-3), r2.get());
assertEquals(4, result.size());
assertEquals("OK", result.get(0));
assertEquals("QUEUED", result.get(1));
assertEquals("QUEUED", result.get(2));
// 4th result is a list with the results from the multi
@SuppressWarnings("unchecked")
List<Object> multiResult = (List<Object>) result.get(3);
assertEquals(new Long(-1), multiResult.get(0));
assertEquals(new Long(-3), multiResult.get(1));
assertEquals(new Long(-1), r3.get().get(0));
assertEquals(new Long(-3), r3.get().get(1));
} }
@Test @Test
public void testDiscardInPipeline() { public void testDiscardInPipeline() {
Pipeline pipeline = jedis.pipelined(); Pipeline pipeline = jedis.pipelined();
pipeline.multi(); pipeline.multi();
pipeline.set("foo", "bar"); pipeline.set("foo", "bar");
Response<String> discard = pipeline.discard(); Response<String> discard = pipeline.discard();
Response<String> get = pipeline.get("foo"); Response<String> get = pipeline.get("foo");
pipeline.sync(); pipeline.sync();
discard.get(); discard.get();
get.get(); get.get();
} }
@Test
public void testEval() {
String script = "return 'success!'";
Pipeline p = jedis.pipelined(); @Test
Response<String> result = p.eval(script); public void testEval() {
p.sync(); String script = "return 'success!'";
assertEquals("success!", result.get()); Pipeline p = jedis.pipelined();
} Response<String> result = p.eval(script);
p.sync();
@Test assertEquals("success!", result.get());
public void testEvalKeyAndArg() { }
String key = "test";
String arg = "3";
String script = "redis.call('INCRBY', KEYS[1], ARGV[1]) redis.call('INCRBY', KEYS[1], ARGV[1])";
Pipeline p = jedis.pipelined(); @Test
p.set(key, "0"); public void testEvalKeyAndArg() {
Response<String> result0 = p.eval(script, Arrays.asList(key), Arrays.asList(arg)); String key = "test";
p.incr(key); String arg = "3";
Response<String> result1 = p.eval(script, Arrays.asList(key), Arrays.asList(arg)); String script = "redis.call('INCRBY', KEYS[1], ARGV[1]) redis.call('INCRBY', KEYS[1], ARGV[1])";
Response<String> result2 = p.get(key);
p.sync();
assertNull(result0.get()); Pipeline p = jedis.pipelined();
assertNull(result1.get()); p.set(key, "0");
assertEquals("13", result2.get()); Response<String> result0 = p.eval(script, Arrays.asList(key),
} Arrays.asList(arg));
p.incr(key);
Response<String> result1 = p.eval(script, Arrays.asList(key),
Arrays.asList(arg));
Response<String> result2 = p.get(key);
p.sync();
@Test assertNull(result0.get());
public void testEvalsha() { assertNull(result1.get());
String script = "return 'success!'"; assertEquals("13", result2.get());
String sha1 = jedis.scriptLoad(script); }
assertTrue(jedis.scriptExists(sha1)); @Test
public void testEvalsha() {
String script = "return 'success!'";
String sha1 = jedis.scriptLoad(script);
Pipeline p = jedis.pipelined(); assertTrue(jedis.scriptExists(sha1));
Response<String> result = p.evalsha(sha1);
p.sync();
assertEquals("success!", result.get()); Pipeline p = jedis.pipelined();
} Response<String> result = p.evalsha(sha1);
p.sync();
@Test assertEquals("success!", result.get());
public void testEvalshaKeyAndArg() { }
String key = "test";
String arg = "3";
String script = "redis.call('INCRBY', KEYS[1], ARGV[1]) redis.call('INCRBY', KEYS[1], ARGV[1])";
String sha1 = jedis.scriptLoad(script);
assertTrue(jedis.scriptExists(sha1)); @Test
public void testEvalshaKeyAndArg() {
String key = "test";
String arg = "3";
String script = "redis.call('INCRBY', KEYS[1], ARGV[1]) redis.call('INCRBY', KEYS[1], ARGV[1])";
String sha1 = jedis.scriptLoad(script);
Pipeline p = jedis.pipelined(); assertTrue(jedis.scriptExists(sha1));
p.set(key, "0");
Response<String> result0 = p.evalsha(sha1, Arrays.asList(key), Arrays.asList(arg));
p.incr(key);
Response<String> result1 = p.evalsha(sha1, Arrays.asList(key), Arrays.asList(arg));
Response<String> result2 = p.get(key);
p.sync();
assertNull(result0.get()); Pipeline p = jedis.pipelined();
assertNull(result1.get()); p.set(key, "0");
assertEquals("13", result2.get()); Response<String> result0 = p.evalsha(sha1, Arrays.asList(key),
} Arrays.asList(arg));
p.incr(key);
Response<String> result1 = p.evalsha(sha1, Arrays.asList(key),
Arrays.asList(arg));
Response<String> result2 = p.get(key);
p.sync();
assertNull(result0.get());
assertNull(result1.get());
assertEquals("13", result2.get());
}
} }

View File

@@ -19,86 +19,86 @@ import redis.clients.util.SafeEncoder;
public class ProtocolTest extends JedisTestBase { public class ProtocolTest extends JedisTestBase {
@Test @Test
public void buildACommand() throws IOException { public void buildACommand() throws IOException {
PipedInputStream pis = new PipedInputStream(); PipedInputStream pis = new PipedInputStream();
BufferedInputStream bis = new BufferedInputStream(pis); BufferedInputStream bis = new BufferedInputStream(pis);
PipedOutputStream pos = new PipedOutputStream(pis); PipedOutputStream pos = new PipedOutputStream(pis);
RedisOutputStream ros = new RedisOutputStream(pos); RedisOutputStream ros = new RedisOutputStream(pos);
Protocol.sendCommand(ros, Protocol.Command.GET, Protocol.sendCommand(ros, Protocol.Command.GET,
"SOMEKEY".getBytes(Protocol.CHARSET)); "SOMEKEY".getBytes(Protocol.CHARSET));
ros.flush(); ros.flush();
pos.close(); pos.close();
String expectedCommand = "*2\r\n$3\r\nGET\r\n$7\r\nSOMEKEY\r\n"; String expectedCommand = "*2\r\n$3\r\nGET\r\n$7\r\nSOMEKEY\r\n";
int b; int b;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
while ((b = bis.read()) != -1) { while ((b = bis.read()) != -1) {
sb.append((char) b); sb.append((char) b);
} }
assertEquals(expectedCommand, sb.toString()); assertEquals(expectedCommand, sb.toString());
} }
@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());
byte[] response = (byte[]) Protocol.read(new RedisInputStream(is)); byte[] response = (byte[]) Protocol.read(new RedisInputStream(is));
assertArrayEquals(SafeEncoder.encode("foobar"), response); assertArrayEquals(SafeEncoder.encode("foobar"), response);
} }
@Test @Test
public void fragmentedBulkReply() { public void fragmentedBulkReply() {
FragmentedByteArrayInputStream fis = new FragmentedByteArrayInputStream( FragmentedByteArrayInputStream fis = new FragmentedByteArrayInputStream(
"$30\r\n012345678901234567890123456789\r\n".getBytes()); "$30\r\n012345678901234567890123456789\r\n".getBytes());
byte[] response = (byte[]) Protocol.read(new RedisInputStream(fis)); byte[] response = (byte[]) Protocol.read(new RedisInputStream(fis));
assertArrayEquals(SafeEncoder.encode("012345678901234567890123456789"), assertArrayEquals(SafeEncoder.encode("012345678901234567890123456789"),
response); response);
} }
@Test @Test
public void nullBulkReply() { public void nullBulkReply() {
InputStream is = new ByteArrayInputStream("$-1\r\n".getBytes()); InputStream is = new ByteArrayInputStream("$-1\r\n".getBytes());
String response = (String) Protocol.read(new RedisInputStream(is)); String response = (String) Protocol.read(new RedisInputStream(is));
assertEquals(null, response); assertEquals(null, response);
} }
@Test @Test
public void singleLineReply() { public void singleLineReply() {
InputStream is = new ByteArrayInputStream("+OK\r\n".getBytes()); InputStream is = new ByteArrayInputStream("+OK\r\n".getBytes());
byte[] response = (byte[]) Protocol.read(new RedisInputStream(is)); byte[] response = (byte[]) Protocol.read(new RedisInputStream(is));
assertArrayEquals(SafeEncoder.encode("OK"), response); assertArrayEquals(SafeEncoder.encode("OK"), response);
} }
@Test @Test
public void integerReply() { public void integerReply() {
InputStream is = new ByteArrayInputStream(":123\r\n".getBytes()); InputStream is = new ByteArrayInputStream(":123\r\n".getBytes());
long response = (Long) Protocol.read(new RedisInputStream(is)); long response = (Long) Protocol.read(new RedisInputStream(is));
assertEquals(123, response); assertEquals(123, response);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Test @Test
public void multiBulkReply() { public void multiBulkReply() {
InputStream is = new ByteArrayInputStream( InputStream is = new ByteArrayInputStream(
"*4\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$5\r\nHello\r\n$5\r\nWorld\r\n" "*4\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$5\r\nHello\r\n$5\r\nWorld\r\n"
.getBytes()); .getBytes());
List<byte[]> response = (List<byte[]>) Protocol List<byte[]> response = (List<byte[]>) Protocol
.read(new RedisInputStream(is)); .read(new RedisInputStream(is));
List<byte[]> expected = new ArrayList<byte[]>(); List<byte[]> expected = new ArrayList<byte[]>();
expected.add(SafeEncoder.encode("foo")); expected.add(SafeEncoder.encode("foo"));
expected.add(SafeEncoder.encode("bar")); expected.add(SafeEncoder.encode("bar"));
expected.add(SafeEncoder.encode("Hello")); expected.add(SafeEncoder.encode("Hello"));
expected.add(SafeEncoder.encode("World")); expected.add(SafeEncoder.encode("World"));
assertEquals(expected, response); assertEquals(expected, response);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Test @Test
public void nullMultiBulkReply() { public void nullMultiBulkReply() {
InputStream is = new ByteArrayInputStream("*-1\r\n".getBytes()); InputStream is = new ByteArrayInputStream("*-1\r\n".getBytes());
List<String> response = (List<String>) Protocol List<String> response = (List<String>) Protocol
.read(new RedisInputStream(is)); .read(new RedisInputStream(is));
assertNull(response); assertNull(response);
} }
} }

View File

@@ -1,9 +1,9 @@
package redis.clients.jedis.tests; package redis.clients.jedis.tests;
import static junit.framework.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -15,6 +15,7 @@ import java.util.UUID;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
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.Response; import redis.clients.jedis.Response;
@@ -24,105 +25,109 @@ import redis.clients.jedis.Tuple;
import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisDataException;
public class ShardedJedisPipelineTest { public class ShardedJedisPipelineTest {
private static HostAndPortUtil.HostAndPort redis1 = HostAndPortUtil
.getRedisServers().get(0); private static HostAndPort redis1 = HostAndPortUtil.getRedisServers()
private static HostAndPortUtil.HostAndPort redis2 = HostAndPortUtil .get(0);
.getRedisServers().get(1); private static HostAndPort redis2 = HostAndPortUtil.getRedisServers()
.get(1);
private ShardedJedis jedis; private ShardedJedis jedis;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
Jedis jedis = new Jedis(redis1.host, redis1.port); Jedis jedis = new Jedis(redis1.getHost(), redis1.getPort());
jedis.auth("foobared"); jedis.auth("foobared");
jedis.flushAll(); jedis.flushAll();
jedis.disconnect(); jedis.disconnect();
jedis = new Jedis(redis2.host, redis2.port); jedis = new Jedis(redis2.getHost(), redis2.getPort());
jedis.auth("foobared"); jedis.auth("foobared");
jedis.flushAll(); jedis.flushAll();
jedis.disconnect(); jedis.disconnect();
JedisShardInfo shardInfo1 = new JedisShardInfo(redis1.getHost(),
redis1.getPort());
JedisShardInfo shardInfo2 = new JedisShardInfo(redis2.getHost(),
redis2.getPort());
shardInfo1.setPassword("foobared");
shardInfo2.setPassword("foobared");
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(shardInfo1);
shards.add(shardInfo2);
this.jedis = new ShardedJedis(shards);
JedisShardInfo shardInfo1 = new JedisShardInfo(redis1.host, redis1.port);
JedisShardInfo shardInfo2 = new JedisShardInfo(redis2.host, redis2.port);
shardInfo1.setPassword("foobared");
shardInfo2.setPassword("foobared");
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(shardInfo1);
shards.add(shardInfo2);
this.jedis = new ShardedJedis(shards);
} }
@Test @Test
public void pipeline() throws UnsupportedEncodingException { public void pipeline() throws UnsupportedEncodingException {
ShardedJedisPipeline p = jedis.pipelined(); ShardedJedisPipeline p = jedis.pipelined();
p.set("foo", "bar"); p.set("foo", "bar");
p.get("foo"); p.get("foo");
List<Object> results = p.syncAndReturnAll(); List<Object> results = p.syncAndReturnAll();
assertEquals(2, results.size()); assertEquals(2, results.size());
assertEquals("OK", results.get(0)); assertEquals("OK", results.get(0));
assertEquals("bar", results.get(1)); assertEquals("bar", results.get(1));
} }
@Test @Test
public void pipelineResponse() { public void pipelineResponse() {
jedis.set("string", "foo"); jedis.set("string", "foo");
jedis.lpush("list", "foo"); jedis.lpush("list", "foo");
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");
ShardedJedisPipeline p = jedis.pipelined(); ShardedJedisPipeline p = jedis.pipelined();
Response<String> string = p.get("string"); Response<String> string = p.get("string");
Response<Long> del = p.del("string"); Response<Long> del = p.del("string");
Response<String> emptyString = p.get("string"); Response<String> emptyString = p.get("string");
Response<String> list = p.lpop("list"); Response<String> list = p.lpop("list");
Response<String> hash = p.hget("hash", "foo"); Response<String> hash = p.hget("hash", "foo");
Response<Set<String>> zset = p.zrange("zset", 0, -1); Response<Set<String>> zset = p.zrange("zset", 0, -1);
Response<String> set = p.spop("set"); Response<String> set = p.spop("set");
Response<Boolean> blist = p.exists("list"); Response<Boolean> blist = p.exists("list");
Response<Double> zincrby = p.zincrby("zset", 1, "foo"); Response<Double> zincrby = p.zincrby("zset", 1, "foo");
Response<Long> zcard = p.zcard("zset"); Response<Long> zcard = p.zcard("zset");
p.lpush("list", "bar"); p.lpush("list", "bar");
Response<List<String>> lrange = p.lrange("list", 0, -1); Response<List<String>> lrange = p.lrange("list", 0, -1);
Response<Map<String, String>> hgetAll = p.hgetAll("hash"); Response<Map<String, String>> hgetAll = p.hgetAll("hash");
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(); p.sync();
assertEquals("foo", string.get()); assertEquals("foo", string.get());
assertEquals(Long.valueOf(1), del.get()); assertEquals(Long.valueOf(1), del.get());
assertNull(emptyString.get()); assertNull(emptyString.get());
assertEquals("foo", list.get()); assertEquals("foo", list.get());
assertEquals("bar", hash.get()); assertEquals("bar", hash.get());
assertEquals("foo", zset.get().iterator().next()); assertEquals("foo", zset.get().iterator().next());
assertEquals("foo", set.get()); assertEquals("foo", set.get());
assertFalse(blist.get()); assertFalse(blist.get());
assertEquals(Double.valueOf(2), zincrby.get()); assertEquals(Double.valueOf(2), zincrby.get());
assertEquals(Long.valueOf(1), zcard.get()); assertEquals(Long.valueOf(1), zcard.get());
assertEquals(1, lrange.get().size()); assertEquals(1, lrange.get().size());
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());
} }
@Test(expected = JedisDataException.class) @Test(expected = JedisDataException.class)
public void pipelineResponseWithinPipeline() { public void pipelineResponseWithinPipeline() {
jedis.set("string", "foo"); jedis.set("string", "foo");
ShardedJedisPipeline p = jedis.pipelined(); ShardedJedisPipeline p = jedis.pipelined();
Response<String> string = p.get("string"); Response<String> string = p.get("string");
string.get(); string.get();
p.sync(); p.sync();
} }
@Test @Test
public void canRetrieveUnsetKey() { public void canRetrieveUnsetKey() {
ShardedJedisPipeline p = jedis.pipelined(); ShardedJedisPipeline p = jedis.pipelined();
Response<String> shouldNotExist = p.get(UUID.randomUUID().toString()); Response<String> shouldNotExist = p.get(UUID.randomUUID().toString());
p.sync(); p.sync();
assertNull(shouldNotExist.get()); assertNull(shouldNotExist.get());
} }
} }

View File

@@ -5,222 +5,230 @@ import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
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.ShardedJedisPool; import redis.clients.jedis.ShardedJedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
public class ShardedJedisPoolTest extends Assert { public class ShardedJedisPoolTest extends Assert {
private static HostAndPort redis1 = HostAndPortUtil.getRedisServers() private static HostAndPort redis1 = HostAndPortUtil.getRedisServers()
.get(0); .get(0);
private static HostAndPort redis2 = HostAndPortUtil.getRedisServers() private static HostAndPort redis2 = HostAndPortUtil.getRedisServers()
.get(1); .get(1);
private List<JedisShardInfo> shards; private List<JedisShardInfo> shards;
@Before @Before
public void startUp() { public void startUp() {
shards = new ArrayList<JedisShardInfo>(); shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo(redis1.host, redis1.port)); shards.add(new JedisShardInfo(redis1.getHost(), redis1.getPort()));
shards.add(new JedisShardInfo(redis2.host, redis2.port)); shards.add(new JedisShardInfo(redis2.getHost(), redis2.getPort()));
shards.get(0).setPassword("foobared"); shards.get(0).setPassword("foobared");
shards.get(1).setPassword("foobared"); shards.get(1).setPassword("foobared");
Jedis j = new Jedis(shards.get(0)); Jedis j = new Jedis(shards.get(0));
j.connect(); j.connect();
j.flushAll(); j.flushAll();
j.disconnect(); j.disconnect();
j = new Jedis(shards.get(1)); j = new Jedis(shards.get(1));
j.connect(); j.connect();
j.flushAll(); j.flushAll();
j.disconnect(); j.disconnect();
} }
@Test @Test
public void checkConnections() { public void checkConnections() {
ShardedJedisPool pool = new ShardedJedisPool(new Config(), shards); ShardedJedisPool pool = new ShardedJedisPool(
ShardedJedis jedis = pool.getResource(); new GenericObjectPoolConfig(), shards);
jedis.set("foo", "bar"); ShardedJedis jedis = pool.getResource();
assertEquals("bar", jedis.get("foo")); jedis.set("foo", "bar");
pool.returnResource(jedis); assertEquals("bar", jedis.get("foo"));
pool.destroy(); pool.returnResource(jedis);
pool.destroy();
} }
@Test @Test
public void checkConnectionWithDefaultPort() { public void checkConnectionWithDefaultPort() {
ShardedJedisPool pool = new ShardedJedisPool(new Config(), shards); ShardedJedisPool pool = new ShardedJedisPool(
ShardedJedis jedis = pool.getResource(); new GenericObjectPoolConfig(), shards);
jedis.set("foo", "bar"); ShardedJedis jedis = pool.getResource();
assertEquals("bar", jedis.get("foo")); jedis.set("foo", "bar");
pool.returnResource(jedis); assertEquals("bar", jedis.get("foo"));
pool.destroy(); pool.returnResource(jedis);
pool.destroy();
} }
@Test @Test
public void checkJedisIsReusedWhenReturned() { public void checkJedisIsReusedWhenReturned() {
ShardedJedisPool pool = new ShardedJedisPool(new Config(), shards); ShardedJedisPool pool = new ShardedJedisPool(
ShardedJedis jedis = pool.getResource(); new GenericObjectPoolConfig(), shards);
jedis.set("foo", "0"); ShardedJedis jedis = pool.getResource();
pool.returnResource(jedis); jedis.set("foo", "0");
pool.returnResource(jedis);
jedis = pool.getResource(); jedis = pool.getResource();
jedis.incr("foo"); jedis.incr("foo");
pool.returnResource(jedis); pool.returnResource(jedis);
pool.destroy(); pool.destroy();
} }
@Test @Test
public void checkPoolRepairedWhenJedisIsBroken() { public void checkPoolRepairedWhenJedisIsBroken() {
ShardedJedisPool pool = new ShardedJedisPool(new Config(), shards); ShardedJedisPool pool = new ShardedJedisPool(
ShardedJedis jedis = pool.getResource(); new GenericObjectPoolConfig(), shards);
jedis.disconnect(); ShardedJedis jedis = pool.getResource();
pool.returnBrokenResource(jedis); jedis.disconnect();
pool.returnBrokenResource(jedis);
jedis = pool.getResource(); jedis = pool.getResource();
jedis.incr("foo"); jedis.incr("foo");
pool.returnResource(jedis); pool.returnResource(jedis);
pool.destroy(); pool.destroy();
} }
@Test(expected = JedisConnectionException.class) @Test(expected = JedisConnectionException.class)
public void checkPoolOverflow() { public void checkPoolOverflow() {
Config config = new Config(); GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.maxActive = 1; config.setMaxTotal(1);
config.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_FAIL; config.setBlockWhenExhausted(false);
ShardedJedisPool pool = new ShardedJedisPool(config, shards); ShardedJedisPool pool = new ShardedJedisPool(config, shards);
ShardedJedis jedis = pool.getResource(); ShardedJedis jedis = pool.getResource();
jedis.set("foo", "0"); jedis.set("foo", "0");
ShardedJedis newJedis = pool.getResource(); ShardedJedis newJedis = pool.getResource();
newJedis.incr("foo"); newJedis.incr("foo");
} }
@Test @Test
public void shouldNotShareInstances() { public void shouldNotShareInstances() {
Config config = new Config(); GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.maxActive = 2; config.setMaxTotal(2);
config.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_FAIL;
ShardedJedisPool pool = new ShardedJedisPool(config, shards); ShardedJedisPool pool = new ShardedJedisPool(config, shards);
ShardedJedis j1 = pool.getResource(); ShardedJedis j1 = pool.getResource();
ShardedJedis j2 = pool.getResource(); ShardedJedis j2 = pool.getResource();
assertNotSame(j1.getShard("foo"), j2.getShard("foo")); assertNotSame(j1.getShard("foo"), j2.getShard("foo"));
} }
@Test @Test
public void checkFailedJedisServer() { public void checkFailedJedisServer() {
ShardedJedisPool pool = new ShardedJedisPool(new Config(), shards); ShardedJedisPool pool = new ShardedJedisPool(
ShardedJedis jedis = pool.getResource(); new GenericObjectPoolConfig(), shards);
jedis.incr("foo"); ShardedJedis jedis = pool.getResource();
pool.returnResource(jedis); jedis.incr("foo");
pool.destroy(); pool.returnResource(jedis);
pool.destroy();
} }
@Test @Test
public void shouldReturnActiveShardsWhenOneGoesOffline() { public void shouldReturnActiveShardsWhenOneGoesOffline() {
Config redisConfig = new Config(); GenericObjectPoolConfig redisConfig = new GenericObjectPoolConfig();
redisConfig.testOnBorrow = false; redisConfig.setTestOnBorrow(false);
ShardedJedisPool pool = new ShardedJedisPool(redisConfig, shards); ShardedJedisPool pool = new ShardedJedisPool(redisConfig, shards);
ShardedJedis jedis = pool.getResource(); ShardedJedis jedis = pool.getResource();
// fill the shards // fill the shards
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
jedis.set("a-test-" + i, "0"); jedis.set("a-test-" + i, "0");
} }
pool.returnResource(jedis); pool.returnResource(jedis);
// check quantity for each shard // check quantity for each shard
Jedis j = new Jedis(shards.get(0)); Jedis j = new Jedis(shards.get(0));
j.connect(); j.connect();
Long c1 = j.dbSize(); Long c1 = j.dbSize();
j.disconnect(); j.disconnect();
j = new Jedis(shards.get(1)); j = new Jedis(shards.get(1));
j.connect(); j.connect();
Long c2 = j.dbSize(); Long c2 = j.dbSize();
j.disconnect(); j.disconnect();
// shutdown shard 2 and check thay the pool returns an instance with c1 // shutdown shard 2 and check thay the pool returns an instance with c1
// items on one shard // items on one shard
// alter shard 1 and recreate pool // alter shard 1 and recreate pool
pool.destroy(); pool.destroy();
shards.set(1, new JedisShardInfo("nohost", 1234)); shards.set(1, new JedisShardInfo("nohost", 1234));
pool = new ShardedJedisPool(redisConfig, shards); pool = new ShardedJedisPool(redisConfig, shards);
jedis = pool.getResource(); jedis = pool.getResource();
Long actual = Long.valueOf(0); Long actual = Long.valueOf(0);
Long fails = Long.valueOf(0); Long fails = Long.valueOf(0);
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
try { try {
jedis.get("a-test-" + i); jedis.get("a-test-" + i);
actual++; actual++;
} catch (RuntimeException e) { } catch (RuntimeException e) {
fails++; fails++;
} }
} }
pool.returnResource(jedis); pool.returnResource(jedis);
pool.destroy(); pool.destroy();
assertEquals(actual, c1); assertEquals(actual, c1);
assertEquals(fails, c2); assertEquals(fails, c2);
} }
@Test @Test
public void startWithUrlString() { public void startWithUrlString() {
Jedis j = new Jedis("localhost", 6380); Jedis j = new Jedis("localhost", 6380);
j.auth("foobared"); j.auth("foobared");
j.set("foo", "bar"); j.set("foo", "bar");
j = new Jedis("localhost", 6379); j = new Jedis("localhost", 6379);
j.auth("foobared"); j.auth("foobared");
j.set("foo", "bar"); j.set("foo", "bar");
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo("redis://:foobared@localhost:6380")); shards.add(new JedisShardInfo("redis://:foobared@localhost:6380"));
shards.add(new JedisShardInfo("redis://:foobared@localhost:6379")); shards.add(new JedisShardInfo("redis://:foobared@localhost:6379"));
Config redisConfig = new Config(); GenericObjectPoolConfig redisConfig = new GenericObjectPoolConfig();
ShardedJedisPool pool = new ShardedJedisPool(redisConfig, shards); ShardedJedisPool pool = new ShardedJedisPool(redisConfig, shards);
Jedis[] jedises = pool.getResource().getAllShards().toArray(new Jedis[2]); Jedis[] jedises = pool.getResource().getAllShards()
.toArray(new Jedis[2]);
Jedis jedis = jedises[0]; Jedis jedis = jedises[0];
assertEquals("PONG", jedis.ping()); assertEquals("PONG", jedis.ping());
assertEquals("bar", jedis.get("foo")); assertEquals("bar", jedis.get("foo"));
jedis = jedises[1]; jedis = jedises[1];
assertEquals("PONG", jedis.ping()); assertEquals("PONG", jedis.ping());
assertEquals("bar", jedis.get("foo")); assertEquals("bar", jedis.get("foo"));
} }
@Test @Test
public void startWithUrl() throws URISyntaxException { public void startWithUrl() throws URISyntaxException {
Jedis j = new Jedis("localhost", 6380); Jedis j = new Jedis("localhost", 6380);
j.auth("foobared"); j.auth("foobared");
j.set("foo", "bar"); j.set("foo", "bar");
j = new Jedis("localhost", 6379); j = new Jedis("localhost", 6379);
j.auth("foobared"); j.auth("foobared");
j.set("foo", "bar"); j.set("foo", "bar");
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo(new URI("redis://:foobared@localhost:6380"))); shards.add(new JedisShardInfo(new URI(
shards.add(new JedisShardInfo(new URI("redis://:foobared@localhost:6379"))); "redis://:foobared@localhost:6380")));
shards.add(new JedisShardInfo(new URI(
Config redisConfig = new Config(); "redis://:foobared@localhost:6379")));
GenericObjectPoolConfig redisConfig = new GenericObjectPoolConfig();
ShardedJedisPool pool = new ShardedJedisPool(redisConfig, shards); ShardedJedisPool pool = new ShardedJedisPool(redisConfig, shards);
Jedis[] jedises = pool.getResource().getAllShards().toArray(new Jedis[2]); Jedis[] jedises = pool.getResource().getAllShards()
.toArray(new Jedis[2]);
Jedis jedis = jedises[0]; Jedis jedis = jedises[0];
assertEquals("PONG", jedis.ping()); assertEquals("PONG", jedis.ping());
assertEquals("bar", jedis.get("foo")); assertEquals("bar", jedis.get("foo"));
jedis = jedises[1]; jedis = jedises[1];
assertEquals("PONG", jedis.ping()); assertEquals("PONG", jedis.ping());
assertEquals("bar", jedis.get("foo")); assertEquals("bar", jedis.get("foo"));

View File

@@ -6,298 +6,300 @@ import java.util.List;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
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.Protocol; import redis.clients.jedis.Protocol;
import redis.clients.jedis.ShardedJedis; import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPipeline; import redis.clients.jedis.ShardedJedisPipeline;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
import redis.clients.util.Hashing; import redis.clients.util.Hashing;
import redis.clients.util.SafeEncoder; import redis.clients.util.SafeEncoder;
import redis.clients.util.Sharded; import redis.clients.util.Sharded;
public class ShardedJedisTest extends Assert { public class ShardedJedisTest extends Assert {
private static HostAndPort redis1 = HostAndPortUtil.getRedisServers() private static HostAndPort redis1 = HostAndPortUtil.getRedisServers()
.get(0); .get(0);
private static HostAndPort redis2 = HostAndPortUtil.getRedisServers() private static HostAndPort redis2 = HostAndPortUtil.getRedisServers()
.get(1); .get(1);
private List<String> getKeysDifferentShard(ShardedJedis jedis) { private List<String> getKeysDifferentShard(ShardedJedis jedis) {
List<String> ret = new ArrayList<String>(); List<String> ret = new ArrayList<String>();
JedisShardInfo first = jedis.getShardInfo("a0"); JedisShardInfo first = jedis.getShardInfo("a0");
ret.add("a0"); ret.add("a0");
for (int i = 1; i < 100; ++i) { for (int i = 1; i < 100; ++i) {
JedisShardInfo actual = jedis.getShardInfo("a" + i); JedisShardInfo actual = jedis.getShardInfo("a" + i);
if (actual != first) { if (actual != first) {
ret.add("a" + i); ret.add("a" + i);
break; break;
} }
} }
return ret; return ret;
} }
@Test @Test
public void checkSharding() { public void checkSharding() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo(redis1.host, redis1.port)); shards.add(new JedisShardInfo(redis1.getHost(), redis1.getPort()));
shards.add(new JedisShardInfo(redis2.host, redis2.port)); shards.add(new JedisShardInfo(redis2.getHost(), redis2.getPort()));
ShardedJedis jedis = new ShardedJedis(shards); ShardedJedis jedis = new ShardedJedis(shards);
List<String> keys = getKeysDifferentShard(jedis); List<String> keys = getKeysDifferentShard(jedis);
JedisShardInfo s1 = jedis.getShardInfo(keys.get(0)); JedisShardInfo s1 = jedis.getShardInfo(keys.get(0));
JedisShardInfo s2 = jedis.getShardInfo(keys.get(1)); JedisShardInfo s2 = jedis.getShardInfo(keys.get(1));
assertNotSame(s1, s2); assertNotSame(s1, s2);
} }
@Test @Test
public void trySharding() { public void trySharding() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
JedisShardInfo si = new JedisShardInfo(redis1.host, redis1.port); JedisShardInfo si = new JedisShardInfo(redis1.getHost(),
si.setPassword("foobared"); redis1.getPort());
shards.add(si); si.setPassword("foobared");
si = new JedisShardInfo(redis2.host, redis2.port); shards.add(si);
si.setPassword("foobared"); si = new JedisShardInfo(redis2.getHost(), redis2.getPort());
shards.add(si); si.setPassword("foobared");
ShardedJedis jedis = new ShardedJedis(shards); shards.add(si);
jedis.set("a", "bar"); ShardedJedis jedis = new ShardedJedis(shards);
JedisShardInfo s1 = jedis.getShardInfo("a"); jedis.set("a", "bar");
jedis.set("b", "bar1"); JedisShardInfo s1 = jedis.getShardInfo("a");
JedisShardInfo s2 = jedis.getShardInfo("b"); jedis.set("b", "bar1");
jedis.disconnect(); JedisShardInfo s2 = jedis.getShardInfo("b");
jedis.disconnect();
Jedis j = new Jedis(s1.getHost(), s1.getPort()); Jedis j = new Jedis(s1.getHost(), s1.getPort());
j.auth("foobared"); j.auth("foobared");
assertEquals("bar", j.get("a")); assertEquals("bar", j.get("a"));
j.disconnect(); j.disconnect();
j = new Jedis(s2.getHost(), s2.getPort()); j = new Jedis(s2.getHost(), s2.getPort());
j.auth("foobared"); j.auth("foobared");
assertEquals("bar1", j.get("b")); assertEquals("bar1", j.get("b"));
j.disconnect(); j.disconnect();
} }
@Test @Test
public void tryShardingWithMurmure() { public void tryShardingWithMurmure() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
JedisShardInfo si = new JedisShardInfo(redis1.host, redis1.port); JedisShardInfo si = new JedisShardInfo(redis1.getHost(),
si.setPassword("foobared"); redis1.getPort());
shards.add(si); si.setPassword("foobared");
si = new JedisShardInfo(redis2.host, redis2.port); shards.add(si);
si.setPassword("foobared"); si = new JedisShardInfo(redis2.getHost(), redis2.getPort());
shards.add(si); si.setPassword("foobared");
ShardedJedis jedis = new ShardedJedis(shards, Hashing.MURMUR_HASH); shards.add(si);
jedis.set("a", "bar"); ShardedJedis jedis = new ShardedJedis(shards, Hashing.MURMUR_HASH);
JedisShardInfo s1 = jedis.getShardInfo("a"); jedis.set("a", "bar");
jedis.set("b", "bar1"); JedisShardInfo s1 = jedis.getShardInfo("a");
JedisShardInfo s2 = jedis.getShardInfo("b"); jedis.set("b", "bar1");
jedis.disconnect(); JedisShardInfo s2 = jedis.getShardInfo("b");
jedis.disconnect();
Jedis j = new Jedis(s1.getHost(), s1.getPort()); Jedis j = new Jedis(s1.getHost(), s1.getPort());
j.auth("foobared"); j.auth("foobared");
assertEquals("bar", j.get("a")); assertEquals("bar", j.get("a"));
j.disconnect(); j.disconnect();
j = new Jedis(s2.getHost(), s2.getPort()); j = new Jedis(s2.getHost(), s2.getPort());
j.auth("foobared"); j.auth("foobared");
assertEquals("bar1", j.get("b")); assertEquals("bar1", j.get("b"));
j.disconnect(); j.disconnect();
} }
@Test @Test
public void checkKeyTags() { public void checkKeyTags() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo(redis1.host, redis1.port)); shards.add(new JedisShardInfo(redis1.getHost(), redis1.getPort()));
shards.add(new JedisShardInfo(redis2.host, redis2.port)); shards.add(new JedisShardInfo(redis2.getHost(), redis2.getPort()));
ShardedJedis jedis = new ShardedJedis(shards, ShardedJedis jedis = new ShardedJedis(shards,
ShardedJedis.DEFAULT_KEY_TAG_PATTERN); ShardedJedis.DEFAULT_KEY_TAG_PATTERN);
assertEquals(jedis.getKeyTag("foo"), "foo"); assertEquals(jedis.getKeyTag("foo"), "foo");
assertEquals(jedis.getKeyTag("foo{bar}"), "bar"); assertEquals(jedis.getKeyTag("foo{bar}"), "bar");
assertEquals(jedis.getKeyTag("foo{bar}}"), "bar"); // default pattern is assertEquals(jedis.getKeyTag("foo{bar}}"), "bar"); // default pattern is
// non greedy // non greedy
assertEquals(jedis.getKeyTag("{bar}foo"), "bar"); // Key tag may appear assertEquals(jedis.getKeyTag("{bar}foo"), "bar"); // Key tag may appear
// anywhere // anywhere
assertEquals(jedis.getKeyTag("f{bar}oo"), "bar"); // Key tag may appear assertEquals(jedis.getKeyTag("f{bar}oo"), "bar"); // Key tag may appear
// anywhere // anywhere
JedisShardInfo s1 = jedis.getShardInfo("abc{bar}"); JedisShardInfo s1 = jedis.getShardInfo("abc{bar}");
JedisShardInfo s2 = jedis.getShardInfo("foo{bar}"); JedisShardInfo s2 = jedis.getShardInfo("foo{bar}");
assertSame(s1, s2); assertSame(s1, s2);
List<String> keys = getKeysDifferentShard(jedis); List<String> keys = getKeysDifferentShard(jedis);
JedisShardInfo s3 = jedis.getShardInfo(keys.get(0)); JedisShardInfo s3 = jedis.getShardInfo(keys.get(0));
JedisShardInfo s4 = jedis.getShardInfo(keys.get(1)); JedisShardInfo s4 = jedis.getShardInfo(keys.get(1));
assertNotSame(s3, s4); assertNotSame(s3, s4);
ShardedJedis jedis2 = new ShardedJedis(shards); ShardedJedis jedis2 = new ShardedJedis(shards);
assertEquals(jedis2.getKeyTag("foo"), "foo"); assertEquals(jedis2.getKeyTag("foo"), "foo");
assertNotSame(jedis2.getKeyTag("foo{bar}"), "bar"); assertNotSame(jedis2.getKeyTag("foo{bar}"), "bar");
JedisShardInfo s5 = jedis2.getShardInfo(keys.get(0) + "{bar}"); JedisShardInfo s5 = jedis2.getShardInfo(keys.get(0) + "{bar}");
JedisShardInfo s6 = jedis2.getShardInfo(keys.get(1) + "{bar}"); JedisShardInfo s6 = jedis2.getShardInfo(keys.get(1) + "{bar}");
assertNotSame(s5, s6); assertNotSame(s5, s6);
} }
@Test @Test
public void shardedPipeline() { public void shardedPipeline() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo(redis1.host, redis1.port)); shards.add(new JedisShardInfo(redis1.getHost(), redis1.getPort()));
shards.add(new JedisShardInfo(redis2.host, redis2.port)); shards.add(new JedisShardInfo(redis2.getHost(), redis2.getPort()));
shards.get(0).setPassword("foobared"); shards.get(0).setPassword("foobared");
shards.get(1).setPassword("foobared"); shards.get(1).setPassword("foobared");
ShardedJedis jedis = new ShardedJedis(shards); ShardedJedis jedis = new ShardedJedis(shards);
final List<String> keys = getKeysDifferentShard(jedis); final List<String> keys = getKeysDifferentShard(jedis);
jedis.set(keys.get(0), "a"); jedis.set(keys.get(0), "a");
jedis.set(keys.get(1), "b"); jedis.set(keys.get(1), "b");
assertNotSame(jedis.getShard(keys.get(0)), jedis.getShard(keys.get(1))); assertNotSame(jedis.getShard(keys.get(0)), jedis.getShard(keys.get(1)));
List<Object> results = jedis.pipelined(new ShardedJedisPipeline() { List<Object> results = jedis.pipelined(new ShardedJedisPipeline() {
public void execute() { public void execute() {
get(keys.get(0)); get(keys.get(0));
get(keys.get(1)); get(keys.get(1));
} }
}); });
List<Object> expected = new ArrayList<Object>(2); List<Object> expected = new ArrayList<Object>(2);
expected.add(SafeEncoder.encode("a")); expected.add(SafeEncoder.encode("a"));
expected.add(SafeEncoder.encode("b")); expected.add(SafeEncoder.encode("b"));
assertEquals(2, results.size()); assertEquals(2, results.size());
assertArrayEquals(SafeEncoder.encode("a"), (byte[]) results.get(0)); assertArrayEquals(SafeEncoder.encode("a"), (byte[]) results.get(0));
assertArrayEquals(SafeEncoder.encode("b"), (byte[]) results.get(1)); assertArrayEquals(SafeEncoder.encode("b"), (byte[]) results.get(1));
} }
@Test @Test
public void testMD5Sharding() { public void testMD5Sharding() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(3); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(3);
shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT)); shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT));
shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 1)); shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 1));
shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 2)); shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 2));
Sharded<Jedis, JedisShardInfo> sharded = new Sharded<Jedis, JedisShardInfo>( Sharded<Jedis, JedisShardInfo> sharded = new Sharded<Jedis, JedisShardInfo>(
shards, Hashing.MD5); shards, Hashing.MD5);
int shard_6379 = 0; int shard_6379 = 0;
int shard_6380 = 0; int shard_6380 = 0;
int shard_6381 = 0; int shard_6381 = 0;
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
JedisShardInfo jedisShardInfo = sharded.getShardInfo(Integer JedisShardInfo jedisShardInfo = sharded.getShardInfo(Integer
.toString(i)); .toString(i));
switch (jedisShardInfo.getPort()) { switch (jedisShardInfo.getPort()) {
case 6379: case 6379:
shard_6379++; shard_6379++;
break; break;
case 6380: case 6380:
shard_6380++; shard_6380++;
break; break;
case 6381: case 6381:
shard_6381++; shard_6381++;
break; break;
default: default:
fail("Attempting to use a non-defined shard!!:" fail("Attempting to use a non-defined shard!!:"
+ jedisShardInfo); + jedisShardInfo);
break; break;
} }
} }
assertTrue(shard_6379 > 300 && shard_6379 < 400); assertTrue(shard_6379 > 300 && shard_6379 < 400);
assertTrue(shard_6380 > 300 && shard_6380 < 400); assertTrue(shard_6380 > 300 && shard_6380 < 400);
assertTrue(shard_6381 > 300 && shard_6381 < 400); assertTrue(shard_6381 > 300 && shard_6381 < 400);
} }
@Test @Test
public void testMurmurSharding() { public void testMurmurSharding() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(3); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(3);
shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT)); shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT));
shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 1)); shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 1));
shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 2)); shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 2));
Sharded<Jedis, JedisShardInfo> sharded = new Sharded<Jedis, JedisShardInfo>( Sharded<Jedis, JedisShardInfo> sharded = new Sharded<Jedis, JedisShardInfo>(
shards, Hashing.MURMUR_HASH); shards, Hashing.MURMUR_HASH);
int shard_6379 = 0; int shard_6379 = 0;
int shard_6380 = 0; int shard_6380 = 0;
int shard_6381 = 0; int shard_6381 = 0;
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
JedisShardInfo jedisShardInfo = sharded.getShardInfo(Integer JedisShardInfo jedisShardInfo = sharded.getShardInfo(Integer
.toString(i)); .toString(i));
switch (jedisShardInfo.getPort()) { switch (jedisShardInfo.getPort()) {
case 6379: case 6379:
shard_6379++; shard_6379++;
break; break;
case 6380: case 6380:
shard_6380++; shard_6380++;
break; break;
case 6381: case 6381:
shard_6381++; shard_6381++;
break; break;
default: default:
fail("Attempting to use a non-defined shard!!:" fail("Attempting to use a non-defined shard!!:"
+ jedisShardInfo); + jedisShardInfo);
break; break;
} }
} }
assertTrue(shard_6379 > 300 && shard_6379 < 400); assertTrue(shard_6379 > 300 && shard_6379 < 400);
assertTrue(shard_6380 > 300 && shard_6380 < 400); assertTrue(shard_6380 > 300 && shard_6380 < 400);
assertTrue(shard_6381 > 300 && shard_6381 < 400); assertTrue(shard_6381 > 300 && shard_6381 < 400);
} }
@Test @Test
public void testMasterSlaveShardingConsistency() { public void testMasterSlaveShardingConsistency() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(3); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(3);
shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT)); shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT));
shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 1)); shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 1));
shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 2)); shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 2));
Sharded<Jedis, JedisShardInfo> sharded = new Sharded<Jedis, JedisShardInfo>( Sharded<Jedis, JedisShardInfo> sharded = new Sharded<Jedis, JedisShardInfo>(
shards, Hashing.MURMUR_HASH); shards, Hashing.MURMUR_HASH);
List<JedisShardInfo> otherShards = new ArrayList<JedisShardInfo>(3); List<JedisShardInfo> otherShards = new ArrayList<JedisShardInfo>(3);
otherShards.add(new JedisShardInfo("otherhost", Protocol.DEFAULT_PORT)); otherShards.add(new JedisShardInfo("otherhost", Protocol.DEFAULT_PORT));
otherShards.add(new JedisShardInfo("otherhost", otherShards.add(new JedisShardInfo("otherhost",
Protocol.DEFAULT_PORT + 1)); Protocol.DEFAULT_PORT + 1));
otherShards.add(new JedisShardInfo("otherhost", otherShards.add(new JedisShardInfo("otherhost",
Protocol.DEFAULT_PORT + 2)); Protocol.DEFAULT_PORT + 2));
Sharded<Jedis, JedisShardInfo> sharded2 = new Sharded<Jedis, JedisShardInfo>( Sharded<Jedis, JedisShardInfo> sharded2 = new Sharded<Jedis, JedisShardInfo>(
otherShards, Hashing.MURMUR_HASH); otherShards, Hashing.MURMUR_HASH);
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
JedisShardInfo jedisShardInfo = sharded.getShardInfo(Integer JedisShardInfo jedisShardInfo = sharded.getShardInfo(Integer
.toString(i)); .toString(i));
JedisShardInfo jedisShardInfo2 = sharded2.getShardInfo(Integer JedisShardInfo jedisShardInfo2 = sharded2.getShardInfo(Integer
.toString(i)); .toString(i));
assertEquals(shards.indexOf(jedisShardInfo), otherShards assertEquals(shards.indexOf(jedisShardInfo),
.indexOf(jedisShardInfo2)); otherShards.indexOf(jedisShardInfo2));
} }
} }
@Test @Test
public void testMasterSlaveShardingConsistencyWithShardNaming() { public void testMasterSlaveShardingConsistencyWithShardNaming() {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(3); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(3);
shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT, shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT,
"HOST1:1234")); "HOST1:1234"));
shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 1, shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 1,
"HOST2:1234")); "HOST2:1234"));
shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 2, shards.add(new JedisShardInfo("localhost", Protocol.DEFAULT_PORT + 2,
"HOST3:1234")); "HOST3:1234"));
Sharded<Jedis, JedisShardInfo> sharded = new Sharded<Jedis, JedisShardInfo>( Sharded<Jedis, JedisShardInfo> sharded = new Sharded<Jedis, JedisShardInfo>(
shards, Hashing.MURMUR_HASH); shards, Hashing.MURMUR_HASH);
List<JedisShardInfo> otherShards = new ArrayList<JedisShardInfo>(3); List<JedisShardInfo> otherShards = new ArrayList<JedisShardInfo>(3);
otherShards.add(new JedisShardInfo("otherhost", Protocol.DEFAULT_PORT, otherShards.add(new JedisShardInfo("otherhost", Protocol.DEFAULT_PORT,
"HOST2:1234")); "HOST2:1234"));
otherShards.add(new JedisShardInfo("otherhost", otherShards.add(new JedisShardInfo("otherhost",
Protocol.DEFAULT_PORT + 1, "HOST3:1234")); Protocol.DEFAULT_PORT + 1, "HOST3:1234"));
otherShards.add(new JedisShardInfo("otherhost", otherShards.add(new JedisShardInfo("otherhost",
Protocol.DEFAULT_PORT + 2, "HOST1:1234")); Protocol.DEFAULT_PORT + 2, "HOST1:1234"));
Sharded<Jedis, JedisShardInfo> sharded2 = new Sharded<Jedis, JedisShardInfo>( Sharded<Jedis, JedisShardInfo> sharded2 = new Sharded<Jedis, JedisShardInfo>(
otherShards, Hashing.MURMUR_HASH); otherShards, Hashing.MURMUR_HASH);
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
JedisShardInfo jedisShardInfo = sharded.getShardInfo(Integer JedisShardInfo jedisShardInfo = sharded.getShardInfo(Integer
.toString(i)); .toString(i));
JedisShardInfo jedisShardInfo2 = sharded2.getShardInfo(Integer JedisShardInfo jedisShardInfo2 = sharded2.getShardInfo(Integer
.toString(i)); .toString(i));
assertEquals(jedisShardInfo.getName(), jedisShardInfo2.getName()); assertEquals(jedisShardInfo.getName(), jedisShardInfo2.getName());
} }
} }
} }

View File

@@ -4,17 +4,17 @@ import java.io.IOException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Calendar; import java.util.Calendar;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.tests.HostAndPortUtil; import redis.clients.jedis.tests.HostAndPortUtil;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
public class GetSetBenchmark { public class GetSetBenchmark {
private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0); private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);
private static final int TOTAL_OPERATIONS = 100000; private static final int TOTAL_OPERATIONS = 100000;
public static void main(String[] args) throws UnknownHostException, public static void main(String[] args) throws UnknownHostException,
IOException { IOException {
Jedis jedis = new Jedis(hnp.host, hnp.port); Jedis jedis = new Jedis(hnp.getHost(), hnp.getPort());
jedis.connect(); jedis.connect();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.flushAll(); jedis.flushAll();

View File

@@ -7,11 +7,11 @@ import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
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.tests.HostAndPortUtil; import redis.clients.jedis.tests.HostAndPortUtil;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
public class HashingBenchmark { public class HashingBenchmark {
private static HostAndPort hnp1 = HostAndPortUtil.getRedisServers().get(0); private static HostAndPort hnp1 = HostAndPortUtil.getRedisServers().get(0);
@@ -19,32 +19,33 @@ public class HashingBenchmark {
private static final int TOTAL_OPERATIONS = 100000; private static final int TOTAL_OPERATIONS = 100000;
public static void main(String[] args) throws UnknownHostException, public static void main(String[] args) throws UnknownHostException,
IOException { IOException {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
JedisShardInfo shard = new JedisShardInfo(hnp1.host, hnp1.port); JedisShardInfo shard = new JedisShardInfo(hnp1.getHost(),
shard.setPassword("foobared"); hnp1.getPort());
shards.add(shard); shard.setPassword("foobared");
shard = new JedisShardInfo(hnp2.host, hnp2.port); shards.add(shard);
shard.setPassword("foobared"); shard = new JedisShardInfo(hnp2.getHost(), hnp2.getPort());
shards.add(shard); shard.setPassword("foobared");
ShardedJedis jedis = new ShardedJedis(shards); shards.add(shard);
Collection<Jedis> allShards = jedis.getAllShards(); ShardedJedis jedis = new ShardedJedis(shards);
for (Jedis j : allShards) { Collection<Jedis> allShards = jedis.getAllShards();
j.flushAll(); for (Jedis j : allShards) {
} j.flushAll();
}
long begin = Calendar.getInstance().getTimeInMillis(); long begin = Calendar.getInstance().getTimeInMillis();
for (int n = 0; n <= TOTAL_OPERATIONS; n++) { for (int n = 0; n <= TOTAL_OPERATIONS; n++) {
String key = "foo" + n; String key = "foo" + n;
jedis.set(key, "bar" + n); jedis.set(key, "bar" + n);
jedis.get(key); jedis.get(key);
} }
long elapsed = Calendar.getInstance().getTimeInMillis() - begin; long elapsed = Calendar.getInstance().getTimeInMillis() - begin;
jedis.disconnect(); jedis.disconnect();
System.out.println(((1000 * 2 * TOTAL_OPERATIONS) / elapsed) + " ops"); System.out.println(((1000 * 2 * TOTAL_OPERATIONS) / elapsed) + " ops");
} }
} }

View File

@@ -4,36 +4,36 @@ import java.io.IOException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Calendar; import java.util.Calendar;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline; import redis.clients.jedis.Pipeline;
import redis.clients.jedis.tests.HostAndPortUtil; import redis.clients.jedis.tests.HostAndPortUtil;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
public class PipelinedGetSetBenchmark { public class PipelinedGetSetBenchmark {
private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0); private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);
private static final int TOTAL_OPERATIONS = 200000; private static final int TOTAL_OPERATIONS = 200000;
public static void main(String[] args) throws UnknownHostException, public static void main(String[] args) throws UnknownHostException,
IOException { IOException {
Jedis jedis = new Jedis(hnp.host, hnp.port); Jedis jedis = new Jedis(hnp.getHost(), hnp.getPort());
jedis.connect(); jedis.connect();
jedis.auth("foobared"); jedis.auth("foobared");
jedis.flushAll(); jedis.flushAll();
long begin = Calendar.getInstance().getTimeInMillis(); long begin = Calendar.getInstance().getTimeInMillis();
Pipeline p = jedis.pipelined(); Pipeline p = jedis.pipelined();
for (int n = 0; n <= TOTAL_OPERATIONS; n++) { for (int n = 0; n <= TOTAL_OPERATIONS; n++) {
String key = "foo" + n; String key = "foo" + n;
p.set(key, "bar" + n); p.set(key, "bar" + n);
p.get(key); p.get(key);
} }
p.sync(); p.sync();
long elapsed = Calendar.getInstance().getTimeInMillis() - begin; long elapsed = Calendar.getInstance().getTimeInMillis() - begin;
jedis.disconnect(); jedis.disconnect();
System.out.println(((1000 * 2 * TOTAL_OPERATIONS) / elapsed) + " ops"); System.out.println(((1000 * 2 * TOTAL_OPERATIONS) / elapsed) + " ops");
} }
} }

View File

@@ -4,60 +4,61 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.pool.impl.GenericObjectPool.Config; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPool;
import redis.clients.jedis.tests.HostAndPortUtil; import redis.clients.jedis.tests.HostAndPortUtil;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
public class PoolBenchmark { public class PoolBenchmark {
private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0); private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);
private static final int TOTAL_OPERATIONS = 100000; private static final int TOTAL_OPERATIONS = 100000;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Jedis j = new Jedis(hnp.host, hnp.port); Jedis j = new Jedis(hnp.getHost(), hnp.getPort());
j.connect(); j.connect();
j.auth("foobared"); j.auth("foobared");
j.flushAll(); j.flushAll();
j.quit(); j.quit();
j.disconnect(); j.disconnect();
long t = System.currentTimeMillis(); long t = System.currentTimeMillis();
// withoutPool(); // withoutPool();
withPool(); withPool();
long elapsed = System.currentTimeMillis() - t; long elapsed = System.currentTimeMillis() - t;
System.out.println(((1000 * 2 * TOTAL_OPERATIONS) / elapsed) + " ops"); System.out.println(((1000 * 2 * TOTAL_OPERATIONS) / elapsed) + " ops");
} }
private static void withPool() throws Exception { private static void withPool() throws Exception {
final JedisPool pool = new JedisPool(new Config(), hnp.host, hnp.port, final JedisPool pool = new JedisPool(new GenericObjectPoolConfig(),
2000, "foobared"); hnp.getHost(), hnp.getPort(), 2000, "foobared");
List<Thread> tds = new ArrayList<Thread>(); List<Thread> tds = new ArrayList<Thread>();
final AtomicInteger ind = new AtomicInteger(); final AtomicInteger ind = new AtomicInteger();
for (int i = 0; i < 50; i++) { for (int i = 0; i < 50; i++) {
Thread hj = new Thread(new Runnable() { Thread hj = new Thread(new Runnable() {
public void run() { public void run() {
for (int i = 0; (i = ind.getAndIncrement()) < TOTAL_OPERATIONS;) { for (int i = 0; (i = ind.getAndIncrement()) < TOTAL_OPERATIONS;) {
try { try {
Jedis j = pool.getResource(); Jedis j = pool.getResource();
final String key = "foo" + i; final String key = "foo" + i;
j.set(key, key); j.set(key, key);
j.get(key); j.get(key);
pool.returnResource(j); pool.returnResource(j);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
}); });
tds.add(hj); tds.add(hj);
hj.start(); hj.start();
} }
for (Thread t : tds) for (Thread t : tds)
t.join(); t.join();
pool.destroy();
pool.destroy();
} }
} }

Some files were not shown because too many files have changed in this diff Show More