Skip to content

Commit

Permalink
Merge pull request crossoverJie#147 from baiyina/Modify-the-consisten…
Browse files Browse the repository at this point in the history
…t-hash

Modify the consistent hash
  • Loading branch information
crossoverJie authored Sep 12, 2024
2 parents 7db4b55 + 758cfeb commit 8703c9c
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ public abstract class AbstractConsistentHash {
*/
protected abstract void add(long key,String value);

/**
* Clear old data in the structure
*/
protected abstract void clear();

/**
* 排序节点,数据结构自身支持排序可以不用重写
*/
Expand All @@ -40,7 +45,8 @@ protected void sort(){}
* @return
*/
public String process(List<String> values,String key){

// fix https://github.com/crossoverJie/cim/issues/79
clear();
for (String value : values) {
add(hash(value), value);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.crossoverjie.cim.common.route.algorithm.consistenthash;

import com.crossoverjie.cim.common.data.construct.SortArrayMap;
import com.google.common.annotations.VisibleForTesting;

import java.util.TreeMap;

/**
* Function:自定义排序 Map 实现
Expand All @@ -20,8 +23,6 @@ public class SortArrayMapConsistentHash extends AbstractConsistentHash {

@Override
public void add(long key, String value) {
// fix https://github.com/crossoverJie/cim/issues/79
sortArrayMap.clear();
for (int i = 0; i < VIRTUAL_NODE_SIZE; i++) {
Long hash = super.hash("vir" + key + i);
sortArrayMap.add(hash,value);
Expand All @@ -34,6 +35,20 @@ public void sort() {
sortArrayMap.sort();
}

/**
* Used only in test.
* @return Return the data structure of the current algorithm.
*/
@VisibleForTesting
public SortArrayMap getSortArrayMap() {
return sortArrayMap;
}

@Override
protected void clear() {
sortArrayMap.clear();
}

@Override
public String getFirstNodeValue(String value) {
long hash = super.hash(value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.crossoverjie.cim.common.enums.StatusEnum;
import com.crossoverjie.cim.common.exception.CIMException;
import com.google.common.annotations.VisibleForTesting;

import java.util.SortedMap;
import java.util.TreeMap;
Expand All @@ -23,16 +24,27 @@ public class TreeMapConsistentHash extends AbstractConsistentHash {

@Override
public void add(long key, String value) {

// fix https://github.com/crossoverJie/cim/issues/79
treeMap.clear();
for (int i = 0; i < VIRTUAL_NODE_SIZE; i++) {
Long hash = super.hash("vir" + key + i);
treeMap.put(hash,value);
}
treeMap.put(key, value);
}

@Override
protected void clear() {
treeMap.clear();
}

/**
* Used only in test.
* @return Return the data structure of the current algorithm.
*/
@VisibleForTesting
public TreeMap getTreeMap() {
return treeMap;
}

@Override
public String getFirstNodeValue(String value) {
long hash = super.hash(value);
Expand All @@ -46,4 +58,5 @@ public String getFirstNodeValue(String value) {
}
return treeMap.firstEntry().getValue();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.crossoverjie.cim.common.route.algorithm.consistenthash;

import org.junit.Assert;

/**
* @description: TODO
* @author: zhangguoa
* @date: 2024/9/12 9:58
* @project: cim
*/
public class RangeCheckTestUtil {
public static void assertInRange (int value, int l, int r) {
Assert.assertTrue(value >= l && value <= r);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package com.crossoverjie.cim.common.route.algorithm.consistenthash;

import com.crossoverjie.cim.common.data.construct.SortArrayMap;
import org.junit.Assert;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.lang.reflect.Field;
import java.util.*;

public class SortArrayMapConsistentHashTest {

Expand All @@ -16,10 +17,11 @@ public void getFirstNodeValue() {
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
String process = map.process(strings,"zhangsan");
System.out.println(process);
Assert.assertEquals("127.0.0.9",process);

String PROCESS = map.process(strings, "zhangsan");
for (int i = 0; i < 100; i++) {
String process = map.process(strings, "zhangsan");
Assert.assertEquals(PROCESS, process);
}
}

@Test
Expand All @@ -30,10 +32,12 @@ public void getFirstNodeValue2() {
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
String process = map.process(strings,"zhangsan2");
System.out.println(process);

Assert.assertEquals("127.0.0.9",process);
String PROCESS = map.process(strings,"zhangsan2");
for (int i = 0; i < 100; i++) {
String process = map.process(strings, "zhangsan2");
Assert.assertEquals(PROCESS, process);
}
}

@Test
Expand All @@ -44,10 +48,11 @@ public void getFirstNodeValue3() {
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
String process = map.process(strings,"1551253899106");

System.out.println(process);
Assert.assertEquals("127.0.0.9",process);
String PROCESS = map.process(strings,"1551253899106");
for (int i = 0; i < 100; i++) {
String process = map.process(strings, "1551253899106");
Assert.assertEquals(PROCESS, process);
}
}


Expand All @@ -59,10 +64,12 @@ public void getFirstNodeValue4() {
strings.add("45.78.28.220:9000:8081") ;
strings.add("45.78.28.220:9100:9081") ;

String process = map.process(strings,"1551253899106");

System.out.println(process);
Assert.assertEquals("45.78.28.220:9100:9081",process);
String PROCESS = map.process(strings,"1551253899106");
for (int i = 0; i < 100; i++) {
String process = map.process(strings, "1551253899106");
Assert.assertEquals(PROCESS, process);
}
}
@Test
public void getFirstNodeValue5() {
Expand All @@ -73,10 +80,11 @@ public void getFirstNodeValue5() {
strings.add("45.78.28.220:9100:9081") ;
strings.add("45.78.28.220:9100:10081") ;

String process = map.process(strings,"1551253899106");

System.out.println(process);
Assert.assertEquals("45.78.28.220:9100:10081",process);
String PROCESS = map.process(strings,"1551253899106");
for (int i = 0; i < 100; i++) {
String process = map.process(strings, "1551253899106");
Assert.assertEquals(PROCESS, process);
}
}

@Test
Expand All @@ -88,10 +96,11 @@ public void getFirstNodeValue6() {
strings.add("45.78.28.220:9100:9081") ;
strings.add("45.78.28.220:9100:10081") ;

String process = map.process(strings,"1551253899106");

System.out.println(process);
Assert.assertEquals("45.78.28.220:9100:10081",process);
String PROCESS = map.process(strings,"1551253899106");
for (int i = 0; i < 100; i++) {
String process = map.process(strings, "1551253899106");
Assert.assertEquals(PROCESS, process);
}
}
@Test
public void getFirstNodeValue7() {
Expand All @@ -103,12 +112,45 @@ public void getFirstNodeValue7() {
strings.add("45.78.28.220:9100:10081") ;
strings.add("45.78.28.220:9100:00081") ;

String process = map.process(strings,"1551253899106");
String PROCESS = map.process(strings,"1551253899106");
for (int i = 0; i < 100; i++) {
String process = map.process(strings, "1551253899106");
Assert.assertEquals(PROCESS, process);
}
}

@Test
public void getFirstNodeValue8() {
AbstractConsistentHash map = new SortArrayMapConsistentHash() ;

System.out.println(process);
Assert.assertEquals("45.78.28.220:9100:00081",process);
List<String> strings = new ArrayList<>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i);
}
Set<String> processes = new HashSet<>();
for (int i = 0; i < 10; i++) {
String process = map.process(strings,"zhangsan" + i);
processes.add(process);
}
RangeCheckTestUtil.assertInRange(processes.size(), 2, 10);
}

@Test
public void testVirtualNode() throws NoSuchFieldException, IllegalAccessException {
SortArrayMapConsistentHash map = new SortArrayMapConsistentHash();

List<String> strings = new ArrayList<>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i);
}

String process = map.process(strings,"zhangsan");

SortArrayMap sortArrayMap = map.getSortArrayMap();
int virtualNodeSize = 2;

System.out.println("sortArrayMapSize = " + sortArrayMap.size() + "\n" + "virtualNodeSize = " + virtualNodeSize);
Assert.assertEquals(sortArrayMap.size(), (virtualNodeSize + 1) * 10);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import org.junit.Assert;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.lang.reflect.Field;
import java.util.*;

public class TreeMapConsistentHashTest {



@Test
public void getFirstNodeValue() {
AbstractConsistentHash map = new TreeMapConsistentHash() ;
Expand All @@ -16,9 +18,11 @@ public void getFirstNodeValue() {
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
String process = map.process(strings,"zhangsan");
System.out.println(process);
Assert.assertEquals("127.0.0.9",process);
String PROCESS = map.process(strings, "zhangsan");
for (int i = 0; i < 100; i++) {
String process = map.process(strings, "zhangsan");
Assert.assertEquals(PROCESS, process);
}
}


Expand All @@ -31,10 +35,11 @@ public void getFirstNodeValue2() {
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
String process = map.process(strings,"zhangsan2");
System.out.println(process);

Assert.assertEquals("127.0.0.9",process);
String PROCESS = map.process(strings,"zhangsan2");
for (int i = 0; i < 100; i++) {
String process = map.process(strings, "zhangsan2");
Assert.assertEquals(PROCESS, process);
}
}


Expand All @@ -46,9 +51,44 @@ public void getFirstNodeValue3() {
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
String process = map.process(strings,"1551253899106");
String PROCESS = map.process(strings,"1551253899106");
for (int i = 0; i < 100; i++) {
String process = map.process(strings, "1551253899106");
Assert.assertEquals(PROCESS, process);
}
}

@Test
public void getFirstNodeValue4() {
AbstractConsistentHash map = new TreeMapConsistentHash() ;

List<String> strings = new ArrayList<>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i);
}
Set<String> processes = new HashSet<>();
for (int i = 0; i < 10; i++) {
String process = map.process(strings,"zhangsan" + i);
processes.add(process);
}
RangeCheckTestUtil.assertInRange(processes.size(), 2, 10);
}

@Test
public void testVirtualNode() throws NoSuchFieldException, IllegalAccessException {
TreeMapConsistentHash map = new TreeMapConsistentHash();

List<String> strings = new ArrayList<>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i);
}

String process = map.process(strings,"zhangsan");

TreeMap treeMap = map.getTreeMap();
int virtualNodeSize = 2;

System.out.println(process);
Assert.assertEquals("127.0.0.9",process);
System.out.println("treeMapSize = " + treeMap.size() + "\n" + "virtualNodeSize = " + virtualNodeSize);
Assert.assertEquals(treeMap.size(), (virtualNodeSize + 1) * 10);
}
}

0 comments on commit 8703c9c

Please sign in to comment.