package com.atlassian.bitbucket.mesh.transaction;

public enum QuorumMode {

    /**
     * Any transaction that is successfully prepared locally is always committed, regardless of replica votes.
     * This mode implies that the control plane consistently routes all (write) requests for a given repository to the
     * the same Mesh node.
     */
    ALWAYS {
        @Override
        public int getRequiredVotes(int replicaCount) {
            return 1;
        }
    },
    /**
     * Any transaction that is successfully prepared by a majority of replicas is committed.
     */
    MAJORITY {
        @Override
        public int getRequiredVotes(int replicaCount) {
            return replicaCount / 2 + 1;
        }
    },
    /**
     * All replicas must vote to commit or the transaction will be rolled back.
     */
    UNANIMOUS {
        @Override
        public int getRequiredVotes(int replicaCount) {
            return replicaCount;
        }
    };

    /**
     * @param replicaCount the total number of repository replicas
     * @return the number of replicas (including the leader) that need to have successfully prepared a transaction
     *         (and voted YES) for the transaction to be committable
     */
    public abstract int getRequiredVotes(int replicaCount);
}
