diff --git a/src/main/java/redis/clients/jedis/BinaryClient.java b/src/main/java/redis/clients/jedis/BinaryClient.java index e0e095b..e2bad8f 100644 --- a/src/main/java/redis/clients/jedis/BinaryClient.java +++ b/src/main/java/redis/clients/jedis/BinaryClient.java @@ -846,11 +846,20 @@ public class BinaryClient extends Connection { toByteArray(offset), toByteArray(count)); } + public void zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min) { + sendCommand(ZREVRANGEBYLEX, key, max, min); + } + + public void zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min, + final int offset, final int count) { + sendCommand(ZREVRANGEBYLEX, key, max, min, LIMIT.raw, + toByteArray(offset), toByteArray(count)); + } + public void zremrangeByLex(byte[] key, byte[] min, byte[] max) { sendCommand(ZREMRANGEBYLEX, key, min, max); } - public void save() { sendCommand(SAVE); } diff --git a/src/main/java/redis/clients/jedis/BinaryJedis.java b/src/main/java/redis/clients/jedis/BinaryJedis.java index 4166b11..6734bb5 100644 --- a/src/main/java/redis/clients/jedis/BinaryJedis.java +++ b/src/main/java/redis/clients/jedis/BinaryJedis.java @@ -2847,6 +2847,21 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, client.zrangeByLex(key, min, max, offset, count); return new LinkedHashSet(client.getBinaryMultiBulkReply()); } + + @Override + public Set zrevrangeByLex(byte[] key, byte[] max, byte[] min) { + checkIsInMulti(); + client.zrevrangeByLex(key, max, min); + return new LinkedHashSet(client.getBinaryMultiBulkReply()); + } + + @Override + public Set zrevrangeByLex(byte[] key, byte[] max, byte[] min, + int offset, int count) { + checkIsInMulti(); + client.zrevrangeByLex(key, max, min, offset, count); + return new LinkedHashSet(client.getBinaryMultiBulkReply()); + } @Override public Long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) { @@ -3630,4 +3645,5 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, } return new ScanResult(newcursor, results); } + } diff --git a/src/main/java/redis/clients/jedis/BinaryJedisCommands.java b/src/main/java/redis/clients/jedis/BinaryJedisCommands.java index 164c71c..bf71ecf 100644 --- a/src/main/java/redis/clients/jedis/BinaryJedisCommands.java +++ b/src/main/java/redis/clients/jedis/BinaryJedisCommands.java @@ -203,6 +203,11 @@ public interface BinaryJedisCommands { Set zrangeByLex(final byte[] key, final byte[] min, final byte[] max, int offset, int count); + + Set zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min); + + Set zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min, + int offset, int count); Long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max); diff --git a/src/main/java/redis/clients/jedis/BinaryRedisPipeline.java b/src/main/java/redis/clients/jedis/BinaryRedisPipeline.java index 98ebc73..d74b4c9 100644 --- a/src/main/java/redis/clients/jedis/BinaryRedisPipeline.java +++ b/src/main/java/redis/clients/jedis/BinaryRedisPipeline.java @@ -214,6 +214,11 @@ public interface BinaryRedisPipeline { Response> zrangeByLex(final byte[] key, final byte[] max, final byte[] min, int offset, int count); + Response> zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min); + + Response> zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min, + int offset, int count); + Response zremrangeByLex(final byte[] key, final byte[] min, final byte[] max); Response bitcount(byte[] key); diff --git a/src/main/java/redis/clients/jedis/BinaryShardedJedis.java b/src/main/java/redis/clients/jedis/BinaryShardedJedis.java index c34a574..ab0b4bc 100644 --- a/src/main/java/redis/clients/jedis/BinaryShardedJedis.java +++ b/src/main/java/redis/clients/jedis/BinaryShardedJedis.java @@ -509,6 +509,19 @@ public class BinaryShardedJedis extends Sharded Jedis j = getShard(key); return j.zrangeByLex(key, min, max, offset, count); } + + @Override + public Set zrevrangeByLex(byte[] key, byte[] max, byte[] min) { + Jedis j = getShard(key); + return j.zrevrangeByLex(key, max, min); + } + + @Override + public Set zrevrangeByLex(byte[] key, byte[] max, byte[] min, + int offset, int count) { + Jedis j = getShard(key); + return j.zrevrangeByLex(key, max, min, offset, count); + } @Override public Long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) { diff --git a/src/main/java/redis/clients/jedis/Client.java b/src/main/java/redis/clients/jedis/Client.java index 1501297..4863ac6 100644 --- a/src/main/java/redis/clients/jedis/Client.java +++ b/src/main/java/redis/clients/jedis/Client.java @@ -600,6 +600,16 @@ public class Client extends BinaryClient implements Commands { zrangeByLex(SafeEncoder.encode(key), SafeEncoder.encode(min), SafeEncoder.encode(max), offset, count); } + + public void zrevrangeByLex(String key, String max, String min) { + zrevrangeByLex(SafeEncoder.encode(key), SafeEncoder.encode(max), SafeEncoder.encode(min)); + } + + public void zrevrangeByLex(String key, String max, String min, int offset, + int count) { + zrevrangeByLex(SafeEncoder.encode(key), SafeEncoder.encode(max), SafeEncoder.encode(min), + offset, count); + } public void zremrangeByLex(final String key, final String min, final String max) { zremrangeByLex(SafeEncoder.encode(key), SafeEncoder.encode(min), SafeEncoder.encode(max)); @@ -1003,4 +1013,5 @@ public void clusterSetSlotStable(final int slot) { public void clusterSlots() { cluster(Protocol.CLUSTER_SLOTS); } + } diff --git a/src/main/java/redis/clients/jedis/Jedis.java b/src/main/java/redis/clients/jedis/Jedis.java index c93bb9a..ec0bb65 100644 --- a/src/main/java/redis/clients/jedis/Jedis.java +++ b/src/main/java/redis/clients/jedis/Jedis.java @@ -2646,6 +2646,21 @@ public class Jedis extends BinaryJedis implements JedisCommands, return new LinkedHashSet(client.getMultiBulkReply()); } + @Override + public Set zrevrangeByLex(String key, String max, String min) { + checkIsInMulti(); + client.zrevrangeByLex(key, max, min); + return new LinkedHashSet(client.getMultiBulkReply()); + } + + @Override + public Set zrevrangeByLex(String key, String max, String min, + int offset, int count) { + checkIsInMulti(); + client.zrevrangeByLex(key, max, min, offset, count); + return new LinkedHashSet(client.getMultiBulkReply()); + } + @Override public Long zremrangeByLex(final String key, final String min, final String max) { checkIsInMulti(); @@ -3507,6 +3522,6 @@ public class Jedis extends BinaryJedis implements JedisCommands, final List multiBulkReply = client.getMultiBulkReply(); client.rollbackTimeout(); return multiBulkReply; - } + } } diff --git a/src/main/java/redis/clients/jedis/JedisCluster.java b/src/main/java/redis/clients/jedis/JedisCluster.java index a5a888e..36c39fe 100644 --- a/src/main/java/redis/clients/jedis/JedisCluster.java +++ b/src/main/java/redis/clients/jedis/JedisCluster.java @@ -1157,6 +1157,29 @@ public class JedisCluster implements JedisCommands, BasicCommands, Closeable { }.run(key); } + @Override + public Set zrevrangeByLex(final String key, final String max, final String min) { + return new JedisClusterCommand>(connectionHandler, timeout, + maxRedirections) { + @Override + public Set execute(Jedis connection) { + return connection.zrevrangeByLex(key, max, min); + } + }.run(key); + } + + @Override + public Set zrevrangeByLex(final String key, final String max, final String min, + final int offset, final int count) { + return new JedisClusterCommand>(connectionHandler, timeout, + maxRedirections) { + @Override + public Set execute(Jedis connection) { + return connection.zrevrangeByLex(key, max, min, offset, count); + } + }.run(key); + } + @Override public Long zremrangeByLex(final String key, final String min, final String max) { return new JedisClusterCommand(connectionHandler, timeout, @@ -1577,4 +1600,5 @@ public class JedisCluster implements JedisCommands, BasicCommands, Closeable { } }.run(null); } + } diff --git a/src/main/java/redis/clients/jedis/JedisCommands.java b/src/main/java/redis/clients/jedis/JedisCommands.java index 17dc08d..e4f9fc2 100644 --- a/src/main/java/redis/clients/jedis/JedisCommands.java +++ b/src/main/java/redis/clients/jedis/JedisCommands.java @@ -201,6 +201,11 @@ public interface JedisCommands { Set zrangeByLex(final String key, final String min, final String max, final int offset, final int count); + + Set zrevrangeByLex(final String key, final String max, final String min); + + Set zrevrangeByLex(final String key, final String max, final String min, + final int offset, final int count); Long zremrangeByLex(final String key, final String min, final String max); diff --git a/src/main/java/redis/clients/jedis/PipelineBase.java b/src/main/java/redis/clients/jedis/PipelineBase.java index 58d06e1..bf6d6cb 100644 --- a/src/main/java/redis/clients/jedis/PipelineBase.java +++ b/src/main/java/redis/clients/jedis/PipelineBase.java @@ -1064,6 +1064,32 @@ abstract class PipelineBase extends Queable implements BinaryRedisPipeline, return getResponse(BuilderFactory.STRING_ZSET); } + @Override + public Response> zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min) { + getClient(key).zrevrangeByLex(key, max, min); + return getResponse(BuilderFactory.BYTE_ARRAY_ZSET); + } + + @Override + public Response> zrevrangeByLex(final String key, final String max, final String min) { + getClient(key).zrevrangeByLex(key, max, min); + return getResponse(BuilderFactory.STRING_ZSET); + } + + @Override + public Response> zrevrangeByLex(final byte[] key, final byte[] max, + final byte[] min, final int offset, final int count) { + getClient(key).zrevrangeByLex(key, max, min, offset, count); + return getResponse(BuilderFactory.BYTE_ARRAY_ZSET); + } + + @Override + public Response> zrevrangeByLex(final String key, final String max, + final String min, final int offset, final int count) { + getClient(key).zrevrangeByLex(key, max, min, offset, count); + return getResponse(BuilderFactory.STRING_ZSET); + } + @Override public Response zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) { getClient(key).zremrangeByLex(key, min, max); diff --git a/src/main/java/redis/clients/jedis/Protocol.java b/src/main/java/redis/clients/jedis/Protocol.java index 52ab151..cda3983 100644 --- a/src/main/java/redis/clients/jedis/Protocol.java +++ b/src/main/java/redis/clients/jedis/Protocol.java @@ -219,7 +219,7 @@ public final class Protocol { } public static enum Command { - PING, SET, GET, QUIT, EXISTS, DEL, TYPE, FLUSHDB, KEYS, RANDOMKEY, RENAME, RENAMENX, RENAMEX, DBSIZE, EXPIRE, EXPIREAT, TTL, SELECT, MOVE, FLUSHALL, GETSET, MGET, SETNX, SETEX, MSET, MSETNX, DECRBY, DECR, INCRBY, INCR, APPEND, SUBSTR, HSET, HGET, HSETNX, HMSET, HMGET, HINCRBY, HEXISTS, HDEL, HLEN, HKEYS, HVALS, HGETALL, RPUSH, LPUSH, LLEN, LRANGE, LTRIM, LINDEX, LSET, LREM, LPOP, RPOP, RPOPLPUSH, SADD, SMEMBERS, SREM, SPOP, SMOVE, SCARD, SISMEMBER, SINTER, SINTERSTORE, SUNION, SUNIONSTORE, SDIFF, SDIFFSTORE, SRANDMEMBER, ZADD, ZRANGE, ZREM, ZINCRBY, ZRANK, ZREVRANK, ZREVRANGE, ZCARD, ZSCORE, MULTI, DISCARD, EXEC, WATCH, UNWATCH, SORT, BLPOP, BRPOP, AUTH, SUBSCRIBE, PUBLISH, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBSUB, ZCOUNT, ZRANGEBYSCORE, ZREVRANGEBYSCORE, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZUNIONSTORE, ZINTERSTORE, ZLEXCOUNT, ZRANGEBYLEX, ZREMRANGEBYLEX, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, SHUTDOWN, INFO, MONITOR, SLAVEOF, CONFIG, STRLEN, SYNC, LPUSHX, PERSIST, RPUSHX, ECHO, LINSERT, DEBUG, BRPOPLPUSH, SETBIT, GETBIT, BITPOS, SETRANGE, GETRANGE, EVAL, EVALSHA, SCRIPT, SLOWLOG, OBJECT, BITCOUNT, BITOP, SENTINEL, DUMP, RESTORE, PEXPIRE, PEXPIREAT, PTTL, INCRBYFLOAT, PSETEX, CLIENT, TIME, MIGRATE, HINCRBYFLOAT, SCAN, HSCAN, SSCAN, ZSCAN, WAIT, CLUSTER, ASKING, PFADD, PFCOUNT, PFMERGE; + PING, SET, GET, QUIT, EXISTS, DEL, TYPE, FLUSHDB, KEYS, RANDOMKEY, RENAME, RENAMENX, RENAMEX, DBSIZE, EXPIRE, EXPIREAT, TTL, SELECT, MOVE, FLUSHALL, GETSET, MGET, SETNX, SETEX, MSET, MSETNX, DECRBY, DECR, INCRBY, INCR, APPEND, SUBSTR, HSET, HGET, HSETNX, HMSET, HMGET, HINCRBY, HEXISTS, HDEL, HLEN, HKEYS, HVALS, HGETALL, RPUSH, LPUSH, LLEN, LRANGE, LTRIM, LINDEX, LSET, LREM, LPOP, RPOP, RPOPLPUSH, SADD, SMEMBERS, SREM, SPOP, SMOVE, SCARD, SISMEMBER, SINTER, SINTERSTORE, SUNION, SUNIONSTORE, SDIFF, SDIFFSTORE, SRANDMEMBER, ZADD, ZRANGE, ZREM, ZINCRBY, ZRANK, ZREVRANK, ZREVRANGE, ZCARD, ZSCORE, MULTI, DISCARD, EXEC, WATCH, UNWATCH, SORT, BLPOP, BRPOP, AUTH, SUBSCRIBE, PUBLISH, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBSUB, ZCOUNT, ZRANGEBYSCORE, ZREVRANGEBYSCORE, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZUNIONSTORE, ZINTERSTORE, ZLEXCOUNT, ZRANGEBYLEX, ZREVRANGEBYLEX, ZREMRANGEBYLEX, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, SHUTDOWN, INFO, MONITOR, SLAVEOF, CONFIG, STRLEN, SYNC, LPUSHX, PERSIST, RPUSHX, ECHO, LINSERT, DEBUG, BRPOPLPUSH, SETBIT, GETBIT, BITPOS, SETRANGE, GETRANGE, EVAL, EVALSHA, SCRIPT, SLOWLOG, OBJECT, BITCOUNT, BITOP, SENTINEL, DUMP, RESTORE, PEXPIRE, PEXPIREAT, PTTL, INCRBYFLOAT, PSETEX, CLIENT, TIME, MIGRATE, HINCRBYFLOAT, SCAN, HSCAN, SSCAN, ZSCAN, WAIT, CLUSTER, ASKING, PFADD, PFCOUNT, PFMERGE; public final byte[] raw; diff --git a/src/main/java/redis/clients/jedis/RedisPipeline.java b/src/main/java/redis/clients/jedis/RedisPipeline.java index 63e3257..54d498e 100644 --- a/src/main/java/redis/clients/jedis/RedisPipeline.java +++ b/src/main/java/redis/clients/jedis/RedisPipeline.java @@ -192,6 +192,11 @@ public interface RedisPipeline { Response> zrangeByLex(final String key, final String max, final String min, final int offset, final int count); + Response> zrevrangeByLex(final String key, final String max, final String min); + + Response> zrevrangeByLex(final String key, final String max, final String min, + final int offset, final int count); + Response zremrangeByLex(final String key, final String start, final String end); Response bitcount(String key); diff --git a/src/main/java/redis/clients/jedis/ShardedJedis.java b/src/main/java/redis/clients/jedis/ShardedJedis.java index 333a63e..fda6ec6 100644 --- a/src/main/java/redis/clients/jedis/ShardedJedis.java +++ b/src/main/java/redis/clients/jedis/ShardedJedis.java @@ -1,6 +1,7 @@ package redis.clients.jedis; import java.io.Closeable; + import redis.clients.jedis.BinaryClient.LIST_POSITION; import redis.clients.util.Hashing; @@ -558,7 +559,18 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands, final int offset, final int count) { return getShard(key).zrangeByLex(key, min, max, offset, count); } + + @Override + public Set zrevrangeByLex(String key, String max, String min) { + return getShard(key).zrevrangeByLex(key, max, min); + } + @Override + public Set zrevrangeByLex(String key, String max, String min, + int offset, int count) { + return getShard(key).zrevrangeByLex(key, max, min, offset, count); + } + @Override public Long zremrangeByLex(final String key, final String min, final String max) { return getShard(key).zremrangeByLex(key, min, max); @@ -638,5 +650,5 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands, Jedis j = getShard(key); return j.pfcount(key); } - + } diff --git a/src/test/java/redis/clients/jedis/tests/commands/SortedSetCommandsTest.java b/src/test/java/redis/clients/jedis/tests/commands/SortedSetCommandsTest.java index 42ad7e0..24557ef 100644 --- a/src/test/java/redis/clients/jedis/tests/commands/SortedSetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/tests/commands/SortedSetCommandsTest.java @@ -137,6 +137,48 @@ public class SortedSetCommandsTest extends JedisCommandTestBase { // with LIMIT assertEquals(bExpected, jedis.zrangeByLex(bfoo, bLexMinusInf, bLexPlusInf, 0, 2)); } + + @Test + public void zrevrangeByLex() { + jedis.zadd("foo", 1, "aa"); + jedis.zadd("foo", 1, "c"); + jedis.zadd("foo", 1, "bb"); + jedis.zadd("foo", 1, "d"); + + Set expected = new LinkedHashSet(); + expected.add("c"); + expected.add("bb"); + + // exclusive aa ~ inclusive c + assertEquals(expected, jedis.zrevrangeByLex("foo", "[c", "(aa")); + + expected.clear(); + expected.add("c"); + expected.add("bb"); + + // with LIMIT + assertEquals(expected, jedis.zrevrangeByLex("foo", "+", "-", 1, 2)); + } + + @Test + public void zrevrangeByLexBinary() { + // binary + jedis.zadd(bfoo, 1, ba); + jedis.zadd(bfoo, 1, bc); + jedis.zadd(bfoo, 1, bb); + + Set bExpected = new LinkedHashSet(); + bExpected.add(bb); + + assertEquals(bExpected, jedis.zrevrangeByLex(bfoo, bExclusiveC, bInclusiveB)); + + bExpected.clear(); + bExpected.add(bb); + bExpected.add(ba); + + // with LIMIT + assertEquals(bExpected, jedis.zrevrangeByLex(bfoo, bLexPlusInf, bLexMinusInf, 0, 2)); + } @Test public void zrevrange() {