blob: e3741e0b0a9609d3595bf0b3260d3c562f5c5cb2 [file] [log] [blame]
Scott Baker2c1c4822019-10-16 11:02:41 -07001// Copyright 2019 The etcd Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package quorum
16
17// JointConfig is a configuration of two groups of (possibly overlapping)
18// majority configurations. Decisions require the support of both majorities.
19type JointConfig [2]MajorityConfig
20
21func (c JointConfig) String() string {
22 if len(c[1]) > 0 {
23 return c[0].String() + "&&" + c[1].String()
24 }
25 return c[0].String()
26}
27
28// IDs returns a newly initialized map representing the set of voters present
29// in the joint configuration.
30func (c JointConfig) IDs() map[uint64]struct{} {
31 m := map[uint64]struct{}{}
32 for _, cc := range c {
33 for id := range cc {
34 m[id] = struct{}{}
35 }
36 }
37 return m
38}
39
40// Describe returns a (multi-line) representation of the commit indexes for the
41// given lookuper.
42func (c JointConfig) Describe(l AckedIndexer) string {
43 return MajorityConfig(c.IDs()).Describe(l)
44}
45
46// CommittedIndex returns the largest committed index for the given joint
47// quorum. An index is jointly committed if it is committed in both constituent
48// majorities.
49func (c JointConfig) CommittedIndex(l AckedIndexer) Index {
50 idx0 := c[0].CommittedIndex(l)
51 idx1 := c[1].CommittedIndex(l)
52 if idx0 < idx1 {
53 return idx0
54 }
55 return idx1
56}
57
58// VoteResult takes a mapping of voters to yes/no (true/false) votes and returns
59// a result indicating whether the vote is pending, lost, or won. A joint quorum
60// requires both majority quorums to vote in favor.
61func (c JointConfig) VoteResult(votes map[uint64]bool) VoteResult {
62 r1 := c[0].VoteResult(votes)
63 r2 := c[1].VoteResult(votes)
64
65 if r1 == r2 {
66 // If they agree, return the agreed state.
67 return r1
68 }
69 if r1 == VoteLost || r2 == VoteLost {
70 // If either config has lost, loss is the only possible outcome.
71 return VoteLost
72 }
73 // One side won, the other one is pending, so the whole outcome is.
74 return VotePending
75}