Skip to content

Instantly share code, notes, and snippets.

@samueleresca
Last active December 10, 2021 12:17
Show Gist options
  • Save samueleresca/213f057f4d2588565adeef22a1a7ad12 to your computer and use it in GitHub Desktop.
Save samueleresca/213f057f4d2588565adeef22a1a7ad12 to your computer and use it in GitHub Desktop.
func (qs QuorumSystem) loadOptimalStrategy(
optimize OptimizeType,
readQuorums []ExprSet,
writeQuorums []ExprSet,
readFraction DistributionValues,
loadLimit *float64,
networkLimit *float64,
latencyLimit *float64) (*Strategy, error) {
...
// Declare a new Simplex problem with a clp.Minimize optimization direction.
simp := clp.NewSimplex()
simp.SetOptimizationDirection(clp.Minimize)
def := lpDefinition{}
if optimize == Load {
def = getLoadObjective(readFraction, loadLimit, buildLoadDef)
} else if optimize == Network {
def = buildNetworkDef(nil)
} else if optimize == Latency {
def, _ = buildLatencyDef(nil)
}
// The sum of the read and write quorums probabilities must be 1.
sumOfReadProbabilities, sumOfWriteProbabilities := getTotalProbabilityObjectives(optimize, readQuorumVars, writeQuorumVars)
def.Objectives = append(def.Objectives, sumOfReadProbabilities)
def.Objectives = append(def.Objectives, sumOfWriteProbabilities)
if loadLimit != nil {
defTemp := getLoadObjective(readFraction, loadLimit, buildLoadDef)
def.Vars = append(def.Vars, 0)
for r := 0; r < len(def.Objectives); r++ {
if len(def.Objectives[r]) != len(def.Vars) {
def.Objectives[r] = insertAt(def.Objectives[r], len(def.Objectives[r])-1, 0.0)
}
}
b := [2]float64{ninf, pinf}
def.Constraints = append(def.Constraints, b)
def.Objectives = append(def.Objectives, defTemp.Objectives...)
}
if networkLimit != nil {
def.Objectives = merge(def.Objectives, buildNetworkDef(networkLimit).Objectives)
}
if latencyLimit != nil {
defTemp, _ := buildLatencyDef(latencyLimit)
def.Objectives = merge(def.Objectives, defTemp.Objectives)
}
simp.EasyLoadDenseProblem(def.Vars, def.Constraints, def.Objectives)
// Solve the optimization problem.
status := simp.Primal(clp.NoValuesPass, clp.NoStartFinishOptions)
soln := simp.PrimalColumnSolution()
if status != clp.Optimal {
return nil, fmt.Errorf("no optimal strategy found")
}
readSigma := make([]SigmaRecord, 0)
writeSigma := make([]SigmaRecord, 0)
for _, v := range readQuorumVars {
readSigma = append(readSigma, SigmaRecord{Quorum: v.Quorum, Probability: soln[v.Index]})
}
for _, v := range writeQuorumVars {
writeSigma = append(writeSigma, SigmaRecord{Quorum: v.Quorum, Probability: soln[v.Index]})
}
newStrategy := NewStrategy(qs, Sigma{Values: readSigma}, Sigma{Values: writeSigma})
return &newStrategy, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment