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  }