Skip to content

Commit

Permalink
RATIS-1870. Refactor hasMajority code during configuration changes. (a…
Browse files Browse the repository at this point in the history
  • Loading branch information
SzyWilliam authored Aug 14, 2023
1 parent f3a5d4d commit c8f4c46
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -875,36 +875,7 @@ private Optional<MinMajorityMax> getMajorityMin(ToLongFunction<FollowerInfo> fol

private boolean hasMajority(Predicate<RaftPeerId> isAcked) {
final RaftPeerId selfId = server.getId();
final RaftConfigurationImpl conf = server.getRaftConf();

final CurrentOldFollowerInfos infos = followerInfoMap.getFollowerInfos(conf);
final List<FollowerInfo> followers = infos.getCurrent();
final boolean includeSelf = conf.containsInConf(selfId);
final boolean newConf = hasMajority(isAcked, followers, includeSelf);

if (!conf.isTransitional()) {
return newConf;
} else {
final List<FollowerInfo> oldFollowers = infos.getOld();
final boolean includeSelfInOldConf = conf.containsInOldConf(selfId);
final boolean oldConf = hasMajority(isAcked, oldFollowers, includeSelfInOldConf);
return newConf && oldConf;
}
}

private boolean hasMajority(Predicate<RaftPeerId> isAcked, List<FollowerInfo> followers, boolean includeSelf) {
if (followers.isEmpty() && !includeSelf) {
return true;
}

int count = includeSelf ? 1 : 0;
for (FollowerInfo follower: followers) {
if (isAcked.test(follower.getId())) {
count++;
}
}
final int size = includeSelf ? followers.size() + 1 : followers.size();
return count > size / 2;
return server.getRaftConf().hasMajority(isAcked, selfId);
}

private void updateCommit(LogEntryHeader[] entriesToCommit) {
Expand Down Expand Up @@ -1094,7 +1065,7 @@ CompletableFuture<Long> getReadIndex() {
final long readIndex = server.getRaftLog().getLastCommittedIndex();

// if group contains only one member, fast path
if (server.getRaftConf().getCurrentPeers().size() == 1) {
if (server.getRaftConf().isSingleton()) {
return CompletableFuture.completedFuture(readIndex);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;

/**
Expand Down Expand Up @@ -150,12 +151,17 @@ List<RaftPeer> getOtherPeers(RaftPeerId selfId) {

boolean hasMajority(Collection<RaftPeerId> others, RaftPeerId selfId) {
Preconditions.assertTrue(!others.contains(selfId));
int num = 0;
if (contains(selfId)) {
num++;
return hasMajority(others::contains, contains(selfId));
}

boolean hasMajority(Predicate<RaftPeerId> activePeers, boolean includeSelf) {
if (peers.isEmpty() && !includeSelf) {
return true;
}
for (RaftPeerId other : others) {
if (contains(other)) {

int num = includeSelf ? 1 : 0;
for (RaftPeerId peerId: peers.keySet()) {
if (activePeers.test(peerId)) {
num++;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -238,6 +239,20 @@ boolean hasMajority(Collection<RaftPeerId> others, RaftPeerId selfId) {
(oldConf == null || oldConf.hasMajority(others, selfId));
}

/** @return true if the self id together with the acknowledged followers reach majority. */
boolean hasMajority(Predicate<RaftPeerId> followers, RaftPeerId selfId) {
final boolean includeInCurrent = containsInConf(selfId);
final boolean hasMajorityInNewConf = conf.hasMajority(followers, includeInCurrent);

if (!isTransitional()) {
return hasMajorityInNewConf;
} else {
final boolean includeInOldConf = containsInOldConf(selfId);
final boolean hasMajorityInOldConf = oldConf.hasMajority(followers, includeInOldConf);
return hasMajorityInOldConf && hasMajorityInNewConf;
}
}

int getMajorityCount() {
return conf.getMajorityCount();
}
Expand All @@ -248,6 +263,11 @@ boolean majorityRejectVotes(Collection<RaftPeerId> rejects) {
(oldConf != null && oldConf.majorityRejectVotes(rejects));
}

/** @return true if only one voting member (the leader) in the cluster */
boolean isSingleton() {
return getCurrentPeers().size() == 1 && getPreviousPeers().size() <= 1;
}

@Override
public String toString() {
return logEntryIndex + ": " + conf + ", old=" + oldConf;
Expand Down

0 comments on commit c8f4c46

Please sign in to comment.