This commit is contained in:
joy 2020-04-13 08:58:13 +08:00 committed by GitHub
commit 4e0e538159
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 115 additions and 6 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.idea
*.exe
demo
etc/*.conf
etc/*.cfg

View File

@ -36,3 +36,9 @@ hash.AddNode("node3", 3)
node := hash.GetNode("key")
```
坑点:
// 一个9064767行的文件 每行做hashring结果不一致 原因hashBytes只取4位 529和83 一致 ,这个库是一对多的关系,非多对一
// node=1000 vitualSpots=20000
//9063340 key=49f57cf0 node=529
//9063340 key=49f57cf0 node=83

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module github.com/joykk/hashring
go 1.13
require github.com/sirupsen/logrus v1.4.2

13
go.sum Normal file
View File

@ -0,0 +1,13 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@ -88,8 +88,12 @@ func (h *HashRing) generate() {
}
totalVirtualSpots := h.virualSpots * len(h.weights)
h.nodes = nodesArray{}
var nodeLen, nodeIndex int64
for _, w := range h.weights {
nodeLen += int64(math.Floor(float64(w) / float64(totalW) * float64(totalVirtualSpots)))
}
h.nodes = make(nodesArray, nodeLen)
for nodeKey, w := range h.weights {
spots := int(math.Floor(float64(w) / float64(totalW) * float64(totalVirtualSpots)))
for i := 1; i <= spots; i++ {
@ -100,7 +104,8 @@ func (h *HashRing) generate() {
nodeKey: nodeKey,
spotValue: genValue(hashBytes[6:10]),
}
h.nodes = append(h.nodes, n)
h.nodes[nodeIndex] = n
nodeIndex += 1
hash.Reset()
}
}
@ -122,7 +127,6 @@ func (h *HashRing) GetNode(s string) string {
if len(h.nodes) == 0 {
return ""
}
hash := sha1.New()
hash.Write([]byte(s))
hashBytes := hash.Sum(nil)

View File

@ -1,8 +1,13 @@
package hashring
import (
// "fmt"
"crypto/sha1"
"fmt"
"regexp"
"runtime"
"strconv"
"testing"
"time"
)
const (
@ -22,7 +27,6 @@ func getNodesCount(nodes nodesArray) (int, int, int) {
}
if node.nodeKey == node2 {
node2Count += 1
}
if node.nodeKey == node3 {
node3Count += 1
@ -82,3 +86,75 @@ func TestHash(t *testing.T) {
t.Logf("len of nodes is %v after AddNode node1:%v, node2:%v, node3:%v", len(hash.nodes), c1, c2, c3)
}
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) {
// node=1000 v=50000 on 8GB/win10/i7 init 35s
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)
}
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
// }
//}
}