com.logicbus.kvalue.common.ConsistentHash Maven / Gradle / Ivy
package com.logicbus.kvalue.common;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Enumeration;
import java.util.SortedMap;
import java.util.TreeMap;
import org.w3c.dom.Element;
import com.anysoft.util.Properties;
import com.anysoft.util.PropertiesConstants;
/**
* 一致性Hash算法实现
* @author duanyy
*
*/
public class ConsistentHash extends AbstractPartitioner {
protected int vnodesPerNode = 128;
protected TreeMap nodes = new TreeMap();
protected String getPartitionCase(String key) {
SortedMap tail = nodes.tailMap(hash(key));
if (tail == null || tail.size() == 0){
return nodes.get(nodes.firstKey());
}
return tail.get(tail.firstKey());
}
protected void onConfigure(Element _e, Properties _p) {
vnodesPerNode = PropertiesConstants.getInt(_p, "vnodesPerNode", vnodesPerNode,true);
vnodesPerNode = vnodesPerNode <= 0 ? 128 : vnodesPerNode;
Enumeration cases = partitions.keys();
while (cases.hasMoreElements()){
String _case = cases.nextElement();
for (int i = 0 ;i < vnodesPerNode ; i ++){
Long _key = hash(_case + "vnode" + i);
nodes.put(_key, _case);
}
}
}
/**
* MurMurHash算法实现
* @param key
* @return Hash值
*/
static protected Long hash(String key) {
ByteBuffer buf = ByteBuffer.wrap(key.getBytes());
int seed = 0x1234ABCD;
ByteOrder byteOrder = buf.order();
buf.order(ByteOrder.LITTLE_ENDIAN);
long m = 0xc6a4a7935bd1e995L;
int r = 47;
long h = seed ^ (buf.remaining() * m);
long k;
while (buf.remaining() >= 8) {
k = buf.getLong();
k *= m;
k ^= k >>> r;
k *= m;
h ^= k;
h *= m;
}
if (buf.remaining() > 0) {
ByteBuffer finish = ByteBuffer.allocate(8).order(
ByteOrder.LITTLE_ENDIAN);
finish.put(buf).rewind();
h ^= finish.getLong();
h *= m;
}
h ^= h >>> r;
h *= m;
h ^= h >>> r;
buf.order(byteOrder);
return h;
}
}