github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/cluster/member.go (about) 1 package cluster 2 3 import ( 4 "sort" 5 "strconv" 6 "strings" 7 8 murmur32 "github.com/twmb/murmur3" 9 ) 10 11 type Members []*Member 12 13 func (m *Members) ToSet() *MemberSet { 14 return NewMemberSet(*m) 15 } 16 17 func (m *Member) HasKind(kind string) bool { 18 for _, k := range m.Kinds { 19 if k == kind { 20 return true 21 } 22 } 23 24 return false 25 } 26 27 // Address return a "host:port". 28 // Member defined by protos.proto 29 func (m *Member) Address() string { 30 return m.Host + ":" + strconv.FormatInt(int64(m.Port), 10) 31 } 32 33 func TopologyHash(members Members) uint64 { 34 // C# version 35 // var x = membersByMemberId.Select(m => m.Id).OrderBy(i => i).ToArray(); 36 // var key = string.Join("", x); 37 // var hashBytes = MurmurHash2.Hash(key); 38 // return hashBytes; 39 40 sort.Slice(members, func(i, j int) bool { 41 return members[i].Id < members[j].Id 42 }) 43 44 // I assume this is not the fastest way to do this? 45 s := "" 46 for _, m := range members { 47 s += m.Id 48 } 49 50 // TODO: this HAS to be compatible with the same hashBytes in .NET 51 // add plenty of tests 52 hash := murmur32.Sum64([]byte(s)) 53 54 return hash 55 } 56 57 func MembersToMap(members Members) map[string]*Member { 58 mapp := make(map[string]*Member) 59 for _, m := range members { 60 mapp[m.Id] = m 61 } 62 63 return mapp 64 } 65 66 func SortMembers(members Members) { 67 sort.Slice(members, func(i, j int) bool { 68 addrI := members[i].Id 69 addrJ := members[j].Id 70 71 return strings.Compare(addrI, addrJ) > 0 72 }) 73 } 74 75 func CopySortMembers(members Members) Members { 76 tmp := append(make(Members, 0, len(members)), members...) 77 SortMembers(tmp) 78 79 return tmp 80 }