作者 crossoverJie

:sparkles: Introducing new features.两种一致性hash 算法

... ... @@ -21,7 +21,7 @@ public class SortArrayMap {
buckets = new Node[DEFAULT_SIZE];
}
public void add(int key, String value) {
public void add(Long key, String value) {
checkSize(size + 1);
Node node = new Node(key, value);
buckets[size++] = node;
... ... @@ -36,7 +36,7 @@ public class SortArrayMap {
}
}
public String firstNodeValue(int key) {
public String firstNodeValue(long key) {
if (size == 0){
return null ;
}
... ... @@ -86,10 +86,10 @@ public class SortArrayMap {
* 数据节点
*/
private class Node {
public int key;
public Long key;
public String value;
public Node(int key, String value) {
public Node(Long key, String value) {
this.key = key;
this.value = value;
}
... ...
package com.crossoverjie.cim.common.route.algorithm;
/**
* Function:
*
* @author crossoverJie
* Date: 2019-02-27 00:31
* @since JDK 1.8
*/
public interface RouteHandle {
String selectServer() ;
}
... ...
package com.crossoverjie.cim.common.route.algorithm.consistenthash;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
/**
* Function:
*
* @author crossoverJie
* Date: 2019-02-27 00:35
* @since JDK 1.8
*/
public abstract class AbstractConsistentHash {
protected void add(long key,String value){}
protected void sort(){}
/**
* 根据当前的
* @param value
* @return
*/
protected String getFirstNodeValue(String value){
return null ;
}
public void process(List<String> values){
for (String value : values) {
add(hash(value), value);
}
sort();
}
/**
* hash 运算
* @param value
* @return
*/
public Long hash(String value){
MessageDigest md5;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5 not supported", e);
}
md5.reset();
byte[] keyBytes = null;
try {
keyBytes = value.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unknown string :" + value, e);
}
md5.update(keyBytes);
byte[] digest = md5.digest();
// hash code, Truncate to 32-bits
long hashCode = ((long) (digest[3] & 0xFF) << 24)
| ((long) (digest[2] & 0xFF) << 16)
| ((long) (digest[1] & 0xFF) << 8)
| (digest[0] & 0xFF);
long truncateHashCode = hashCode & 0xffffffffL;
return truncateHashCode;
}
}
... ...
package com.crossoverjie.cim.common.route.algorithm.consistenthash;
import com.crossoverjie.cim.common.route.algorithm.RouteHandle;
/**
* Function:
*
* @author crossoverJie
* Date: 2019-02-27 00:33
* @since JDK 1.8
*/
public class ConsistentHashHandle implements RouteHandle {
@Override
public String selectServer() {
return null;
}
}
... ...
package com.crossoverjie.cim.common.route.algorithm.consistenthash;
import com.crossoverjie.cim.common.data.construct.SortArrayMap;
/**
* Function:
*
* @author crossoverJie
* Date: 2019-02-27 00:38
* @since JDK 1.8
*/
public class SortArrayMapConsistentHash extends AbstractConsistentHash {
private SortArrayMap sortArrayMap = new SortArrayMap();
@Override
protected void add(long key, String value) {
sortArrayMap.add(key, value);
}
@Override
protected void sort() {
sortArrayMap.sort();
sortArrayMap.print();
}
@Override
protected String getFirstNodeValue(String value) {
long hash = super.hash(value);
System.out.println("value=" + value + " hash = " + hash);
return sortArrayMap.firstNodeValue(hash);
}
}
... ...
package com.crossoverjie.cim.common.route.algorithm.consistenthash;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* Function:
*
* @author crossoverJie
* Date: 2019-02-27 01:16
* @since JDK 1.8
*/
public class TreeMapConsistentHash extends AbstractConsistentHash {
private TreeMap<Long,String> treeMap = new TreeMap<Long, String>() ;
@Override
protected void add(long key, String value) {
treeMap.put(key, value);
}
@Override
protected void sort() {
}
@Override
protected String getFirstNodeValue(String value) {
long hash = super.hash(value);
System.out.println("value=" + value + " hash = " + hash);
SortedMap<Long, String> last = treeMap.tailMap(hash);
if (!last.isEmpty()) {
return last.get(last.firstKey());
}
return treeMap.firstEntry().getValue();
}
}
... ...
... ... @@ -8,7 +8,7 @@ public class SortArrayMapTest {
public void ad() {
SortArrayMap map = new SortArrayMap() ;
for (int i = 0; i < 9; i++) {
map.add(i ,"127.0.0." + i);
map.add(Long.valueOf(i) ,"127.0.0." + i);
}
map.print();
System.out.println(map.size());
... ... @@ -18,7 +18,7 @@ public class SortArrayMapTest {
public void add() {
SortArrayMap map = new SortArrayMap() ;
for (int i = 0; i < 10; i++) {
map.add(i ,"127.0.0." + i);
map.add(Long.valueOf(i) ,"127.0.0." + i);
}
map.print();
System.out.println(map.size());
... ... @@ -28,7 +28,7 @@ public class SortArrayMapTest {
public void add2() {
SortArrayMap map = new SortArrayMap() ;
for (int i = 0; i < 20; i++) {
map.add(i ,"127.0.0." + i);
map.add(Long.valueOf(i) ,"127.0.0." + i);
}
map.sort();
map.print();
... ... @@ -39,10 +39,10 @@ public class SortArrayMapTest {
public void add3() {
SortArrayMap map = new SortArrayMap() ;
map.add(100,"127.0.0.100");
map.add(10,"127.0.0.10");
map.add(8,"127.0.0.8");
map.add(1000,"127.0.0.1000");
map.add(100L,"127.0.0.100");
map.add(10L,"127.0.0.10");
map.add(8L,"127.0.0.8");
map.add(1000L,"127.0.0.1000");
map.print();
System.out.println(map.size());
... ... @@ -52,10 +52,10 @@ public class SortArrayMapTest {
public void firstNode() {
SortArrayMap map = new SortArrayMap() ;
map.add(100,"127.0.0.100");
map.add(10,"127.0.0.10");
map.add(8,"127.0.0.8");
map.add(1000,"127.0.0.1000");
map.add(100L,"127.0.0.100");
map.add(10L,"127.0.0.10");
map.add(8L,"127.0.0.8");
map.add(1000L,"127.0.0.1000");
map.sort();
map.print();
... ... @@ -66,10 +66,10 @@ public class SortArrayMapTest {
public void firstNode2() {
SortArrayMap map = new SortArrayMap() ;
map.add(100,"127.0.0.100");
map.add(10,"127.0.0.10");
map.add(8,"127.0.0.8");
map.add(1000,"127.0.0.1000");
map.add(100L,"127.0.0.100");
map.add(10L,"127.0.0.10");
map.add(8L,"127.0.0.8");
map.add(1000L,"127.0.0.1000");
map.sort();
map.print();
... ... @@ -80,10 +80,10 @@ public class SortArrayMapTest {
public void firstNode3() {
SortArrayMap map = new SortArrayMap() ;
map.add(100,"127.0.0.100");
map.add(10,"127.0.0.10");
map.add(8,"127.0.0.8");
map.add(1000,"127.0.0.1000");
map.add(100L,"127.0.0.100");
map.add(10L,"127.0.0.10");
map.add(8L,"127.0.0.8");
map.add(1000L,"127.0.0.1000");
map.sort();
map.print();
... ... @@ -94,10 +94,10 @@ public class SortArrayMapTest {
public void firstNode4() {
SortArrayMap map = new SortArrayMap() ;
map.add(100,"127.0.0.100");
map.add(10,"127.0.0.10");
map.add(8,"127.0.0.8");
map.add(1000,"127.0.0.1000");
map.add(100L,"127.0.0.100");
map.add(10L,"127.0.0.10");
map.add(8L,"127.0.0.8");
map.add(1000L,"127.0.0.1000");
map.sort();
map.print();
... ... @@ -109,10 +109,10 @@ public class SortArrayMapTest {
public void add4() {
SortArrayMap map = new SortArrayMap() ;
map.add(100,"127.0.0.100");
map.add(10,"127.0.0.10");
map.add(8,"127.0.0.8");
map.add(1000,"127.0.0.1000");
map.add(100L,"127.0.0.100");
map.add(10L,"127.0.0.10");
map.add(8L,"127.0.0.8");
map.add(1000L,"127.0.0.1000");
map.sort();
map.print();
... ... @@ -129,7 +129,7 @@ public class SortArrayMapTest {
for (int i = 0; i < count; i++) {
double d = Math.random();
int ran = (int)(d*100);
map.add(i + ran ,"127.0.0." + i);
map.add(Long.valueOf(i + ran) ,"127.0.0." + i);
}
map.sort();
long end = System.currentTimeMillis() ;
... ... @@ -148,7 +148,7 @@ public class SortArrayMapTest {
for (int i = 0; i < count; i++) {
double d = Math.random();
int ran = (int)(d*100);
map.add(i + ran ,"127.0.0." + i);
map.add(Long.valueOf(i + ran) ,"127.0.0." + i);
}
long end = System.currentTimeMillis() ;
System.out.println("不排耗时 " + (end -star));
... ...
package com.crossoverjie.cim.common.route.algorithm.consistenthash;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.*;
public class SortArrayMapConsistentHashTest {
@Test
public void getFirstNodeValue() {
AbstractConsistentHash map = new SortArrayMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
map.process(strings);
String firstNodeValue = map.getFirstNodeValue("zhangsan");
System.out.println(firstNodeValue);
}
@Test
public void getFirstNodeValue2() {
AbstractConsistentHash map = new SortArrayMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
map.process(strings);
String firstNodeValue = map.getFirstNodeValue("zhangsan2");
System.out.println(firstNodeValue);
}
}
\ No newline at end of file
... ...
package com.crossoverjie.cim.common.route.algorithm.consistenthash;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class TreeMapConsistentHashTest {
@Test
public void getFirstNodeValue() {
AbstractConsistentHash map = new TreeMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
map.process(strings);
String firstNodeValue = map.getFirstNodeValue("zhangsan");
System.out.println(firstNodeValue);
}
@Test
public void getFirstNodeValue2() {
AbstractConsistentHash map = new TreeMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
map.process(strings);
String firstNodeValue = map.getFirstNodeValue("zhangsan2");
System.out.println(firstNodeValue);
}
}
\ No newline at end of file
... ...