implemented bitcount and bitop commands for Redis 2.6
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,3 +8,4 @@
|
|||||||
target/
|
target/
|
||||||
build/
|
build/
|
||||||
bin/
|
bin/
|
||||||
|
tags
|
||||||
|
|||||||
@@ -807,4 +807,41 @@ public class BinaryClient extends Connection {
|
|||||||
public void objectEncoding(byte[] key) {
|
public void objectEncoding(byte[] key) {
|
||||||
sendCommand(OBJECT, ENCODING.raw, key);
|
sendCommand(OBJECT, ENCODING.raw, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void bitcount(byte[] key) {
|
||||||
|
sendCommand(BITCOUNT, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bitcount(byte[] key, long start, long end) {
|
||||||
|
sendCommand(BITCOUNT, key, toByteArray(start), toByteArray(end));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bitop(BitOP op, byte[] destKey, String... srcKeys) {
|
||||||
|
Keyword kw = Keyword.AND;
|
||||||
|
int len = srcKeys.length;
|
||||||
|
switch (op) {
|
||||||
|
case AND:
|
||||||
|
kw = Keyword.AND;
|
||||||
|
break;
|
||||||
|
case OR:
|
||||||
|
kw = Keyword.OR;
|
||||||
|
break;
|
||||||
|
case XOR:
|
||||||
|
kw = Keyword.XOR;
|
||||||
|
break;
|
||||||
|
case NOT:
|
||||||
|
kw = Keyword.NOT;
|
||||||
|
len = Math.min(1, len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[][] bargs = new byte[len + 2][];
|
||||||
|
bargs[0] = kw.raw;
|
||||||
|
bargs[1] = destKey;
|
||||||
|
for (int i = 0; i < len; ++i) {
|
||||||
|
bargs[i + 2] = SafeEncoder.encode(srcKeys[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendCommand(BITOP, bargs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
src/main/java/redis/clients/jedis/BitOP.java
Normal file
8
src/main/java/redis/clients/jedis/BitOP.java
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package redis.clients.jedis;
|
||||||
|
|
||||||
|
public enum BitOP {
|
||||||
|
AND,
|
||||||
|
OR,
|
||||||
|
XOR,
|
||||||
|
NOT;
|
||||||
|
}
|
||||||
@@ -703,4 +703,16 @@ public class Client extends BinaryClient implements Commands {
|
|||||||
public void objectEncoding(String key) {
|
public void objectEncoding(String key) {
|
||||||
objectEncoding(SafeEncoder.encode(key));
|
objectEncoding(SafeEncoder.encode(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void bitcount(final String key) {
|
||||||
|
bitcount(SafeEncoder.encode(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bitcount(final String key, long start, long end) {
|
||||||
|
bitcount(SafeEncoder.encode(key), start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bitop(BitOP op, final String destKey, String... srcKeys) {
|
||||||
|
bitop(op, SafeEncoder.encode(destKey), srcKeys);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -285,4 +285,10 @@ public interface Commands {
|
|||||||
public void objectIdletime(String key);
|
public void objectIdletime(String key);
|
||||||
|
|
||||||
public void objectEncoding(String key);
|
public void objectEncoding(String key);
|
||||||
}
|
|
||||||
|
public void bitcount(final String key);
|
||||||
|
|
||||||
|
public void bitcount(final String key, long start, long end);
|
||||||
|
|
||||||
|
public void bitop(BitOP op, final String destKey, String... srcKeys);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2873,4 +2873,20 @@ public class Jedis extends BinaryJedis implements JedisCommands {
|
|||||||
client.objectIdletime(string);
|
client.objectIdletime(string);
|
||||||
return client.getIntegerReply();
|
return client.getIntegerReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long bitcount(final String key) {
|
||||||
|
client.bitcount(key);
|
||||||
|
return client.getIntegerReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long bitcount(final String key, long start, long end) {
|
||||||
|
client.bitcount(key, start, end);
|
||||||
|
return client.getIntegerReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long bitop(BitOP op, final String destKey, String... srcKeys) {
|
||||||
|
client.bitop(op, destKey, srcKeys);
|
||||||
|
return client.getIntegerReply();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,4 +190,11 @@ public interface JedisCommands {
|
|||||||
Long lpushx(String key, String string);
|
Long lpushx(String key, String string);
|
||||||
|
|
||||||
Long rpushx(String key, String string);
|
Long rpushx(String key, String string);
|
||||||
|
|
||||||
|
Long bitcount(final String key);
|
||||||
|
|
||||||
|
Long bitcount(final String key, long start, long end);
|
||||||
|
|
||||||
|
Long bitop(BitOP op, final String destKey, String... srcKeys);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,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;
|
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;
|
||||||
|
|
||||||
public final byte[] raw;
|
public final byte[] raw;
|
||||||
|
|
||||||
@@ -154,7 +154,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;
|
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;
|
||||||
public final byte[] raw;
|
public final byte[] raw;
|
||||||
|
|
||||||
Keyword() {
|
Keyword() {
|
||||||
|
|||||||
@@ -483,4 +483,19 @@ public class ShardedJedis extends BinaryShardedJedis implements JedisCommands {
|
|||||||
Jedis j = getShard(key);
|
Jedis j = getShard(key);
|
||||||
return j.linsert(key, where, pivot, value);
|
return j.linsert(key, where, pivot, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long bitcount(final String key) {
|
||||||
|
Jedis j = getShard(key);
|
||||||
|
return j.bitcount(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long bitcount(final String key, long start, long end) {
|
||||||
|
Jedis j = getShard(key);
|
||||||
|
return j.bitcount(key, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long bitop(BitOP op, final String destKey, String... srcKeys) {
|
||||||
|
Jedis j = getShard(destKey);
|
||||||
|
return j.bitop(op, destKey, srcKeys);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package redis.clients.jedis.tests.commands;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import redis.clients.jedis.BitOP;
|
||||||
|
|
||||||
public class BitCommandsTest extends JedisCommandTestBase {
|
public class BitCommandsTest extends JedisCommandTestBase {
|
||||||
@Test
|
@Test
|
||||||
public void setAndgetbit() {
|
public void setAndgetbit() {
|
||||||
@@ -29,4 +31,63 @@ public class BitCommandsTest extends JedisCommandTestBase {
|
|||||||
assertEquals("Hello", jedis.getrange("key1", 0, 4));
|
assertEquals("Hello", jedis.getrange("key1", 0, 4));
|
||||||
assertEquals("Jedis", jedis.getrange("key1", 6, 11));
|
assertEquals("Jedis", jedis.getrange("key1", 6, 11));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Test
|
||||||
|
public void bitCount() {
|
||||||
|
jedis.del("foo");
|
||||||
|
|
||||||
|
jedis.setbit("foo", 16, true);
|
||||||
|
jedis.setbit("foo", 24, true);
|
||||||
|
jedis.setbit("foo", 40, true);
|
||||||
|
jedis.setbit("foo", 56, true);
|
||||||
|
|
||||||
|
long c4 = jedis.bitcount("foo");
|
||||||
|
assertEquals(4, c4);
|
||||||
|
|
||||||
|
long c3 = jedis.bitcount("foo", 2L, 5L);
|
||||||
|
assertEquals(3, c3);
|
||||||
|
|
||||||
|
jedis.del("foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bitOp()
|
||||||
|
{
|
||||||
|
jedis.set("key1", "\u0060");
|
||||||
|
jedis.set("key2", "\u0044");
|
||||||
|
|
||||||
|
jedis.bitop(BitOP.AND, "resultAnd", "key1", "key2");
|
||||||
|
String resultAnd = jedis.get("resultAnd");
|
||||||
|
assertEquals("\u0040", resultAnd);
|
||||||
|
|
||||||
|
jedis.bitop(BitOP.OR, "resultOr", "key1", "key2");
|
||||||
|
String resultOr = jedis.get("resultOr");
|
||||||
|
assertEquals("\u0064", resultOr);
|
||||||
|
|
||||||
|
jedis.bitop(BitOP.XOR, "resultXor", "key1", "key2");
|
||||||
|
String resultXor = jedis.get("resultXor");
|
||||||
|
assertEquals("\u0024", resultXor);
|
||||||
|
|
||||||
|
jedis.del("resultAnd");
|
||||||
|
jedis.del("resultOr");
|
||||||
|
jedis.del("resultXor");
|
||||||
|
jedis.del("key1");
|
||||||
|
jedis.del("key2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bitOpNot()
|
||||||
|
{
|
||||||
|
jedis.del("key");
|
||||||
|
jedis.setbit("key", 0, true);
|
||||||
|
jedis.setbit("key", 4, true);
|
||||||
|
|
||||||
|
jedis.bitop(BitOP.NOT, "resultNot", "key");
|
||||||
|
|
||||||
|
String resultNot = jedis.get("resultNot");
|
||||||
|
assertEquals("\u0077", resultNot);
|
||||||
|
|
||||||
|
jedis.del("key");
|
||||||
|
jedis.del("resultNot");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user