github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/consensus/ipbft/types/candidate_set.go (about) 1 package types 2 3 import ( 4 "bytes" 5 "sort" 6 ) 7 8 type CandidateSet struct { 9 Candidates []*Candidate `json:"candidates"` 10 } 11 12 func NewCandidateSet(cans []*Candidate) *CandidateSet { 13 candidates := make([]*Candidate, len(cans)) 14 for i, can := range cans { 15 candidates[i] = can.Copy() 16 } 17 18 sort.Sort(CandidatesByAddress(candidates)) 19 20 cs := &CandidateSet{ 21 Candidates: candidates, 22 } 23 return cs 24 } 25 26 func (canSet *CandidateSet) Copy() *CandidateSet { 27 candidates := make([]*Candidate, len(canSet.Candidates)) 28 for i, can := range canSet.Candidates { 29 candidates[i] = can.Copy() 30 } 31 32 return &CandidateSet{ 33 Candidates: candidates, 34 } 35 } 36 37 func (canSet *CandidateSet) Add(cal *Candidate) (added bool) { 38 cal = cal.Copy() 39 40 idx := -1 41 for i := 0; i < len(canSet.Candidates); i++ { 42 if bytes.Compare(cal.Address, canSet.Candidates[i].Address) == 0 { 43 idx = i 44 break 45 } 46 } 47 48 //if idx == len(valSet.Validators) { 49 if idx == -1 { 50 canSet.Candidates = append(canSet.Candidates, cal) 51 return true 52 } else { 53 return false 54 } 55 } 56 57 func (canSet *CandidateSet) Remove(address []byte) (cal *Candidate, removed bool) { 58 idx := -1 59 for i := 0; i < len(canSet.Candidates); i++ { 60 if bytes.Compare(address, canSet.Candidates[i].Address) == 0 { 61 idx = i 62 break 63 } 64 } 65 66 if idx == -1 { 67 return nil, false 68 } else { 69 removedCal := canSet.Candidates[idx] 70 newCandidates := canSet.Candidates[:idx] 71 if idx+1 < len(canSet.Candidates) { 72 newCandidates = append(newCandidates, canSet.Candidates[idx+1:]...) 73 } 74 canSet.Candidates = newCandidates 75 return removedCal, true 76 } 77 } 78 79 // HasAddress returns true if address given is in the candidate set, false - 80 // otherwise. 81 func (canSet *CandidateSet) HasAddress(address []byte) bool { 82 83 for i := 0; i < len(canSet.Candidates); i++ { 84 if bytes.Compare(address, canSet.Candidates[i].Address) == 0 { 85 return true 86 } 87 } 88 return false 89 } 90 91 func (canSet *CandidateSet) GetByAddress(address []byte) (index int, val *Candidate) { 92 93 idx := -1 94 for i := 0; i < len(canSet.Candidates); i++ { 95 if bytes.Compare(address, canSet.Candidates[i].Address) == 0 { 96 idx = i 97 break 98 } 99 } 100 101 if idx != -1 { 102 return idx, canSet.Candidates[idx].Copy() 103 } else { 104 return 0, nil 105 } 106 } 107 108 type CandidatesByAddress []*Candidate 109 110 func (cs CandidatesByAddress) Len() int { 111 return len(cs) 112 } 113 114 func (cs CandidatesByAddress) Less(i, j int) bool { 115 return bytes.Compare(cs[i].Address, cs[j].Address) == -1 116 } 117 118 func (cs CandidatesByAddress) Swap(i, j int) { 119 it := cs[i] 120 cs[i] = cs[j] 121 cs[j] = it 122 }