Skip to content

Commit 5dd5e05

Browse files
sheinbergonHeartSaVioR
authored andcommitted
Implemented a HashTag version of SCAN methods for Redis Cluster (#1335)
Based on http://www.paluch.biz/blog/162-iterate-over-all-keys-in-a-redis-cluster.html. This implementation supports scanning for "Hash Tag" prefixed based patterns ( i.e. {TAG}* ) *NOTE* Changes on Jungtaek Lim <kabhwan@gmail.com> * Fix conflicts * Moved scan() interface from JedisClusterCommands to MultiKeyJedisClusterCommands * JedisClusterCommands is not available for 2.9 * since we treat scan as multikey operation, it should be applied to master, too
1 parent ca468e5 commit 5dd5e05

File tree

9 files changed

+121
-284
lines changed

9 files changed

+121
-284
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*.iml
33
*.ipr
44
*.iws
5+
nb*
56
.project
67
.settings/
78
.gradle/

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import java.util.List;
1515
import java.util.Map;
1616
import java.util.Set;
17+
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
18+
import redis.clients.util.JedisClusterHashTagUtil;
1719

1820
public class BinaryJedisCluster implements BasicCommands, BinaryJedisClusterCommands,
1921
MultiKeyBinaryJedisClusterCommands, JedisClusterBinaryScriptingCommands, Closeable {
@@ -1951,7 +1953,30 @@ public List<GeoRadiusResponse> execute(Jedis connection) {
19511953
}
19521954
}.runBinary(key);
19531955
}
1956+
1957+
@Override
1958+
public ScanResult<byte[]> scan(final byte[] cursor, final ScanParams params) {
19541959

1960+
String matchPattern = null;
1961+
1962+
if (params == null || (matchPattern = params.match()) == null || matchPattern.isEmpty()) {
1963+
throw new IllegalArgumentException(BinaryJedisCluster.class.getSimpleName() + " only supports SCAN commands with non-empty MATCH patterns");
1964+
}
1965+
1966+
if (JedisClusterHashTagUtil.isClusterCompliantMatchPattern(matchPattern)) {
1967+
1968+
return new JedisClusterCommand< ScanResult<byte[]>>(connectionHandler,
1969+
maxRedirections) {
1970+
@Override
1971+
public ScanResult<byte[]> execute(Jedis connection) {
1972+
return connection.scan(cursor, params);
1973+
}
1974+
}.runBinary(SafeEncoder.encode(matchPattern));
1975+
} else {
1976+
throw new IllegalArgumentException(BinaryJedisCluster.class.getSimpleName() + " only supports SCAN commands with MATCH patterns containing hash-tags ( curly-brackets enclosed strings )");
1977+
}
1978+
}
1979+
19551980
@Override
19561981
public ScanResult<Map.Entry<byte[], byte[]>> hscan(final byte[] key, final byte[] cursor) {
19571982
return new JedisClusterCommand<ScanResult<Map.Entry<byte[], byte[]>>>(connectionHandler,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ List<GeoRadiusResponse> georadius(byte[] key, double longitude, double latitude,
261261
List<GeoRadiusResponse> georadiusByMember(byte[] key, byte[] member, double radius, GeoUnit unit,
262262
GeoRadiusParam param);
263263

264+
ScanResult<byte[]> scan(final byte[] cursor, final ScanParams params);
265+
264266
ScanResult<Map.Entry<byte[], byte[]>> hscan(byte[] key, byte[] cursor);
265267

266268
ScanResult<Map.Entry<byte[], byte[]>> hscan(byte[] key, byte[] cursor, ScanParams params);

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import java.util.Set;
1414

1515
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
16+
import redis.clients.util.JedisClusterHashTagUtil;
17+
import redis.clients.util.SafeEncoder;
1618

1719
public class JedisCluster extends BinaryJedisCluster implements JedisCommands,
1820
MultiKeyJedisClusterCommands, JedisClusterScriptingCommands {
@@ -1236,6 +1238,29 @@ public Long execute(Jedis connection) {
12361238
}.run(key);
12371239
}
12381240

1241+
@Override
1242+
public ScanResult<String> scan(final String cursor, final ScanParams params) {
1243+
1244+
String matchPattern = null;
1245+
1246+
if (params == null || (matchPattern = params.match()) == null || matchPattern.isEmpty()) {
1247+
throw new IllegalArgumentException(JedisCluster.class.getSimpleName() + " only supports SCAN commands with non-empty MATCH patterns");
1248+
}
1249+
1250+
if (JedisClusterHashTagUtil.isClusterCompliantMatchPattern(matchPattern)) {
1251+
1252+
return new JedisClusterCommand< ScanResult<String>>(connectionHandler,
1253+
maxRedirections) {
1254+
@Override
1255+
public ScanResult<String> execute(Jedis connection) {
1256+
return connection.scan(cursor, params);
1257+
}
1258+
}.runBinary(SafeEncoder.encode(matchPattern));
1259+
} else {
1260+
throw new IllegalArgumentException(JedisCluster.class.getSimpleName() + " only supports SCAN commands with MATCH patterns containing hash-tags ( curly-brackets enclosed strings )");
1261+
}
1262+
}
1263+
12391264
@Override
12401265
public Long bitpos(final String key, final boolean value) {
12411266
return new JedisClusterCommand<Long>(connectionHandler, maxRedirections) {

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

Lines changed: 0 additions & 268 deletions
This file was deleted.

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,6 @@ public interface MultiKeyJedisClusterCommands {
6363
String pfmerge(final String destkey, final String... sourcekeys);
6464

6565
long pfcount(final String... keys);
66+
67+
ScanResult<String> scan(final String cursor, final ScanParams params);
6668
}

0 commit comments

Comments
 (0)