2016-08-15 22:52:09 +08:00
|
|
|
|
package hashring
|
|
|
|
|
|
|
|
|
|
import (
|
2020-02-15 22:26:47 +08:00
|
|
|
|
"crypto/sha1"
|
2019-12-21 21:32:02 +08:00
|
|
|
|
"fmt"
|
|
|
|
|
"regexp"
|
|
|
|
|
"runtime"
|
|
|
|
|
"strconv"
|
2016-08-15 22:52:09 +08:00
|
|
|
|
"testing"
|
2019-12-21 21:32:02 +08:00
|
|
|
|
"time"
|
2016-08-15 22:52:09 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
node1 = "192.168.1.1"
|
|
|
|
|
node2 = "192.168.1.2"
|
|
|
|
|
node3 = "192.168.1.3"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func getNodesCount(nodes nodesArray) (int, int, int) {
|
|
|
|
|
node1Count := 0
|
|
|
|
|
node2Count := 0
|
|
|
|
|
node3Count := 0
|
|
|
|
|
|
|
|
|
|
for _, node := range nodes {
|
|
|
|
|
if node.nodeKey == node1 {
|
|
|
|
|
node1Count += 1
|
|
|
|
|
}
|
|
|
|
|
if node.nodeKey == node2 {
|
|
|
|
|
node2Count += 1
|
|
|
|
|
}
|
|
|
|
|
if node.nodeKey == node3 {
|
|
|
|
|
node3Count += 1
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return node1Count, node2Count, node3Count
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestHash(t *testing.T) {
|
|
|
|
|
|
|
|
|
|
nodeWeight := make(map[string]int)
|
|
|
|
|
nodeWeight[node1] = 2
|
|
|
|
|
nodeWeight[node2] = 2
|
|
|
|
|
nodeWeight[node3] = 3
|
|
|
|
|
vitualSpots := 100
|
|
|
|
|
|
|
|
|
|
hash := NewHashRing(vitualSpots)
|
|
|
|
|
|
|
|
|
|
hash.AddNodes(nodeWeight)
|
|
|
|
|
if hash.GetNode("1") != node3 {
|
|
|
|
|
t.Fatalf("expetcd %v got %v", node3, hash.GetNode("1"))
|
|
|
|
|
}
|
|
|
|
|
if hash.GetNode("2") != node3 {
|
|
|
|
|
t.Fatalf("expetcd %v got %v", node3, hash.GetNode("2"))
|
|
|
|
|
}
|
|
|
|
|
if hash.GetNode("3") != node2 {
|
|
|
|
|
t.Fatalf("expetcd %v got %v", node2, hash.GetNode("3"))
|
|
|
|
|
}
|
|
|
|
|
c1, c2, c3 := getNodesCount(hash.nodes)
|
|
|
|
|
t.Logf("len of nodes is %v after AddNodes node1:%v, node2:%v, node3:%v", len(hash.nodes), c1, c2, c3)
|
|
|
|
|
|
|
|
|
|
hash.RemoveNode(node3)
|
|
|
|
|
if hash.GetNode("1") != node1 {
|
|
|
|
|
t.Fatalf("expetcd %v got %v", node1, hash.GetNode("1"))
|
|
|
|
|
}
|
|
|
|
|
if hash.GetNode("2") != node2 {
|
|
|
|
|
t.Fatalf("expetcd %v got %v", node1, hash.GetNode("2"))
|
|
|
|
|
}
|
|
|
|
|
if hash.GetNode("3") != node2 {
|
|
|
|
|
t.Fatalf("expetcd %v got %v", node2, hash.GetNode("3"))
|
|
|
|
|
}
|
|
|
|
|
c1, c2, c3 = getNodesCount(hash.nodes)
|
|
|
|
|
t.Logf("len of nodes is %v after RemoveNode node1:%v, node2:%v, node3:%v", len(hash.nodes), c1, c2, c3)
|
|
|
|
|
|
|
|
|
|
hash.AddNode(node3, 3)
|
|
|
|
|
if hash.GetNode("1") != node3 {
|
|
|
|
|
t.Fatalf("expetcd %v got %v", node3, hash.GetNode("1"))
|
|
|
|
|
}
|
|
|
|
|
if hash.GetNode("2") != node3 {
|
|
|
|
|
t.Fatalf("expetcd %v got %v", node3, hash.GetNode("2"))
|
|
|
|
|
}
|
|
|
|
|
if hash.GetNode("3") != node2 {
|
|
|
|
|
t.Fatalf("expetcd %v got %v", node2, hash.GetNode("3"))
|
|
|
|
|
}
|
|
|
|
|
c1, c2, c3 = getNodesCount(hash.nodes)
|
|
|
|
|
t.Logf("len of nodes is %v after AddNode node1:%v, node2:%v, node3:%v", len(hash.nodes), c1, c2, c3)
|
|
|
|
|
|
|
|
|
|
}
|
2019-12-21 21:32:02 +08:00
|
|
|
|
|
|
|
|
|
func TimeTrack(start time.Time) {
|
|
|
|
|
elapsed := time.Since(start)
|
|
|
|
|
|
|
|
|
|
// Skip this function, and fetch the PC and file for its parent.
|
|
|
|
|
pc, _, _, _ := runtime.Caller(1)
|
|
|
|
|
|
|
|
|
|
// Retrieve a function object this functions parent.
|
|
|
|
|
funcObj := runtime.FuncForPC(pc)
|
|
|
|
|
|
|
|
|
|
// Regex to extract just the function name (and not the module path).
|
|
|
|
|
runtimeFunc := regexp.MustCompile(`^.*\.(.*)$`)
|
|
|
|
|
name := runtimeFunc.ReplaceAllString(funcObj.Name(), "$1")
|
|
|
|
|
|
|
|
|
|
fmt.Printf("TimeTrack funcName:%s elapsed:%s \n", name, elapsed)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestSpeed(t *testing.T) {
|
2019-12-21 21:35:32 +08:00
|
|
|
|
// node=1000 v=50000 on 8GB/win10/i7 init 35s
|
2019-12-21 21:32:02 +08:00
|
|
|
|
defer TimeTrack(time.Now())
|
|
|
|
|
nodeWeight := make(map[string]int)
|
|
|
|
|
for i := 0; i < 1000; i += 1 {
|
|
|
|
|
nodeWeight[strconv.Itoa(i)] = 1
|
|
|
|
|
}
|
|
|
|
|
vitualSpots := 50000
|
|
|
|
|
hash := NewHashRing(vitualSpots)
|
|
|
|
|
|
|
|
|
|
hash.AddNodes(nodeWeight)
|
|
|
|
|
}
|
2020-02-15 22:26:47 +08:00
|
|
|
|
|
|
|
|
|
func TestManyTime(t *testing.T) {
|
|
|
|
|
// 一个9064767行的文件 每行做hashring,结果不一致 原因hashBytes只取4位 529和83 一致 ,这个库是一对多的关系,非多对一
|
|
|
|
|
// node=1000 vitualSpots=20000
|
|
|
|
|
//9063340 key=49f57cf0 node=529
|
|
|
|
|
//9063340 key=49f57cf0 node=83
|
|
|
|
|
|
|
|
|
|
hash := sha1.New()
|
|
|
|
|
hash.Write([]byte("529" + ":" + strconv.Itoa(1)))
|
|
|
|
|
hashBytes := hash.Sum(nil)
|
|
|
|
|
a := hashBytes[6:10]
|
|
|
|
|
|
|
|
|
|
hash2 := sha1.New()
|
|
|
|
|
hash2.Write([]byte("83" + ":" + strconv.Itoa(1)))
|
|
|
|
|
hashBytes2 := hash.Sum(nil)
|
|
|
|
|
a2 := hashBytes2[6:10]
|
|
|
|
|
|
|
|
|
|
fmt.Printf("%s %s\n", a, a2)
|
|
|
|
|
|
|
|
|
|
//defer TimeTrack(time.Now())
|
|
|
|
|
//nodeWeight := make(map[string]int)
|
|
|
|
|
//for i := 0; i < 1000; i += 1 {
|
|
|
|
|
// nodeWeight[strconv.Itoa(i)] = 1
|
|
|
|
|
//}
|
|
|
|
|
//vitualSpots := 20000
|
|
|
|
|
//hash := NewHashRing(vitualSpots)
|
|
|
|
|
//hash.AddNodes(nodeWeight)
|
|
|
|
|
//for _, nn := range hash.nodes {
|
|
|
|
|
// if "529" != nn.nodeKey {
|
|
|
|
|
// fmt.Printf("529 %s\n", nn.nodeKey)
|
|
|
|
|
// }
|
|
|
|
|
// if "83" != nn.nodeKey {
|
|
|
|
|
// fmt.Printf("83 %s\n", nn.nodeKey)
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
//for i := 0; i <= 906476700; i++ {
|
|
|
|
|
// node := hash.GetNode("49f57cf0")
|
|
|
|
|
// if "83" != node {
|
|
|
|
|
// t.Errorf("err:%s\n", node)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
}
|