From 409740f06cd2375c9164f66c84b217546ef38aac Mon Sep 17 00:00:00 2001 From: Jungtaek Lim Date: Tue, 22 Apr 2014 23:39:37 +0900 Subject: [PATCH] Support Sorted Set with LEX commands * new commands : ZLEXCOUNT, ZRANGEBYLEX, ZREMRANGEBYLEX ** added commands to Jedis, ShardedJedis, JedisCluster, PipelineBase with Binary / Normal(String) ** description links *** http://redis.io/commands/zlexcount *** http://redis.io/commands/zrangebylex *** http://redis.io/commands/zremrangebylex ** Unit test included --- .../redis/clients/jedis/BinaryClient.java | 20 +++ .../java/redis/clients/jedis/BinaryJedis.java | 29 +++++ .../clients/jedis/BinaryJedisCommands.java | 9 ++ .../clients/jedis/BinaryRedisPipeline.java | 9 ++ .../clients/jedis/BinaryShardedJedis.java | 26 ++++ src/main/java/redis/clients/jedis/Client.java | 18 +++ src/main/java/redis/clients/jedis/Jedis.java | 30 +++++ .../redis/clients/jedis/JedisCluster.java | 46 +++++++ .../redis/clients/jedis/JedisCommands.java | 9 ++ .../redis/clients/jedis/PipelineBase.java | 50 ++++++++ .../java/redis/clients/jedis/Protocol.java | 2 +- .../redis/clients/jedis/RedisPipeline.java | 9 ++ .../redis/clients/jedis/ShardedJedis.java | 22 ++++ .../tests/commands/SortedSetCommandsTest.java | 119 +++++++++++++++++- 14 files changed, 396 insertions(+), 2 deletions(-) diff --git a/src/main/java/redis/clients/jedis/BinaryClient.java b/src/main/java/redis/clients/jedis/BinaryClient.java index 2377665..a921b06 100644 --- a/src/main/java/redis/clients/jedis/BinaryClient.java +++ b/src/main/java/redis/clients/jedis/BinaryClient.java @@ -16,6 +16,7 @@ import static redis.clients.jedis.Protocol.Keyword.WITHSCORES; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.Map.Entry; import redis.clients.jedis.Protocol.Command; @@ -827,6 +828,25 @@ public class BinaryClient extends Connection { args.addAll(params.getParams()); sendCommand(ZINTERSTORE, args.toArray(new byte[args.size()][])); } + + public void zlexcount(final byte[] key, final byte[] min, final byte[] max) { + sendCommand(ZLEXCOUNT, key, min, max); + } + + public void zrangeByLex(final byte[] key, final byte[] min, final byte[] max) { + sendCommand(ZRANGEBYLEX, key, min, max); + } + + public void zrangeByLex(final byte[] key, final byte[] min, final byte[] max, + final int offset, final int count) { + sendCommand(ZRANGEBYLEX, key, min, max, 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 eba466f..d061389 100644 --- a/src/main/java/redis/clients/jedis/BinaryJedis.java +++ b/src/main/java/redis/clients/jedis/BinaryJedis.java @@ -2732,6 +2732,35 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, return client.getIntegerReply(); } + @Override + public Long zlexcount(final byte[] key, final byte[] min, final byte[] max) { + checkIsInMulti(); + client.zlexcount(key, min, max); + return client.getIntegerReply(); + } + + @Override + public Set zrangeByLex(final byte[] key, final byte[] min, final byte[] max) { + checkIsInMulti(); + client.zrangeByLex(key, min, max); + return new LinkedHashSet(client.getBinaryMultiBulkReply()); + } + + @Override + public Set zrangeByLex(final byte[] key, final byte[] min, final byte[] max, + final int offset, final int count) { + checkIsInMulti(); + client.zrangeByLex(key, min, max, offset, count); + return new LinkedHashSet(client.getBinaryMultiBulkReply()); + } + + @Override + public Long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) { + checkIsInMulti(); + client.zremrangeByLex(key, min, max); + return client.getIntegerReply(); + } + /** * Synchronously save the DB on disk. *

diff --git a/src/main/java/redis/clients/jedis/BinaryJedisCommands.java b/src/main/java/redis/clients/jedis/BinaryJedisCommands.java index b229f97..3920c67 100644 --- a/src/main/java/redis/clients/jedis/BinaryJedisCommands.java +++ b/src/main/java/redis/clients/jedis/BinaryJedisCommands.java @@ -190,6 +190,15 @@ public interface BinaryJedisCommands { Long zremrangeByScore(byte[] key, double start, double end); Long zremrangeByScore(byte[] key, byte[] start, byte[] end); + + Long zlexcount(final byte[] key, final byte[] min, final byte[] max); + + Set zrangeByLex(final byte[] key, final byte[] min, final byte[] max); + + Set zrangeByLex(final byte[] key, final byte[] min, final byte[] max, + int offset, int count); + + Long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max); Long linsert(byte[] key, Client.LIST_POSITION where, byte[] pivot, byte[] value); diff --git a/src/main/java/redis/clients/jedis/BinaryRedisPipeline.java b/src/main/java/redis/clients/jedis/BinaryRedisPipeline.java index 73037b7..799557d 100644 --- a/src/main/java/redis/clients/jedis/BinaryRedisPipeline.java +++ b/src/main/java/redis/clients/jedis/BinaryRedisPipeline.java @@ -206,6 +206,15 @@ public interface BinaryRedisPipeline { Response zrevrank(byte[] key, byte[] member); Response zscore(byte[] key, byte[] member); + + Response zlexcount(final byte[] key, final byte[] min, final byte[] max); + + Response> zrangeByLex(final byte[] key, final byte[] max, final byte[] min); + + Response> zrangeByLex(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 5895f20..b879d55 100644 --- a/src/main/java/redis/clients/jedis/BinaryShardedJedis.java +++ b/src/main/java/redis/clients/jedis/BinaryShardedJedis.java @@ -474,6 +474,31 @@ public class BinaryShardedJedis extends Sharded Jedis j = getShard(key); return j.zremrangeByScore(key, start, end); } + + @Override + public Long zlexcount(final byte[] key, final byte[] min, final byte[] max) { + Jedis j = getShard(key); + return j.zlexcount(key, min, max); + } + + @Override + public Set zrangeByLex(final byte[] key, final byte[] min, final byte[] max) { + Jedis j = getShard(key); + return j.zrangeByLex(key, min, max); + } + + @Override + public Set zrangeByLex(final byte[] key, final byte[] min, final byte[] max, + final int offset, final int count) { + Jedis j = getShard(key); + return j.zrangeByLex(key, min, max, offset, count); + } + + @Override + public Long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) { + Jedis j = getShard(key); + return j.zremrangeByLex(key, min, max); + } public Long linsert(byte[] key, LIST_POSITION where, byte[] pivot, byte[] value) { @@ -569,4 +594,5 @@ public class BinaryShardedJedis extends Sharded Jedis j = getShard(key); return j.bitcount(key, start, end); } + } \ No newline at end of file diff --git a/src/main/java/redis/clients/jedis/Client.java b/src/main/java/redis/clients/jedis/Client.java index 64f6f5c..f0d9f82 100644 --- a/src/main/java/redis/clients/jedis/Client.java +++ b/src/main/java/redis/clients/jedis/Client.java @@ -585,6 +585,24 @@ public class Client extends BinaryClient implements Commands { } zinterstore(SafeEncoder.encode(dstkey), params, bsets); } + + public void zlexcount(final String key, final String min, final String max) { + zlexcount(SafeEncoder.encode(key), SafeEncoder.encode(min), SafeEncoder.encode(max)); + } + + public void zrangeByLex(final String key, final String min, final String max) { + zrangeByLex(SafeEncoder.encode(key), SafeEncoder.encode(min), SafeEncoder.encode(max)); + } + + public void zrangeByLex(final String key, final String min, final String max, + final int offset, final int count) { + zrangeByLex(SafeEncoder.encode(key), SafeEncoder.encode(min), SafeEncoder.encode(max), + offset, count); + } + + public void zremrangeByLex(final String key, final String min, final String max) { + zremrangeByLex(SafeEncoder.encode(key), SafeEncoder.encode(min), SafeEncoder.encode(max)); + } public void strlen(final String key) { strlen(SafeEncoder.encode(key)); diff --git a/src/main/java/redis/clients/jedis/Jedis.java b/src/main/java/redis/clients/jedis/Jedis.java index 4961f42..ff5bd89 100644 --- a/src/main/java/redis/clients/jedis/Jedis.java +++ b/src/main/java/redis/clients/jedis/Jedis.java @@ -2561,6 +2561,35 @@ public class Jedis extends BinaryJedis implements JedisCommands, client.zinterstore(dstkey, params, sets); return client.getIntegerReply(); } + + @Override + public Long zlexcount(final String key, final String min, final String max) { + checkIsInMulti(); + client.zlexcount(key, min, max); + return client.getIntegerReply(); + } + + @Override + public Set zrangeByLex(final String key, final String min, final String max) { + checkIsInMulti(); + client.zrangeByLex(key, min, max); + return new LinkedHashSet(client.getMultiBulkReply()); + } + + @Override + public Set zrangeByLex(final String key, final String min, final String max, + final int offset, final int count) { + checkIsInMulti(); + client.zrangeByLex(key, min, max, offset, count); + return new LinkedHashSet(client.getMultiBulkReply()); + } + + @Override + public Long zremrangeByLex(final String key, final String min, final String max) { + checkIsInMulti(); + client.zremrangeByLex(key, min, max); + return client.getIntegerReply(); + } public Long strlen(final String key) { client.strlen(key); @@ -3412,4 +3441,5 @@ public class Jedis extends BinaryJedis implements JedisCommands, return BuilderFactory.STRING_MAP .build(client.getBinaryMultiBulkReply()); } + } diff --git a/src/main/java/redis/clients/jedis/JedisCluster.java b/src/main/java/redis/clients/jedis/JedisCluster.java index 121bde8..8f8b693 100644 --- a/src/main/java/redis/clients/jedis/JedisCluster.java +++ b/src/main/java/redis/clients/jedis/JedisCluster.java @@ -1063,6 +1063,51 @@ public class JedisCluster implements JedisCommands, BasicCommands { } }.run(key); } + + @Override + public Long zlexcount(final String key, final String min, final String max) { + return new JedisClusterCommand(connectionHandler, timeout, + maxRedirections) { + @Override + public Long execute(Jedis connection) { + return connection.zlexcount(key, min, max); + } + }.run(key); + } + + @Override + public Set zrangeByLex(final String key, final String min, final String max) { + return new JedisClusterCommand>(connectionHandler, timeout, + maxRedirections) { + @Override + public Set execute(Jedis connection) { + return connection.zrangeByLex(key, min, max); + } + }.run(key); + } + + @Override + public Set zrangeByLex(final String key, final String min, final String max, + final int offset, final int count) { + return new JedisClusterCommand>(connectionHandler, timeout, + maxRedirections) { + @Override + public Set execute(Jedis connection) { + return connection.zrangeByLex(key, min, max, offset, count); + } + }.run(key); + } + + @Override + public Long zremrangeByLex(final String key, final String min, final String max) { + return new JedisClusterCommand(connectionHandler, timeout, + maxRedirections) { + @Override + public Long execute(Jedis connection) { + return connection.zremrangeByLex(key, min, max); + } + }.run(key); + } @Override public Long linsert(final String key, final LIST_POSITION where, @@ -1481,4 +1526,5 @@ public class JedisCluster implements JedisCommands, BasicCommands { } }.run(null); } + } diff --git a/src/main/java/redis/clients/jedis/JedisCommands.java b/src/main/java/redis/clients/jedis/JedisCommands.java index 5952bdb..907b328 100644 --- a/src/main/java/redis/clients/jedis/JedisCommands.java +++ b/src/main/java/redis/clients/jedis/JedisCommands.java @@ -189,6 +189,15 @@ public interface JedisCommands { Long zremrangeByScore(String key, double start, double end); Long zremrangeByScore(String key, String start, String end); + + Long zlexcount(final String key, final String min, final String max); + + Set zrangeByLex(final String key, final String min, final String max); + + Set zrangeByLex(final String key, final String min, final String max, + final int offset, final int count); + + Long zremrangeByLex(final String key, final String min, final String max); Long linsert(String key, Client.LIST_POSITION where, String pivot, String value); diff --git a/src/main/java/redis/clients/jedis/PipelineBase.java b/src/main/java/redis/clients/jedis/PipelineBase.java index 3183ba1..db37b2e 100644 --- a/src/main/java/redis/clients/jedis/PipelineBase.java +++ b/src/main/java/redis/clients/jedis/PipelineBase.java @@ -1008,6 +1008,56 @@ abstract class PipelineBase extends Queable implements BinaryRedisPipeline, return getResponse(BuilderFactory.DOUBLE); } + @Override + public Response zlexcount(final byte[] key, final byte[] min, final byte[] max) { + getClient(key).zlexcount(key, min, max); + return getResponse(BuilderFactory.LONG); + } + + @Override + public Response zlexcount(final String key, final String min, final String max) { + getClient(key).zlexcount(key, min, max); + return getResponse(BuilderFactory.LONG); + } + + @Override + public Response> zrangeByLex(final byte[] key, final byte[] max, final byte[] min) { + getClient(key).zrangeByLex(key, min, max); + return getResponse(BuilderFactory.BYTE_ARRAY_ZSET); + } + + @Override + public Response> zrangeByLex(final String key, final String max, final String min) { + getClient(key).zrangeByLex(key, min, max); + return getResponse(BuilderFactory.STRING_ZSET); + } + + @Override + public Response> zrangeByLex(final byte[] key, final byte[] max, + final byte[] min, final int offset, final int count) { + getClient(key).zrangeByLex(key, min, max, offset, count); + return getResponse(BuilderFactory.BYTE_ARRAY_ZSET); + } + + @Override + public Response> zrangeByLex(final String key, final String max, + final String min, final int offset, final int count) { + getClient(key).zrangeByLex(key, min, max, 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); + return getResponse(BuilderFactory.LONG); + } + + @Override + public Response zremrangeByLex(final String key, final String min, final String max) { + getClient(key).zremrangeByLex(key, min, max); + return getResponse(BuilderFactory.LONG); + } + public Response bitcount(String key) { getClient(key).bitcount(key); return getResponse(BuilderFactory.LONG); diff --git a/src/main/java/redis/clients/jedis/Protocol.java b/src/main/java/redis/clients/jedis/Protocol.java index 681bc56..76e74ef 100644 --- a/src/main/java/redis/clients/jedis/Protocol.java +++ b/src/main/java/redis/clients/jedis/Protocol.java @@ -208,7 +208,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, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, SHUTDOWN, INFO, MONITOR, SLAVEOF, CONFIG, STRLEN, SYNC, LPUSHX, PERSIST, RPUSHX, ECHO, LINSERT, DEBUG, BRPOPLPUSH, SETBIT, GETBIT, SETRANGE, GETRANGE, EVAL, EVALSHA, SCRIPT, SLOWLOG, OBJECT, BITCOUNT, BITOP, SENTINEL, DUMP, RESTORE, PEXPIRE, PEXPIREAT, PTTL, INCRBYFLOAT, PSETEX, CLIENT, TIME, MIGRATE, HINCRBYFLOAT, SCAN, HSCAN, SSCAN, ZSCAN, WAIT, CLUSTER, ASKING; + PING, SET, GET, QUIT, EXISTS, DEL, TYPE, FLUSHDB, KEYS, RANDOMKEY, RENAME, RENAMENX, RENAMEX, DBSIZE, EXPIRE, EXPIREAT, TTL, SELECT, MOVE, FLUSHALL, GETSET, MGET, SETNX, SETEX, MSET, MSETNX, DECRBY, DECR, INCRBY, INCR, APPEND, SUBSTR, HSET, HGET, HSETNX, HMSET, HMGET, HINCRBY, HEXISTS, HDEL, HLEN, HKEYS, HVALS, HGETALL, RPUSH, LPUSH, LLEN, LRANGE, LTRIM, LINDEX, LSET, LREM, LPOP, RPOP, RPOPLPUSH, SADD, SMEMBERS, SREM, SPOP, SMOVE, SCARD, SISMEMBER, SINTER, SINTERSTORE, SUNION, SUNIONSTORE, SDIFF, SDIFFSTORE, SRANDMEMBER, ZADD, ZRANGE, ZREM, ZINCRBY, ZRANK, ZREVRANK, ZREVRANGE, ZCARD, ZSCORE, MULTI, DISCARD, EXEC, WATCH, UNWATCH, SORT, BLPOP, BRPOP, AUTH, SUBSCRIBE, PUBLISH, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBSUB, ZCOUNT, ZRANGEBYSCORE, ZREVRANGEBYSCORE, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZUNIONSTORE, ZINTERSTORE, ZLEXCOUNT, ZRANGEBYLEX, ZREMRANGEBYLEX, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, SHUTDOWN, INFO, MONITOR, SLAVEOF, CONFIG, STRLEN, SYNC, LPUSHX, PERSIST, RPUSHX, ECHO, LINSERT, DEBUG, BRPOPLPUSH, SETBIT, GETBIT, 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; 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 bb5226c..2961a68 100644 --- a/src/main/java/redis/clients/jedis/RedisPipeline.java +++ b/src/main/java/redis/clients/jedis/RedisPipeline.java @@ -184,6 +184,15 @@ public interface RedisPipeline { Response zrevrank(String key, String member); Response zscore(String key, String member); + + Response zlexcount(final String key, final String min, final String max); + + Response> zrangeByLex(final String key, final String max, final String min); + + Response> zrangeByLex(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 7235cfe..2211467 100644 --- a/src/main/java/redis/clients/jedis/ShardedJedis.java +++ b/src/main/java/redis/clients/jedis/ShardedJedis.java @@ -506,6 +506,27 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands { Jedis j = getShard(key); return j.zremrangeByScore(key, start, end); } + + @Override + public Long zlexcount(final String key, final String min, final String max) { + return getShard(key).zlexcount(key, min, max); + } + + @Override + public Set zrangeByLex(final String key, final String min, final String max) { + return getShard(key).zrangeByLex(key, min, max); + } + + @Override + public Set zrangeByLex(final String key, final String min, final String max, + final int offset, final int count) { + return getShard(key).zrangeByLex(key, min, max, offset, count); + } + + @Override + public Long zremrangeByLex(final String key, final String min, final String max) { + return getShard(key).zremrangeByLex(key, min, max); + } public Long linsert(String key, LIST_POSITION where, String pivot, String value) { @@ -570,4 +591,5 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands { Jedis j = getShard(key); return j.zscan(key, cursor); } + } 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 90b4c20..3b046a2 100644 --- a/src/test/java/redis/clients/jedis/tests/commands/SortedSetCommandsTest.java +++ b/src/test/java/redis/clients/jedis/tests/commands/SortedSetCommandsTest.java @@ -3,6 +3,8 @@ package redis.clients.jedis.tests.commands; import java.util.LinkedHashSet; import java.util.Set; +import javax.swing.text.html.MinimalHTMLWriter; + import org.junit.Test; import redis.clients.jedis.ScanParams; @@ -19,6 +21,10 @@ public class SortedSetCommandsTest extends JedisCommandTestBase { final byte[] ba = { 0x0A }; final byte[] bb = { 0x0B }; final byte[] bc = { 0x0C }; + final byte[] bInclusiveB = { 0x5B, 0x0B }; + final byte[] bExclusiveC = { 0x28, 0x0C }; + final byte[] bLexMinusInf = { 0x2D }; + final byte[] bLexPlusInf = { 0x2B }; @Test public void zadd() { @@ -48,7 +54,7 @@ public class SortedSetCommandsTest extends JedisCommandTestBase { assertEquals(0, bstatus); } - + @Test public void zrange() { jedis.zadd("foo", 1d, "a"); @@ -85,6 +91,48 @@ public class SortedSetCommandsTest extends JedisCommandTestBase { assertEquals(bexpected, brange); } + + @Test + public void zrangeByLex() { + 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("bb"); + expected.add("c"); + + // exclusive aa ~ inclusive c + assertEquals(expected, jedis.zrangeByLex("foo", "(aa", "[c")); + + expected.clear(); + expected.add("bb"); + expected.add("c"); + + // with LIMIT + assertEquals(expected, jedis.zrangeByLex("foo", "-", "+", 1, 2)); + } + + @Test + public void zrangeByLexBinary() { + // 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.zrangeByLex(bfoo, bInclusiveB, bExclusiveC)); + + bExpected.clear(); + bExpected.add(ba); + bExpected.add(bb); + + // with LIMIT + assertEquals(bExpected, jedis.zrangeByLex(bfoo, bLexMinusInf, bLexPlusInf, 0, 2)); + } @Test public void zrevrange() { @@ -395,6 +443,40 @@ public class SortedSetCommandsTest extends JedisCommandTestBase { assertEquals(3, bresult); } + + @Test + public void zlexcount() { + jedis.zadd("foo", 1, "a"); + jedis.zadd("foo", 1, "b"); + jedis.zadd("foo", 1, "c"); + jedis.zadd("foo", 1, "aa"); + + long result = jedis.zlexcount("foo", "[aa", "(c"); + assertEquals(2, result); + + result = jedis.zlexcount("foo", "-", "+"); + assertEquals(4, result); + + result = jedis.zlexcount("foo", "-", "(c"); + assertEquals(3, result); + + result = jedis.zlexcount("foo", "[aa", "+"); + assertEquals(3, result); + } + + @Test + public void zlexcountBinary() { + // Binary + jedis.zadd(bfoo, 1, ba); + jedis.zadd(bfoo, 1, bc); + jedis.zadd(bfoo, 1, bb); + + long result = jedis.zlexcount(bfoo, bInclusiveB, bExclusiveC); + assertEquals(1, result); + + result = jedis.zlexcount(bfoo, bLexMinusInf, bLexPlusInf); + assertEquals(3, result); + } @Test public void zrangebyscore() { @@ -733,6 +815,41 @@ public class SortedSetCommandsTest extends JedisCommandTestBase { assertEquals(bexpected, jedis.zrange(bfoo, 0, 100)); } + + @Test + public void zremrangeByLex() { + jedis.zadd("foo", 1, "a"); + jedis.zadd("foo", 1, "b"); + jedis.zadd("foo", 1, "c"); + jedis.zadd("foo", 1, "aa"); + + long result = jedis.zremrangeByLex("foo", "[aa", "(c"); + + assertEquals(2, result); + + Set expected = new LinkedHashSet(); + expected.add("a"); + expected.add("c"); + + assertEquals(expected, jedis.zrangeByLex("foo", "-", "+")); + } + + @Test + public void zremrangeByLexBinary() { + jedis.zadd(bfoo, 1, ba); + jedis.zadd(bfoo, 1, bc); + jedis.zadd(bfoo, 1, bb); + + long bresult = jedis.zremrangeByLex(bfoo, bInclusiveB, bExclusiveC); + + assertEquals(1, bresult); + + Set bexpected = new LinkedHashSet(); + bexpected.add(ba); + bexpected.add(bc); + + assertEquals(bexpected, jedis.zrangeByLex(bfoo, bLexMinusInf, bLexPlusInf)); + } @Test public void zunionstore() {