-
Notifications
You must be signed in to change notification settings - Fork 8
/
mash.go
66 lines (59 loc) · 1.58 KB
/
mash.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package btrdb
import (
"strings"
pb "github.com/BTrDB/btrdb/v5/v5api"
"github.com/huichen/murmur"
"github.com/pborman/uuid"
)
//The MASH struct (Master Allocation by Stable Hashing) contains information
//about the cluster and which fraction of the uuid space is being served by
//which endpoints. Generally you will not need to use this, but it is handy
//for checking the cluster is healthy.
type MASH struct {
*pb.Mash
eps []mashEndpoint
}
type mashEndpoint struct {
start int64
end int64
hash uint32
grpc []string
}
func (m *MASH) pbEndpointFor(uuid uuid.UUID) *pb.Member {
hsh := int64(murmur.Murmur3(uuid[:]))
for _, mbr := range m.GetMembers() {
s := mbr.GetStart()
e := mbr.GetEnd()
if hsh >= s && hsh < e {
return mbr
}
}
return nil
}
//EndpointFor will take a uuid and return the connection details for the
//endpoint that can service a write to that uuid. This is a low level function.
func (m *MASH) EndpointFor(uuid uuid.UUID) (found bool, hash uint32, addrs []string) {
hsh := int64(murmur.Murmur3(uuid[:]))
for _, e := range m.eps {
if e.start <= hsh && e.end > hsh {
return true, e.hash, e.grpc
}
}
return false, 0, nil
}
//Called after mash pb obj is populated. Can be used to fill in
//read optimized data structures in the MASH object
func (m *MASH) precalculate() {
m.eps = []mashEndpoint{}
for _, mbr := range m.Members {
if mbr.In && mbr.Up && mbr.Start != mbr.End {
seps := strings.Split(mbr.GrpcEndpoints, ";")
m.eps = append(m.eps, mashEndpoint{
start: mbr.Start,
end: mbr.End,
hash: mbr.Hash,
grpc: seps,
})
}
}
}