Permalink
Browse files

Add hincrby, getbit, setbit commands

  • Loading branch information...
1 parent f69b865 commit eae3b4a916af80152a44239b4a13c976e4e76045 @akbertram akbertram committed Mar 17, 2012
View
5 core/api/src/main/java/org/jredis/JRedis.java
@@ -1092,4 +1092,9 @@
* @see {@link ObjectInfo}
*/
public <K extends Object> ObjectInfo debug (K key) throws RedisException;
+
+ public <K extends Object> boolean setbit(K key, int offset, boolean value) throws RedisException;
+
+ public <K extends Object> boolean getbit(K key, int offset) throws RedisException;
+
}
View
22 core/api/src/main/java/org/jredis/JRedisFuture.java
@@ -152,6 +152,10 @@
public <K extends Object, T extends Serializable>
Future<Boolean> setnx (K key, T object);
+ public <K extends Object> Future<Boolean> setbit(K key, int offset, boolean value);
+
+
+
/**
* @Redis GET
* @param key
@@ -165,7 +169,10 @@
public <K extends Object, T extends Serializable>
Future<byte[]> getset (K key, T object);
-
+
+ public <K extends Object> Future<Boolean> getbit(K key, int offset);
+
+
/**
* @Redis MGET
* @param key
@@ -810,6 +817,17 @@
@Redis(versions="1.3.4")
public <K extends Object> Future<byte[]> hget(K key, K entry);
+
+ /**
+ * @Redis HINCRBY
+ * @param key
+ * @param entry
+ * @param increment
+ * @return
+ */
+ public <K extends Object> Future<Long> hincrby(K key, K entry, long increment);
+
+
/**
*
* @Redis HEXISTS
@@ -998,4 +1016,6 @@
* @return
*/
public <K extends Object> Future<ObjectInfo> debug (K key);
+
+
}
View
9 core/api/src/main/java/org/jredis/protocol/Command.java
@@ -122,6 +122,10 @@
ZREMRANGEBYRANK (RequestType.KEY_NUM_NUM, ResponseType.NUMBER),
ZCOUNT (RequestType.KEY_NUM_NUM, ResponseType.NUMBER),
+ // Commands operating on bit sets
+ SETBIT (RequestType.KEY_IDX_VALUE, ResponseType.NUMBER),
+ GETBIT (RequestType.KEY_NUM, ResponseType.NUMBER),
+
// Commands operating on hashes
HSET (RequestType.KEY_KEY_VALUE, ResponseType.BOOLEAN),
HGET (RequestType.KEY_VALUE, ResponseType.BULK),
@@ -131,6 +135,7 @@
HKEYS (RequestType.KEY, ResponseType.MULTI_BULK),
HVALS (RequestType.KEY, ResponseType.MULTI_BULK),
HGETALL (RequestType.KEY, ResponseType.MULTI_BULK),
+ HINCRBY (RequestType.KEY_KEY_NUM, ResponseType.NUMBER),
// transactional commands
MULTI (RequestType.NO_ARG, ResponseType.STATUS),
@@ -309,7 +314,9 @@ static final public int bitclear(final int bitsetin, Flag...flags){
/** */
MULTI_KEY,
/** */
- BULK_SET
+ BULK_SET,
+
+ KEY_KEY_NUM
}
/**
View
62 core/ri/src/main/java/org/jredis/ri/alphazero/JRedisFutureSupport.java
@@ -337,6 +337,32 @@
// -------- set
@Override
+ public <K> Future<Boolean> setbit(K key, int offset, boolean value) {
+ byte[] keybytes = null;
+ if((keybytes = JRedisSupport.getKeyBytes(key)) == null)
+ throw new IllegalArgumentException ("invalid key => ["+key+"]");
+
+ Future<Response> futureResponse = this.queueRequest(Command.SETBIT, keybytes,
+ Convert.toBytes(offset), Convert.toBytes(value ? 1 : 0));
+
+ return new FutureBit(futureResponse);
+
+ }
+
+
+ @Override
+ public <K> Future<Boolean> getbit(K key, int offset) {
+ byte[] keybytes = null;
+ if((keybytes = JRedisSupport.getKeyBytes(key)) == null)
+ throw new IllegalArgumentException ("invalid key => ["+key+"]");
+
+ Future<Response> futureResponse = this.queueRequest(Command.GETBIT, keybytes,
+ Convert.toBytes(offset));
+
+ return new FutureBit(futureResponse);
+ }
+
+ @Override
public <K extends Object> FutureStatus set(K key, byte[] value) {
byte[] keybytes = null;
if((keybytes = JRedisSupport.getKeyBytes(key)) == null)
@@ -494,6 +520,20 @@
public <K extends Object> Future<Boolean> hset(K key, K field, String stringValue) {
return hset (key, field, DefaultCodec.encode(stringValue));
}
+
+ public <K extends Object> Future<Long> hincrby(K key, K field, long increment) {
+ byte[] keyBytes = null;
+ if((keyBytes = JRedisSupport.getKeyBytes(key)) == null)
+ throw new IllegalArgumentException ("invalid key => ["+key+"]");
+
+ byte[] entryBytes = null;
+ if((entryBytes = JRedisSupport.getKeyBytes(field)) == null)
+ throw new IllegalArgumentException ("invalid field => ["+field+"]");
+
+ Future<Response> futureResponse = this.queueRequest(Command.HINCRBY, keyBytes, entryBytes, Convert.toBytes(increment));
+ return new FutureLong(futureResponse);
+ }
+
public <K extends Object> Future<Boolean> hset(K key, K field, Number numberValue) {
return hset (key, field, String.valueOf(numberValue).getBytes());
}
@@ -1486,6 +1526,26 @@ public Boolean get (long timeout, TimeUnit unit)
return valResp.getBooleanValue();
}
}
+
+ public static class FutureBit extends FutureResultBase implements Future<Boolean> {
+
+ protected FutureBit (Future<Response> pendingRequest) { super(pendingRequest); }
+
+ @SuppressWarnings("boxing")
+ public Boolean get () throws InterruptedException, ExecutionException {
+ ValueResponse valResp = (ValueResponse) pendingRequest.get();
+ return valResp.getLongValue() == 1;
+ }
+
+ @SuppressWarnings("boxing")
+ public Boolean get (long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException
+ {
+ ValueResponse valResp = (ValueResponse) pendingRequest.get(timeout, unit);
+ return valResp.getLongValue() == 1;
+ }
+ }
+
public static class FutureString extends FutureResultBase implements Future<String>{
protected FutureString (Future<Response> pendingRequest) { super(pendingRequest); }
@@ -1779,4 +1839,6 @@ public ObjectInfo get (long timeout, TimeUnit unit)
Future<byte[]> echo (T msg) {
return echo (DefaultCodec.encode(msg));
}
+
+
}
View
36 core/ri/src/main/java/org/jredis/ri/alphazero/JRedisSupport.java
@@ -115,7 +115,41 @@
// ------------------------------------------------------------------------
-// @Override
+ @Override
+ public <K> boolean setbit(K key, int offset, boolean value) throws ProviderException, ClientRuntimeException, RedisException {
+ byte[] keybytes = null;
+ if((keybytes = getKeyBytes(key)) == null)
+ throw new IllegalArgumentException ("invalid key => ["+key+"]");
+
+ /* ValueRespose */
+ try {
+ ValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.SETBIT, keybytes, Convert.toBytes(offset), Convert.toBytes(value ? 1 : 0));
+ return valResponse.getLongValue() == 1;
+ }
+ catch (ClassCastException e){
+ throw new ProviderException("Expecting a ValueResponse here => " + e.getLocalizedMessage(), e);
+ }
+ }
+
+
+ @Override
+ public <K> boolean getbit(K key, int offset) throws ProviderException, ClientRuntimeException, RedisException {
+ byte[] keybytes = null;
+ if((keybytes = getKeyBytes(key)) == null)
+ throw new IllegalArgumentException ("invalid key => ["+key+"]");
+
+ /* ValueRespose */
+ try {
+ ValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.GETBIT, keybytes, Convert.toBytes(offset));
+ return valResponse.getLongValue() == 1;
+ }
+ catch (ClassCastException e){
+ throw new ProviderException("Expecting a ValueResponse here => " + e.getLocalizedMessage(), e);
+ }
+ }
+
+
+ // @Override
// public <K extends Object> JRedis auth(K key) throws RedisException {
// byte[] keydata = null;
// if((keydata = getKeyBytes(key)) == null)
View
58 core/ri/src/test/java/org/jredis/ri/alphazero/JRedisFutureProviderTestsBase.java
@@ -39,6 +39,7 @@
import org.jredis.protocol.Command;
import org.jredis.protocol.ResponseStatus;
import org.jredis.ri.JRedisTestSuiteBase;
+import org.jredis.ri.alphazero.support.Convert;
import org.jredis.ri.alphazero.support.DefaultCodec;
import org.jredis.ri.alphazero.support.Log;
import org.testng.annotations.Test;
@@ -1582,6 +1583,34 @@ public void testHsetHget() throws InterruptedException {
catch (ClientRuntimeException e) { fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e); }
}
+
+ @Test
+ public void testHIncrBy() throws InterruptedException {
+ cmd = Command.HSET.code + " | " + Command.HGET + " | " + Command.HINCRBY;
+ Log.log("TEST: %s command", cmd);
+ try {
+ provider.flushdb();
+ Future<Boolean> hsetResp1 = provider.hset(keys.get(0), keys.get(1), 41);
+ Future<Long> hincrBy1 = provider.hincrby(keys.get(0), keys.get(1), 1);
+ Future<byte[]> hget = provider.hget(keys.get(0), keys.get(1));
+
+ Future<Long> hincrBy2 = provider.hincrby(keys.get(0), keys.get(2), 4);
+
+ try {
+ assertTrue (hsetResp1.get(), "hset using byte[] value");
+ assertEquals (hincrBy1.get(), (Long)42l, "hexists of field should be true");
+ assertEquals(hget.get(), Convert.toBytes(42l));
+ assertEquals(hincrBy2.get(), (Long)4l);
+
+ }
+ catch(ExecutionException e){
+ Throwable cause = e.getCause();
+ fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
+ }
+ }
+ catch (ClientRuntimeException e) { fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e); }
+ }
+
@Test
public void testHkeys() throws InterruptedException {
cmd = Command.HSET.code + " | " + Command.HKEYS;
@@ -1629,6 +1658,35 @@ public void testHkeys() throws InterruptedException {
}
catch (ClientRuntimeException e) { fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e); }
}
+
+ @Test
+ public void testSetBitGetBit() throws InterruptedException {
+ cmd = Command.SETBIT.code + " | " + Command.GETBIT;
+ Log.log("TEST: %s command", cmd);
+ try {
+ provider.flushdb();
+ Future<Boolean> setbit1 = provider.setbit(keys.get(0), 1, true);
+ Future<Boolean> setbit32 = provider.setbit(keys.get(0), 32, true);
+
+ Future<Boolean> getbit1 = provider.getbit(keys.get(0), 1);
+ Future<Boolean> getbit2 = provider.getbit(keys.get(0), 2);
+ Future<Boolean> getbit32 = provider.getbit(keys.get(0), 32);
+
+ try {
+ assertFalse (setbit1.get(), "original bit at 1");
+ assertFalse (setbit32.get(), "original bit at 32");
+ assertTrue (getbit1.get(), "getbit at 1");
+ assertFalse (getbit2.get(), "getbit at 2");
+ assertTrue (getbit32.get(), "getbit at 32");
+ }
+ catch(ExecutionException e){
+ Throwable cause = e.getCause();
+ fail(cmd + " ERROR => " + cause.getLocalizedMessage(), e);
+ }
+ }
+ catch (ClientRuntimeException e) { fail(cmd + " Runtime ERROR => " + e.getLocalizedMessage(), e); }
+ }
+
@Test
public void testHvals() throws InterruptedException {
View
22 core/ri/src/test/java/org/jredis/ri/alphazero/JRedisProviderTestsBase.java
@@ -293,6 +293,28 @@ public void testRename() {
}
catch (RedisException e) { fail(cmd + " ERROR => " + e.getLocalizedMessage(), e); }
}
+
+
+ @Test
+ public void testBitCommands() {
+ cmd = Command.SETBIT.code;
+ Log.log("TEST: %s command", cmd);
+ try {
+ provider.flushdb();
+
+ key = getRandomAsciiString (random.nextInt(24)+2);
+ provider.del(key);
+ provider.setbit(key, 0, true);
+ provider.setbit(key, 32, true);
+ assertEquals(true, provider.getbit(key,0));
+ assertEquals(true, provider.getbit(key,32));
+ assertEquals(false, provider.getbit(key,64));
+ assertEquals(false, provider.getbit(key,1));
+ }
+ catch (RedisException e) { fail(cmd + " ERROR => " + e.getLocalizedMessage(), e); }
+ }
+
+
/**
* Test method for {@link org.jredis.ri.alphazero.JRedisSupport#renamenx(java.lang.String, java.lang.String)}.

0 comments on commit eae3b4a

Please sign in to comment.