Merge branch 'binaryAPI' of git://github.com/yaourt/jedis

Conflicts:
	src/main/java/redis/clients/jedis/Connection.java
	src/main/java/redis/clients/jedis/Jedis.java
	src/main/java/redis/clients/jedis/ShardedJedis.java
This commit is contained in:
Jonathan Leibiusky
2010-11-15 23:55:57 -03:00
41 changed files with 8489 additions and 2326 deletions

View File

@@ -3,13 +3,19 @@ package redis.clients.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import redis.clients.jedis.Protocol;
public interface Hashing {
public static final Hashing MURMUR_HASH = new MurmurHash();
public static final Hashing MD5 = new Hashing() {
private MessageDigest md5 = null; // avoid recurring construction
public long hash(String key) {
return hash(key.getBytes(Protocol.UTF8));
}
public long hash(byte[] key) {
if (md5 == null) {
try {
md5 = MessageDigest.getInstance("MD5");
@@ -20,7 +26,7 @@ public interface Hashing {
}
md5.reset();
md5.update(key.getBytes());
md5.update(key);
byte[] bKey = md5.digest();
long res = ((long) (bKey[3] & 0xFF) << 24)
| ((long) (bKey[2] & 0xFF) << 16)
@@ -30,4 +36,5 @@ public interface Hashing {
};
public long hash(String key);
public long hash(byte[] key);
}

View File

@@ -0,0 +1,148 @@
package redis.clients.util;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class JedisByteHashMap implements Map<byte[], byte[]>, Cloneable,
Serializable {
private static final long serialVersionUID = -6971431362627219416L;
private Map<ByteArrayWrapper, byte[]> internalMap = new HashMap<ByteArrayWrapper, byte[]>();
public void clear() {
internalMap.clear();
}
public boolean containsKey(Object key) {
if (key instanceof byte[])
return internalMap.containsKey(new ByteArrayWrapper((byte[]) key));
return internalMap.containsKey(key);
}
public boolean containsValue(Object value) {
return internalMap.containsValue(value);
}
public Set<java.util.Map.Entry<byte[], byte[]>> entrySet() {
Iterator<java.util.Map.Entry<ByteArrayWrapper, byte[]>> iterator = internalMap
.entrySet().iterator();
HashSet<Entry<byte[], byte[]>> hashSet = new HashSet<java.util.Map.Entry<byte[], byte[]>>();
while (iterator.hasNext()) {
Entry<ByteArrayWrapper, byte[]> entry = iterator.next();
hashSet.add(new JedisByteEntry(entry.getKey().data, entry
.getValue()));
}
return hashSet;
}
@Override
public byte[] get(Object key) {
if (key instanceof byte[])
return internalMap.get(new ByteArrayWrapper((byte[]) key));
return internalMap.get(key);
}
@Override
public boolean isEmpty() {
return internalMap.isEmpty();
}
@Override
public Set<byte[]> keySet() {
Set<byte[]> keySet = new HashSet<byte[]>();
Iterator<ByteArrayWrapper> iterator = internalMap.keySet().iterator();
while (iterator.hasNext()) {
keySet.add(iterator.next().data);
}
return keySet;
}
@Override
public byte[] put(byte[] key, byte[] value) {
return internalMap.put(new ByteArrayWrapper(key), value);
}
@SuppressWarnings("unchecked")
@Override
public void putAll(Map<? extends byte[], ? extends byte[]> m) {
Iterator<?> iterator = m.entrySet().iterator();
while (iterator.hasNext()) {
Entry<? extends byte[], ? extends byte[]> next = (Entry<? extends byte[], ? extends byte[]>) iterator
.next();
internalMap.put(new ByteArrayWrapper(next.getKey()), next
.getValue());
}
}
@Override
public byte[] remove(Object key) {
if (key instanceof byte[])
return internalMap.remove(new ByteArrayWrapper((byte[]) key));
return internalMap.remove(key);
}
@Override
public int size() {
return internalMap.size();
}
@Override
public Collection<byte[]> values() {
return internalMap.values();
}
private final class ByteArrayWrapper {
private final byte[] data;
public ByteArrayWrapper(byte[] data) {
if (data == null) {
throw new NullPointerException();
}
this.data = data;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof ByteArrayWrapper)) {
return false;
}
return Arrays.equals(data, ((ByteArrayWrapper) other).data);
}
@Override
public int hashCode() {
return Arrays.hashCode(data);
}
}
private final class JedisByteEntry implements Entry<byte[], byte[]> {
private byte[] value;
private byte[] key;
public JedisByteEntry(byte[] key, byte[] value) {
this.key = key;
this.value = value;
}
public byte[] getKey() {
return this.key;
}
@Override
public byte[] getValue() {
return this.value;
}
@Override
public byte[] setValue(byte[] value) {
this.value = value;
return value;
}
}
}

View File

@@ -20,6 +20,8 @@ package redis.clients.util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import redis.clients.jedis.Protocol;
/**
* This is a very fast, non-cryptographic hash suitable for general hash-based
* lookup. See http://murmurhash.googlepages.com/ for more details.
@@ -156,7 +158,11 @@ public class MurmurHash implements Hashing {
return h;
}
public long hash(byte[] key) {
return hash64A(key, 0x1234ABCD);
}
public long hash(String key) {
return hash64A(key.getBytes(), 0x1234ABCD);
return hash(key.getBytes(Protocol.UTF8));
}
}

View File

@@ -1,7 +1,6 @@
package redis.clients.util;
import java.io.*;
import java.nio.charset.Charset;
/**
* The class implements a buffered output stream without synchronization
@@ -12,13 +11,12 @@ public final class RedisOutputStream extends FilterOutputStream {
protected final byte buf[];
protected int count;
public static final Charset CHARSET = Charset.forName("UTF-8");
public RedisOutputStream(OutputStream out) {
public RedisOutputStream(final OutputStream out) {
this(out, 8192);
}
public RedisOutputStream(OutputStream out, int size) {
public RedisOutputStream(final OutputStream out, final int size) {
super(out);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
@@ -33,14 +31,18 @@ public final class RedisOutputStream extends FilterOutputStream {
}
}
public void write(int b) throws IOException {
buf[count++] = (byte) b;
public void write(final byte b) throws IOException {
buf[count++] = b;
if (count == buf.length) {
flushBuffer();
}
}
public void write(final byte[] b) throws IOException {
write(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
public void write(final byte b[], final int off, final int len) throws IOException {
if (len >= buf.length) {
flushBuffer();
out.write(b, off, len);
@@ -54,7 +56,7 @@ public final class RedisOutputStream extends FilterOutputStream {
}
}
public void writeAsciiCrLf(String in) throws IOException {
public void writeAsciiCrLf(final String in) throws IOException {
final int size = in.length();
for (int i = 0; i != size; ++i) {
@@ -67,11 +69,11 @@ public final class RedisOutputStream extends FilterOutputStream {
writeCrLf();
}
public static boolean isSurrogate(char ch) {
public static boolean isSurrogate(final char ch) {
return ch >= Character.MIN_SURROGATE && ch <= Character.MAX_SURROGATE;
}
public static int utf8Length (String str) {
public static int utf8Length (final String str) {
int strLen = str.length(), utfLen = 0;
for(int i = 0; i != strLen; ++i) {
char c = str.charAt(i);
@@ -98,7 +100,7 @@ public final class RedisOutputStream extends FilterOutputStream {
buf[count++] = '\n';
}
public void writeUtf8CrLf(String str) throws IOException {
public void writeUtf8CrLf(final String str) throws IOException {
int strLen = str.length();
int i;

View File

@@ -69,10 +69,19 @@ public class Sharded<R, S extends ShardInfo<R>> {
}
}
public R getShard(String key) {
return nodes.floorEntry(algo.hash(getKeyTag(key))).getValue()
.getResource();
}
public R getShard(byte[] key) {
return nodes
.floorEntry(algo.hash(key))
.getValue()
.getResource();
}
public R getShard(String key) {
return nodes
.floorEntry(algo.hash(getKeyTag(key)))
.getValue()
.getResource();
}
public S getShardInfo(String key) {
return nodes.floorEntry(algo.hash(getKeyTag(key))).getValue();