Skip to content

Commit 6ebf7d8

Browse files
committed
fix: FindVoteResult logic
1 parent 1e1b02c commit 6ebf7d8

File tree

1 file changed

+33
-67
lines changed

1 file changed

+33
-67
lines changed

base/vote.go

Lines changed: 33 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package base
22

3-
import (
4-
"sort"
5-
)
6-
73
type VoteResult string
84

95
const (
@@ -47,86 +43,56 @@ func (v *VoteResult) UnmarshalText(b []byte) error {
4743
return nil
4844
}
4945

50-
// FindMajority finds the majority(over threshold) set between the given sets.
51-
// The returned value means,
52-
// 0-N: index number of set
53-
// -1: not yet majority
54-
// -2: draw
55-
func FindMajority(quorum, threshold uint, set ...uint) int {
46+
func FindVoteResult(quorum, threshold uint, s []string) (result VoteResult, key string) {
5647
th := threshold
5748
if th > quorum {
5849
th = quorum
5950
}
6051

61-
if len(set) < 1 {
62-
return -1
52+
total := uint(len(s))
53+
if total == 0 {
54+
return VoteResultNotYet, ""
6355
}
6456

65-
var sum uint
66-
67-
for i := range set {
68-
n := set[i]
69-
70-
if n >= quorum {
71-
return i
72-
}
73-
74-
if n >= th {
75-
return i
76-
}
77-
78-
sum += n
57+
var remain uint
58+
if total < quorum {
59+
remain = quorum - total
7960
}
8061

81-
sort.Slice(set, func(i, j int) bool {
82-
return set[i] > set[j]
83-
})
84-
85-
if quorum-sum+set[0] < th {
86-
return -2
62+
count := make(map[string]uint, len(s))
63+
for _, v := range s {
64+
count[v]++
8765
}
8866

89-
return -1
90-
}
91-
92-
func FindVoteResult(quorum, threshold uint, s []string) (result VoteResult, key string) {
93-
th := threshold
94-
if th > quorum {
95-
th = quorum
96-
}
97-
98-
if len(s) < 1 {
99-
return VoteResultNotYet, ""
67+
var (
68+
maxCount uint
69+
topTies uint
70+
mhs string
71+
)
72+
for hs, cn := range count {
73+
if cn > maxCount {
74+
maxCount = cn
75+
mhs = hs
76+
topTies = 1
77+
} else if cn == maxCount {
78+
topTies++
79+
if hs < mhs {
80+
mhs = hs
81+
}
82+
}
10083
}
10184

102-
keys := map[uint]string{}
103-
defer clear(keys)
104-
105-
count := map[string]uint{}
106-
defer clear(count)
107-
108-
for i := range s {
109-
count[s[i]]++
85+
if maxCount >= th {
86+
return VoteResultMajority, mhs
11087
}
11188

112-
set := make([]uint, len(count))
113-
var i int
114-
115-
for j := range count {
116-
c := count[j]
117-
keys[c] = j
118-
set[i] = c
119-
i++
89+
if remain == 0 {
90+
return VoteResultDraw, ""
12091
}
12192

122-
sort.Slice(set, func(i, j int) bool { return set[i] > set[j] })
123-
124-
switch index := FindMajority(quorum, th, set...); index {
125-
case -1:
126-
return VoteResultNotYet, ""
127-
case -2:
93+
if maxCount+remain < th {
12894
return VoteResultDraw, ""
129-
default:
130-
return VoteResultMajority, keys[set[index]]
13195
}
96+
97+
return VoteResultNotYet, ""
13298
}

0 commit comments

Comments
 (0)