package com.lambdaworks.redis.cluster; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import com.lambdaworks.redis.RedisURI; import com.lambdaworks.redis.cluster.models.partitions.Partitions; import com.lambdaworks.redis.cluster.models.partitions.RedisClusterNode; /** * Implementations for {@link PartitionsConsensus}. * * @author Mark Paluch * @since 4.2 */ class PartitionsConsensusImpl { /** * Votes for {@link Partitions} that contains the most known (previously existing) nodes. */ static final class KnownMajority extends PartitionsConsensus { @Override Partitions getPartitions(Partitions current, Map<RedisURI, Partitions> topologyViews) { if (topologyViews.isEmpty()) { return current; } List<VotedPartitions> votedList = new ArrayList<>(); for (Partitions partitions : topologyViews.values()) { int knownNodes = 0; for (RedisClusterNode knownNode : current) { if (partitions.getPartitionByNodeId(knownNode.getNodeId()) != null) { knownNodes++; } } votedList.add(new VotedPartitions(knownNodes, partitions)); } Collections.shuffle(votedList); Collections.sort(votedList, (o1, o2) -> Integer.compare(o2.votes, o1.votes)); return votedList.get(0).partitions; } } /** * Votes for {@link Partitions} that contains the most active (in total) nodes. */ static final class HealthyMajority extends PartitionsConsensus { @Override Partitions getPartitions(Partitions current, Map<RedisURI, Partitions> topologyViews) { if (topologyViews.isEmpty()) { return current; } List<VotedPartitions> votedList = new ArrayList<>(); for (Partitions partitions : topologyViews.values()) { int votes = 0; for (RedisClusterNode node : partitions) { if (node.is(RedisClusterNode.NodeFlag.FAIL) || node.is(RedisClusterNode.NodeFlag.EVENTUAL_FAIL) || node.is(RedisClusterNode.NodeFlag.NOADDR)) { continue; } votes++; } votedList.add(new VotedPartitions(votes, partitions)); } Collections.shuffle(votedList); Collections.sort(votedList, (o1, o2) -> Integer.compare(o2.votes, o1.votes)); return votedList.get(0).partitions; } } static final class VotedPartitions { final int votes; final Partitions partitions; public VotedPartitions(int votes, Partitions partitions) { this.votes = votes; this.partitions = partitions; } } }