func (c Change) validateIncoming() Change {
	if c.Status == Faulty && c.Tombstone {
		c.Status = Tombstone
	}
	return c
}
validateIncoming validates incoming changes before they are passed into the
swim state machine. This is usefull to make late adjustments to incoming
changes to transform some legacy wire protocol changes into new swim terminology
package swim
import (
	"bytes"
	"encoding/binary"
	"math/rand"
	"strconv"
	"sync"
	"github.com/uber/ringpop-go/membership"
	"github.com/dgryski/go-farm"
	"github.com/uber/ringpop-go/util"
)
const (
	Alive = "alive"
	Suspect = "suspect"
	Faulty = "faulty"
	Leave = "leave"
	Tombstone = "tombstone"
)
var (
	byteBufferPool = sync.Pool{
		New: func() interface{} {
			return new(bytes.Buffer)
		},
	}
)
type Member struct {
	Address     string   `json:"address"`
	Status      string   `json:"status"`
	Incarnation int64    `json:"incarnationNumber"`
	Labels      LabelMap `json:"labels,omitempty"`
}
type LabelMap map[string]string
func (m Member) GetAddress() string {
	return m.Address
}
func (m Member) Label(key string) (value string, has bool) {
	value, has = m.Labels[key]
	return
}
func (m Member) Identity() string {
	identity, set := m.Label(membership.IdentityLabelKey)
	if set {
		return identity
	}
	return m.Address
}
func (m Member) address() string {
	return m.Address
}
func (m Member) incarnation() int64 {
	return m.Incarnation
}
func (m *Member) populateFromChange(c *Change) {
	m.Address = c.Address
	m.Incarnation = c.Incarnation
	m.Status = c.Status
	m.Labels = c.Labels
}
func (m Member) checksumString(b *bytes.Buffer) {
	b.WriteString(m.Address)
	b.WriteString(m.Status)
	b.WriteString(strconv.FormatInt(m.Incarnation, 10))
	m.Labels.checksumString(b)
}
func (l LabelMap) copy() (result LabelMap) {
	result = make(map[string]string, len(l))
	for key, value := range l {
		result[key] = value
	}
	return
}
func (l LabelMap) checksumString(b *bytes.Buffer) {
	checksum := l.checksum()
	if checksum == 0 {
		return
	}
	b.WriteString("#labels")
	b.WriteString(strconv.Itoa(int(checksum)))
}
func (l LabelMap) checksum() int32 {
	var checksum uint32
	lb := byteBufferPool.Get().(*bytes.Buffer)
	lb.Reset()
	for key, value := range l {
		binary.Write(lb, binary.BigEndian, int32(len(key)))
		lb.WriteString(key)
		binary.Write(lb, binary.BigEndian, int32(len(value)))
		lb.WriteString(value)
		checksum = checksum ^ farm.Fingerprint32(lb.Bytes())
		lb.Reset()
	}
	byteBufferPool.Put(lb)
	var signedChecksum int32
	signedChecksum = int32(checksum>>1)<<1 | int32(checksum&uint32(1))
	return signedChecksum
}
func shuffle(members []*Member) []*Member {
	newMembers := make([]*Member, len(members), cap(members))
	newIndexes := rand.Perm(len(members))
	for o, n := range newIndexes {
		newMembers[n] = members[o]
	}
	return newMembers
}
func shouldProcessGossip(old *Member, gossip *Member) bool {
	if gossip.Status == Tombstone && old == nil {
		return false
	}
	if old == nil {
		return true
	}
	if gossip.Incarnation > old.Incarnation {
		return true
	}
	if gossip.Incarnation < old.Incarnation {
		return false
	}
	if statePrecedence(gossip.Status) > statePrecedence(old.Status) {
		return true
	}
	if statePrecedence(gossip.Status) < statePrecedence(old.Status) {
		return false
	}
	gossipLabelsChecksum := gossip.Labels.checksum()
	oldLabelsChecksum := old.Labels.checksum()
	if gossipLabelsChecksum > oldLabelsChecksum {
		return true
	}
	if gossipLabelsChecksum < oldLabelsChecksum {
		return false
	}
	return false
}
func statePrecedence(s string) int {
	switch s {
	case Alive:
		return 0
	case Suspect:
		return 1
	case Faulty:
		return 2
	case Leave:
		return 3
	case Tombstone:
		return 4
	default:
		return -1
	}
}
func (m *Member) isReachable() bool {
	return m.Status == Alive || m.Status == Suspect
}
type Change struct {
	Source            string            `json:"source"`
	SourceIncarnation int64             `json:"sourceIncarnationNumber"`
	Address           string            `json:"address"`
	Incarnation       int64             `json:"incarnationNumber"`
	Status            string            `json:"status"`
	Tombstone         bool              `json:"tombstone,omitempty"`
	Labels            map[string]string `json:"labels,omitempty"`
	Timestamp util.Timestamp `json:"timestamp"`
}