Merge branch 'slowlog' of git://github.com/ivowiblo/jedis into slowlog

Conflicts:
	src/main/java/redis/clients/jedis/BinaryClient.java
	src/main/java/redis/clients/jedis/BinaryJedis.java
	src/main/java/redis/clients/jedis/Jedis.java
	src/main/java/redis/clients/jedis/Protocol.java
This commit is contained in:
Jonathan Leibiusky
2012-04-23 20:35:55 -03:00
6 changed files with 1565 additions and 1415 deletions

View File

@@ -7,6 +7,8 @@ import static redis.clients.jedis.Protocol.Keyword.NO;
import static redis.clients.jedis.Protocol.Keyword.ONE; import static redis.clients.jedis.Protocol.Keyword.ONE;
import static redis.clients.jedis.Protocol.Keyword.STORE; import static redis.clients.jedis.Protocol.Keyword.STORE;
import static redis.clients.jedis.Protocol.Keyword.WITHSCORES; import static redis.clients.jedis.Protocol.Keyword.WITHSCORES;
import static redis.clients.jedis.Protocol.Keyword.RESET;
import static redis.clients.jedis.Protocol.Keyword.LEN;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -249,14 +251,14 @@ public class BinaryClient extends Connection {
} }
public void rpush(final byte[] key, final byte[]... vals) { public void rpush(final byte[] key, final byte[]... vals) {
byte[][] args = new byte[vals.length+1][]; byte[][] args = new byte[vals.length + 1][];
args[0] = key; args[0] = key;
System.arraycopy(vals, 0, args, 1, vals.length); System.arraycopy(vals, 0, args, 1, vals.length);
sendCommand(RPUSH, args); sendCommand(RPUSH, args);
} }
public void lpush(final byte[] key, final byte[]... vals) { public void lpush(final byte[] key, final byte[]... vals) {
byte [][] args = new byte[vals.length+1][]; byte[][] args = new byte[vals.length + 1][];
args[0] = key; args[0] = key;
System.arraycopy(vals, 0, args, 1, vals.length); System.arraycopy(vals, 0, args, 1, vals.length);
sendCommand(LPUSH, args); sendCommand(LPUSH, args);
@@ -725,45 +727,62 @@ public class BinaryClient extends Connection {
super.disconnect(); super.disconnect();
} }
private void sendEvalCommand(Command command, byte[] script, byte[] keyCount, byte[][] params){ private void sendEvalCommand(Command command, byte[] script,
byte[] keyCount, byte[][] params) {
final byte[][] allArgs = new byte[params.length + 2][]; final byte[][] allArgs = new byte[params.length + 2][];
allArgs[0] = script; allArgs[0] = script;
allArgs[1] = keyCount; allArgs[1] = keyCount;
for(int i=0;i<params.length; i++) for (int i = 0; i < params.length; i++)
allArgs[i+2] = params[i]; allArgs[i + 2] = params[i];
sendCommand(command, allArgs ); sendCommand(command, allArgs);
} }
public void eval(byte[] script, byte[] keyCount, byte[][] params){ public void eval(byte[] script, byte[] keyCount, byte[][] params) {
sendEvalCommand(EVAL, script, keyCount, params ); sendEvalCommand(EVAL, script, keyCount, params);
} }
public void evalsha(byte[] sha1, byte[] keyCount, byte[][] params){ public void evalsha(byte[] sha1, byte[] keyCount, byte[][] params) {
sendEvalCommand(EVALSHA, sha1, keyCount, params); sendEvalCommand(EVALSHA, sha1, keyCount, params);
} }
public void scriptFlush(){ public void scriptFlush() {
sendCommand(SCRIPT, Keyword.FLUSH.raw); sendCommand(SCRIPT, Keyword.FLUSH.raw);
} }
public void scriptExists(byte[]... sha1){ public void scriptExists(byte[]... sha1) {
byte[][] args = new byte[sha1.length + 1][]; byte[][] args = new byte[sha1.length + 1][];
args[0] = Keyword.EXISTS.raw; args[0] = Keyword.EXISTS.raw;
for(int i=0;i<sha1.length; i++) for (int i = 0; i < sha1.length; i++)
args[i+1] = sha1[i]; args[i + 1] = sha1[i];
sendCommand(SCRIPT, args); sendCommand(SCRIPT, args);
} }
public void scriptLoad(byte[] script){ public void scriptLoad(byte[] script) {
sendCommand(SCRIPT, Keyword.LOAD.raw, script); sendCommand(SCRIPT, Keyword.LOAD.raw, script);
} }
public void scriptKill(){ public void scriptKill() {
sendCommand(SCRIPT, Keyword.KILL.raw); sendCommand(SCRIPT, Keyword.KILL.raw);
} }
public void slowlogGet() {
sendCommand(SLOWLOG, Keyword.GET.raw);
}
public void slowlogGet(long entries) {
sendCommand(SLOWLOG, Keyword.GET.raw, toByteArray(entries));
}
public void slowlogReset() {
sendCommand(SLOWLOG, RESET.raw);
}
public void slowlogLen() {
sendCommand(SLOWLOG, LEN.raw);
}
} }

View File

@@ -185,8 +185,8 @@ public class BinaryJedis implements BinaryJedisCommands {
public Set<byte[]> keys(final byte[] pattern) { public Set<byte[]> keys(final byte[] pattern) {
checkIsInMulti(); checkIsInMulti();
client.keys(pattern); client.keys(pattern);
final HashSet<byte[]> keySet = new HashSet<byte[]>(client final HashSet<byte[]> keySet = new HashSet<byte[]>(
.getBinaryMultiBulkReply()); client.getBinaryMultiBulkReply());
return keySet; return keySet;
} }
@@ -3012,7 +3012,8 @@ public class BinaryJedis implements BinaryJedisCommands {
} }
/** /**
* Evaluates scripts using the Lua interpreter built into Redis starting from version 2.6.0. * Evaluates scripts using the Lua interpreter built into Redis starting
* from version 2.6.0.
* <p> * <p>
* *
* @return Script result * @return Script result
@@ -3022,41 +3023,63 @@ public class BinaryJedis implements BinaryJedisCommands {
client.eval(script, toByteArray(keys.size()), getParams(keys, args)); client.eval(script, toByteArray(keys.size()), getParams(keys, args));
return client.getOne(); return client.getOne();
} }
private byte[][] getParams(List<byte[]> keys, List<byte[]> args){
private byte[][] getParams(List<byte[]> keys, List<byte[]> args) {
int keyCount = keys.size(); int keyCount = keys.size();
byte[][] params = new byte[keyCount + args.size()][]; byte[][] params = new byte[keyCount + args.size()][];
for(int i=0;i<keyCount;i++) for (int i = 0; i < keyCount; i++)
params[i] = keys.get(i); params[i] = keys.get(i);
for(int i=0;i<keys.size();i++) for (int i = 0; i < keys.size(); i++)
params[keyCount + i] = args.get(i); params[keyCount + i] = args.get(i);
return params; return params;
} }
public Object eval(byte[] script, byte[] keyCount, byte[][] params) { public Object eval(byte[] script, byte[] keyCount, byte[][] params) {
client.setTimeoutInfinite(); client.setTimeoutInfinite();
client.eval(script, keyCount, params); client.eval(script, keyCount, params);
return client.getOne(); return client.getOne();
} }
public byte[] scriptFlush(){ public byte[] scriptFlush() {
client.scriptFlush(); client.scriptFlush();
return client.getBinaryBulkReply(); return client.getBinaryBulkReply();
} }
public List<Long> scriptExists(byte[]... sha1){ public List<Long> scriptExists(byte[]... sha1) {
client.scriptExists(sha1); client.scriptExists(sha1);
return client.getIntegerMultiBulkReply(); return client.getIntegerMultiBulkReply();
} }
public byte[] scriptLoad(byte[] script){ public byte[] scriptLoad(byte[] script) {
client.scriptLoad(script); client.scriptLoad(script);
return client.getBinaryBulkReply(); return client.getBinaryBulkReply();
} }
public byte[] scriptKill(){ public byte[] scriptKill() {
client.scriptKill(); client.scriptKill();
return client.getBinaryBulkReply(); return client.getBinaryBulkReply();
} }
public byte[] slowlogReset() {
client.slowlogReset();
return client.getBinaryBulkReply();
}
public long slowlogLen() {
client.slowlogLen();
return client.getIntegerReply();
}
public List<byte[]> slowlogGetBinary() {
client.slowlogGet();
return client.getBinaryMultiBulkReply();
}
public List<byte[]> slowlogGetBinary(long entries) {
client.slowlogGet(entries);
return client.getBinaryMultiBulkReply();
}
} }

View File

@@ -10,6 +10,7 @@ import java.util.Set;
import redis.clients.jedis.BinaryClient.LIST_POSITION; import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.util.SafeEncoder; import redis.clients.util.SafeEncoder;
import redis.clients.util.Slowlog;
public class Jedis extends BinaryJedis implements JedisCommands { public class Jedis extends BinaryJedis implements JedisCommands {
public Jedis(final String host) { public Jedis(final String host) {
@@ -947,7 +948,8 @@ public class Jedis extends BinaryJedis implements JedisCommands {
* @return Multi bulk reply, specifically a list of elements in the * @return Multi bulk reply, specifically a list of elements in the
* specified range. * specified range.
*/ */
public List<String> lrange(final String key, final long start, final long end) { public List<String> lrange(final String key, final long start,
final long end) {
checkIsInMulti(); checkIsInMulti();
client.lrange(key, start, end); client.lrange(key, start, end);
return client.getMultiBulkReply(); return client.getMultiBulkReply();
@@ -1267,8 +1269,8 @@ public class Jedis extends BinaryJedis implements JedisCommands {
/** /**
* Return the members of a set resulting from the intersection of all the * Return the members of a set resulting from the intersection of all the
* sets hold at the specified keys. Like in * sets hold at the specified keys. Like in
* {@link #lrange(String, long, long) LRANGE} the result is sent to the client * {@link #lrange(String, long, long) LRANGE} the result is sent to the
* as a multi-bulk reply (see the protocol specification for more * client as a multi-bulk reply (see the protocol specification for more
* information). If just a single key is specified, then this command * information). If just a single key is specified, then this command
* produces the same result as {@link #smembers(String) SMEMBERS}. Actually * produces the same result as {@link #smembers(String) SMEMBERS}. Actually
* SMEMBERS is just syntax sugar for SINTER. * SMEMBERS is just syntax sugar for SINTER.
@@ -2253,9 +2255,7 @@ public class Jedis extends BinaryJedis implements JedisCommands {
Set<Tuple> set = new LinkedHashSet<Tuple>(); Set<Tuple> set = new LinkedHashSet<Tuple>();
Iterator<String> iterator = membersWithScores.iterator(); Iterator<String> iterator = membersWithScores.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
set set.add(new Tuple(iterator.next(), Double.valueOf(iterator.next())));
.add(new Tuple(iterator.next(), Double.valueOf(iterator
.next())));
} }
return set; return set;
} }
@@ -2698,16 +2698,16 @@ public class Jedis extends BinaryJedis implements JedisCommands {
return getEvalResult(); return getEvalResult();
} }
private String[] getParams(List<String> keys, List<String> args){ private String[] getParams(List<String> keys, List<String> args) {
int keyCount = keys.size(); int keyCount = keys.size();
int argCount = args.size(); int argCount = args.size();
String[] params = new String[keyCount + args.size()]; String[] params = new String[keyCount + args.size()];
for(int i=0;i<keyCount;i++) for (int i = 0; i < keyCount; i++)
params[i] = keys.get(i); params[i] = keys.get(i);
for(int i=0;i<argCount;i++) for (int i = 0; i < argCount; i++)
params[keyCount + i] = args.get(i); params[keyCount + i] = args.get(i);
return params; return params;
@@ -2718,24 +2718,24 @@ public class Jedis extends BinaryJedis implements JedisCommands {
} }
public Object eval(String script) { public Object eval(String script) {
return eval(script,0); return eval(script, 0);
} }
public Object evalsha(String script) { public Object evalsha(String script) {
return evalsha(script,0); return evalsha(script, 0);
} }
private Object getEvalResult(){ private Object getEvalResult() {
Object result = client.getOne(); Object result = client.getOne();
if(result instanceof byte[]) if (result instanceof byte[])
return SafeEncoder.encode((byte[])result); return SafeEncoder.encode((byte[]) result);
if(result instanceof List<?>) { if (result instanceof List<?>) {
List<?> list = (List<?>)result; List<?> list = (List<?>) result;
List<String> listResult = new ArrayList<String>(list.size()); List<String> listResult = new ArrayList<String>(list.size());
for(Object bin: list) for (Object bin : list)
listResult.add(SafeEncoder.encode((byte[])bin)); listResult.add(SafeEncoder.encode((byte[]) bin));
return listResult; return listResult;
} }
@@ -2754,25 +2754,35 @@ public class Jedis extends BinaryJedis implements JedisCommands {
return getEvalResult(); return getEvalResult();
} }
public Boolean scriptExists(String sha1){ public Boolean scriptExists(String sha1) {
String[] a = new String[1]; String[] a = new String[1];
a[0] = sha1; a[0] = sha1;
return scriptExists(a).get(0); return scriptExists(a).get(0);
} }
public List<Boolean> scriptExists(String... sha1){ public List<Boolean> scriptExists(String... sha1) {
client.scriptExists(sha1); client.scriptExists(sha1);
List<Long> result = client.getIntegerMultiBulkReply(); List<Long> result = client.getIntegerMultiBulkReply();
List<Boolean> exists = new ArrayList<Boolean>(); List<Boolean> exists = new ArrayList<Boolean>();
for(Long value : result) for (Long value : result)
exists.add(value == 1); exists.add(value == 1);
return exists; return exists;
} }
public String scriptLoad(String script){ public String scriptLoad(String script) {
client.scriptLoad(script); client.scriptLoad(script);
return client.getBulkReply(); return client.getBulkReply();
} }
public List<Slowlog> slowlogGet() {
client.slowlogGet();
return Slowlog.from(client.getObjectMultiBulkReply());
}
public List<Slowlog> slowlogGet(long entries) {
client.slowlogGet(entries);
return Slowlog.from(client.getObjectMultiBulkReply());
}
} }

View File

@@ -29,14 +29,12 @@ public final class Protocol {
} }
public static void sendCommand(final RedisOutputStream os, public static void sendCommand(final RedisOutputStream os,
final Command command, final Command command, final byte[]... args) {
final byte[]... args) {
sendCommand(os, command.raw, args); sendCommand(os, command.raw, args);
} }
private static void sendCommand(final RedisOutputStream os, private static void sendCommand(final RedisOutputStream os,
final byte[] command, final byte[] command, final byte[]... args) {
final byte[]... args) {
try { try {
os.write(ASTERISK_BYTE); os.write(ASTERISK_BYTE);
os.writeIntCrLf(args.length + 1); os.writeIntCrLf(args.length + 1);
@@ -120,9 +118,9 @@ public final class Protocol {
} }
List<Object> ret = new ArrayList<Object>(num); List<Object> ret = new ArrayList<Object>(num);
for (int i = 0; i < num; i++) { for (int i = 0; i < num; i++) {
try{ try {
ret.add(process(is)); ret.add(process(is));
}catch(JedisDataException e){ } catch (JedisDataException e) {
ret.add(e); ret.add(e);
} }
} }
@@ -146,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; 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;
public final byte[] raw; public final byte[] raw;
@@ -156,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, FLUSH, EXISTS, LOAD, KILL; 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;
public final byte[] raw; public final byte[] raw;
Keyword() { Keyword() {

View File

@@ -0,0 +1,53 @@
package redis.clients.util;
import java.util.ArrayList;
import java.util.List;
public class Slowlog {
private final long id;
private final long timeStamp;
private final long executionTime;
private final List<String> args;
@SuppressWarnings("unchecked")
public static List<Slowlog> from(List<Object> nestedMultiBulkReply){
List<Slowlog> logs = new ArrayList<Slowlog>(nestedMultiBulkReply.size());
for(Object obj : nestedMultiBulkReply){
List<Object> properties = (List<Object>)obj;
logs.add(new Slowlog(properties));
}
return logs;
}
@SuppressWarnings("unchecked")
private Slowlog(List<Object> properties) {
super();
this.id = (Long)properties.get(0);
this.timeStamp = (Long)properties.get(1);
this.executionTime = (Long)properties.get(2);
List<byte[]> bargs = (List<byte[]>)properties.get(3);
this.args = new ArrayList<String>(bargs.size());
for(byte[] barg:bargs){
this.args.add(SafeEncoder.encode(barg));
}
}
public long getId() {
return id;
}
public long getTimeStamp() {
return timeStamp;
}
public long getExecutionTime() {
return executionTime;
}
public List<String> getArgs() {
return args;
}
}

View File

@@ -0,0 +1,47 @@
package redis.clients.jedis.tests.commands;
import java.util.List;
import org.junit.Test;
import redis.clients.util.Slowlog;
public class SlowlogCommandsTest extends JedisCommandTestBase {
@Test
public void slowlog() {
//do something
jedis.set("foo", "bar");
jedis.set("foo2", "bar2");
List<Slowlog> reducedLog = jedis.slowlogGet(1);
assertEquals(1, reducedLog.size());
Slowlog log = reducedLog.get(0);
assertTrue(log.getId() > 0);
assertTrue(log.getTimeStamp() > 0);
assertTrue(log.getExecutionTime() > 0);
assertNotNull(log.getArgs());
List<byte[]> breducedLog = jedis.slowlogGetBinary(1);
assertEquals(1, breducedLog.size());
List<Slowlog> log1 = jedis.slowlogGet();
List<byte[]> blog1 = jedis.slowlogGetBinary();
assertNotNull(log1);
assertNotNull(blog1);
long len1 = jedis.slowlogLen();
jedis.slowlogReset();
List<Slowlog> log2 = jedis.slowlogGet();
List<byte[]> blog2 = jedis.slowlogGetBinary();
long len2 = jedis.slowlogLen();
assertTrue(len1 > len2);
assertTrue(log1.size() > log2.size());
assertTrue(blog1.size() > blog2.size());
}
}