package io.scalecube.cluster;
/**
* Utility class which contains math computation on cluster properties.
*
* @author Anton Kharenko
*/
public final class ClusterMath {
private ClusterMath() {
// Do not instantiate
}
public static double gossipConvergencePercent(int fanout, int repeatMult, int clusterSize, double lossPercent) {
double msgLossProb = lossPercent / 100.0;
return gossipConvergenceProbability(fanout, repeatMult, clusterSize, msgLossProb) * 100;
}
public static double gossipConvergenceProbability(int fanout, int repeatMult, int clusterSize, double loss) {
double fanoutWithLoss = (1.0 - loss) * fanout;
double spreadSize = clusterSize - Math.pow(clusterSize, -(fanoutWithLoss * repeatMult - 2));
return spreadSize / clusterSize;
}
public static int maxMessagesPerGossipTotal(int fanout, int repeatMult, int clusterSize) {
return clusterSize * maxMessagesPerGossipPerNode(fanout, repeatMult, clusterSize);
}
public static int maxMessagesPerGossipPerNode(int fanout, int repeatMult, int clusterSize) {
return fanout * repeatMult * ceilLog2(clusterSize);
}
public static long gossipDisseminationTime(int repeatMult, int clusterSize, long gossipInterval) {
return gossipPeriodsToSpread(repeatMult, clusterSize) * gossipInterval;
}
public static long gossipTimeoutToSweep(int repeatMult, int clusterSize, long gossipInterval) {
return gossipPeriodsToSweep(repeatMult, clusterSize) * gossipInterval;
}
public static int gossipPeriodsToSweep(int repeatMult, int clusterSize) {
int periodsToSpread = gossipPeriodsToSpread(repeatMult, clusterSize);
return 2 * (periodsToSpread + 1);
}
public static int gossipPeriodsToSpread(int repeatMult, int clusterSize) {
return repeatMult * ceilLog2(clusterSize);
}
public static long suspicionTimeout(int suspicionMult, int clusterSize, long pingInterval) {
return suspicionMult * ceilLog2(clusterSize) * pingInterval;
}
/**
* Returns ceil(log2(n + 1)).
*/
public static int ceilLog2(int num) {
return 32 - Integer.numberOfLeadingZeros(num);
}
}