Merge pull request #753 from HeartSaVioR/support-zrevrangebylex

Support zrevrangebylex command (closes #746)
This commit is contained in:
Jungtaek Lim
2014-09-29 08:07:46 +09:00
14 changed files with 192 additions and 4 deletions

View File

@@ -846,11 +846,20 @@ public class BinaryClient extends Connection {
toByteArray(offset), toByteArray(count)); 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) { public void zremrangeByLex(byte[] key, byte[] min, byte[] max) {
sendCommand(ZREMRANGEBYLEX, key, min, max); sendCommand(ZREMRANGEBYLEX, key, min, max);
} }
public void save() { public void save() {
sendCommand(SAVE); sendCommand(SAVE);
} }

View File

@@ -2848,6 +2848,21 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
return new LinkedHashSet<byte[]>(client.getBinaryMultiBulkReply()); return new LinkedHashSet<byte[]>(client.getBinaryMultiBulkReply());
} }
@Override
public Set<byte[]> zrevrangeByLex(byte[] key, byte[] max, byte[] min) {
checkIsInMulti();
client.zrevrangeByLex(key, max, min);
return new LinkedHashSet<byte[]>(client.getBinaryMultiBulkReply());
}
@Override
public Set<byte[]> zrevrangeByLex(byte[] key, byte[] max, byte[] min,
int offset, int count) {
checkIsInMulti();
client.zrevrangeByLex(key, max, min, offset, count);
return new LinkedHashSet<byte[]>(client.getBinaryMultiBulkReply());
}
@Override @Override
public Long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) { public Long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) {
checkIsInMulti(); checkIsInMulti();
@@ -3630,4 +3645,5 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands,
} }
return new ScanResult<Tuple>(newcursor, results); return new ScanResult<Tuple>(newcursor, results);
} }
} }

View File

@@ -204,6 +204,11 @@ public interface BinaryJedisCommands {
Set<byte[]> zrangeByLex(final byte[] key, final byte[] min, final byte[] max, Set<byte[]> zrangeByLex(final byte[] key, final byte[] min, final byte[] max,
int offset, int count); int offset, int count);
Set<byte[]> zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min);
Set<byte[]> 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); Long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max);
Long linsert(byte[] key, Client.LIST_POSITION where, byte[] pivot, Long linsert(byte[] key, Client.LIST_POSITION where, byte[] pivot,

View File

@@ -214,6 +214,11 @@ public interface BinaryRedisPipeline {
Response<Set<byte[]>> zrangeByLex(final byte[] key, final byte[] max, final byte[] min, Response<Set<byte[]>> zrangeByLex(final byte[] key, final byte[] max, final byte[] min,
int offset, int count); int offset, int count);
Response<Set<byte[]>> zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min);
Response<Set<byte[]>> zrevrangeByLex(final byte[] key, final byte[] max, final byte[] min,
int offset, int count);
Response<Long> zremrangeByLex(final byte[] key, final byte[] min, final byte[] max); Response<Long> zremrangeByLex(final byte[] key, final byte[] min, final byte[] max);
Response<Long> bitcount(byte[] key); Response<Long> bitcount(byte[] key);

View File

@@ -510,6 +510,19 @@ public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo>
return j.zrangeByLex(key, min, max, offset, count); return j.zrangeByLex(key, min, max, offset, count);
} }
@Override
public Set<byte[]> zrevrangeByLex(byte[] key, byte[] max, byte[] min) {
Jedis j = getShard(key);
return j.zrevrangeByLex(key, max, min);
}
@Override
public Set<byte[]> zrevrangeByLex(byte[] key, byte[] max, byte[] min,
int offset, int count) {
Jedis j = getShard(key);
return j.zrevrangeByLex(key, max, min, offset, count);
}
@Override @Override
public Long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) { public Long zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) {
Jedis j = getShard(key); Jedis j = getShard(key);

View File

@@ -601,6 +601,16 @@ public class Client extends BinaryClient implements Commands {
offset, count); 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) { public void zremrangeByLex(final String key, final String min, final String max) {
zremrangeByLex(SafeEncoder.encode(key), SafeEncoder.encode(min), SafeEncoder.encode(max)); zremrangeByLex(SafeEncoder.encode(key), SafeEncoder.encode(min), SafeEncoder.encode(max));
} }
@@ -1003,4 +1013,5 @@ public void clusterSetSlotStable(final int slot) {
public void clusterSlots() { public void clusterSlots() {
cluster(Protocol.CLUSTER_SLOTS); cluster(Protocol.CLUSTER_SLOTS);
} }
} }

View File

@@ -2646,6 +2646,21 @@ public class Jedis extends BinaryJedis implements JedisCommands,
return new LinkedHashSet<String>(client.getMultiBulkReply()); return new LinkedHashSet<String>(client.getMultiBulkReply());
} }
@Override
public Set<String> zrevrangeByLex(String key, String max, String min) {
checkIsInMulti();
client.zrevrangeByLex(key, max, min);
return new LinkedHashSet<String>(client.getMultiBulkReply());
}
@Override
public Set<String> zrevrangeByLex(String key, String max, String min,
int offset, int count) {
checkIsInMulti();
client.zrevrangeByLex(key, max, min, offset, count);
return new LinkedHashSet<String>(client.getMultiBulkReply());
}
@Override @Override
public Long zremrangeByLex(final String key, final String min, final String max) { public Long zremrangeByLex(final String key, final String min, final String max) {
checkIsInMulti(); checkIsInMulti();

View File

@@ -1157,6 +1157,29 @@ public class JedisCluster implements JedisCommands, BasicCommands, Closeable {
}.run(key); }.run(key);
} }
@Override
public Set<String> zrevrangeByLex(final String key, final String max, final String min) {
return new JedisClusterCommand<Set<String>>(connectionHandler, timeout,
maxRedirections) {
@Override
public Set<String> execute(Jedis connection) {
return connection.zrevrangeByLex(key, max, min);
}
}.run(key);
}
@Override
public Set<String> zrevrangeByLex(final String key, final String max, final String min,
final int offset, final int count) {
return new JedisClusterCommand<Set<String>>(connectionHandler, timeout,
maxRedirections) {
@Override
public Set<String> execute(Jedis connection) {
return connection.zrevrangeByLex(key, max, min, offset, count);
}
}.run(key);
}
@Override @Override
public Long zremrangeByLex(final String key, final String min, final String max) { public Long zremrangeByLex(final String key, final String min, final String max) {
return new JedisClusterCommand<Long>(connectionHandler, timeout, return new JedisClusterCommand<Long>(connectionHandler, timeout,
@@ -1577,4 +1600,5 @@ public class JedisCluster implements JedisCommands, BasicCommands, Closeable {
} }
}.run(null); }.run(null);
} }
} }

View File

@@ -202,6 +202,11 @@ public interface JedisCommands {
Set<String> zrangeByLex(final String key, final String min, final String max, Set<String> zrangeByLex(final String key, final String min, final String max,
final int offset, final int count); final int offset, final int count);
Set<String> zrevrangeByLex(final String key, final String max, final String min);
Set<String> 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); Long zremrangeByLex(final String key, final String min, final String max);
Long linsert(String key, Client.LIST_POSITION where, String pivot, Long linsert(String key, Client.LIST_POSITION where, String pivot,

View File

@@ -1064,6 +1064,32 @@ abstract class PipelineBase extends Queable implements BinaryRedisPipeline,
return getResponse(BuilderFactory.STRING_ZSET); return getResponse(BuilderFactory.STRING_ZSET);
} }
@Override
public Response<Set<byte[]>> 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<Set<String>> zrevrangeByLex(final String key, final String max, final String min) {
getClient(key).zrevrangeByLex(key, max, min);
return getResponse(BuilderFactory.STRING_ZSET);
}
@Override
public Response<Set<byte[]>> 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<Set<String>> 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 @Override
public Response<Long> zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) { public Response<Long> zremrangeByLex(final byte[] key, final byte[] min, final byte[] max) {
getClient(key).zremrangeByLex(key, min, max); getClient(key).zremrangeByLex(key, min, max);

View File

@@ -219,7 +219,7 @@ public final class Protocol {
} }
public static enum Command { public static enum Command {
PING, SET, GET, QUIT, EXISTS, DEL, TYPE, FLUSHDB, KEYS, RANDOMKEY, RENAME, RENAMENX, RENAMEX, DBSIZE, EXPIRE, EXPIREAT, TTL, SELECT, MOVE, FLUSHALL, GETSET, MGET, SETNX, SETEX, MSET, MSETNX, DECRBY, DECR, INCRBY, INCR, APPEND, SUBSTR, HSET, HGET, HSETNX, HMSET, HMGET, HINCRBY, HEXISTS, HDEL, HLEN, HKEYS, HVALS, HGETALL, RPUSH, LPUSH, LLEN, LRANGE, LTRIM, LINDEX, LSET, LREM, LPOP, RPOP, RPOPLPUSH, SADD, SMEMBERS, SREM, SPOP, SMOVE, SCARD, SISMEMBER, SINTER, SINTERSTORE, SUNION, SUNIONSTORE, SDIFF, SDIFFSTORE, SRANDMEMBER, ZADD, ZRANGE, ZREM, ZINCRBY, ZRANK, ZREVRANK, ZREVRANGE, ZCARD, ZSCORE, MULTI, DISCARD, EXEC, WATCH, UNWATCH, SORT, BLPOP, BRPOP, AUTH, SUBSCRIBE, PUBLISH, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBSUB, ZCOUNT, ZRANGEBYSCORE, ZREVRANGEBYSCORE, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZUNIONSTORE, ZINTERSTORE, ZLEXCOUNT, ZRANGEBYLEX, ZREMRANGEBYLEX, SAVE, BGSAVE, BGREWRITEAOF, LASTSAVE, SHUTDOWN, INFO, MONITOR, SLAVEOF, CONFIG, STRLEN, SYNC, LPUSHX, PERSIST, RPUSHX, ECHO, LINSERT, DEBUG, BRPOPLPUSH, SETBIT, GETBIT, 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; public final byte[] raw;

View File

@@ -192,6 +192,11 @@ public interface RedisPipeline {
Response<Set<String>> zrangeByLex(final String key, final String max, final String min, Response<Set<String>> zrangeByLex(final String key, final String max, final String min,
final int offset, final int count); final int offset, final int count);
Response<Set<String>> zrevrangeByLex(final String key, final String max, final String min);
Response<Set<String>> zrevrangeByLex(final String key, final String max, final String min,
final int offset, final int count);
Response<Long> zremrangeByLex(final String key, final String start, final String end); Response<Long> zremrangeByLex(final String key, final String start, final String end);
Response<Long> bitcount(String key); Response<Long> bitcount(String key);

View File

@@ -1,6 +1,7 @@
package redis.clients.jedis; package redis.clients.jedis;
import java.io.Closeable; import java.io.Closeable;
import redis.clients.jedis.BinaryClient.LIST_POSITION; import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.util.Hashing; import redis.clients.util.Hashing;
@@ -559,6 +560,17 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands,
return getShard(key).zrangeByLex(key, min, max, offset, count); return getShard(key).zrangeByLex(key, min, max, offset, count);
} }
@Override
public Set<String> zrevrangeByLex(String key, String max, String min) {
return getShard(key).zrevrangeByLex(key, max, min);
}
@Override
public Set<String> zrevrangeByLex(String key, String max, String min,
int offset, int count) {
return getShard(key).zrevrangeByLex(key, max, min, offset, count);
}
@Override @Override
public Long zremrangeByLex(final String key, final String min, final String max) { public Long zremrangeByLex(final String key, final String min, final String max) {
return getShard(key).zremrangeByLex(key, min, max); return getShard(key).zremrangeByLex(key, min, max);

View File

@@ -138,6 +138,48 @@ public class SortedSetCommandsTest extends JedisCommandTestBase {
assertEquals(bExpected, jedis.zrangeByLex(bfoo, bLexMinusInf, bLexPlusInf, 0, 2)); 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<String> expected = new LinkedHashSet<String>();
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<byte[]> bExpected = new LinkedHashSet<byte[]>();
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 @Test
public void zrevrange() { public void zrevrange() {
jedis.zadd("foo", 1d, "a"); jedis.zadd("foo", 1d, "a");