org.opensearch.cluster.routing.WeightedRoundRobin Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opensearch Show documentation
Show all versions of opensearch Show documentation
OpenSearch subproject :server
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/
package org.opensearch.cluster.routing;
import java.util.ArrayList;
import java.util.List;
/**
* Weighted Round Robin Scheduling policy
*
*/
public class WeightedRoundRobin {
private List> entities;
public WeightedRoundRobin(List> entities) {
this.entities = entities;
}
/**
* *
* @return list of entities that is ordered using weighted round-robin scheduling
* http://kb.linuxvirtualserver.org/wiki/Weighted_Round-Robin_Scheduling
*/
public List> orderEntities() {
int lastSelectedEntity = -1;
int size = entities.size();
double currentWeight = 0;
List> orderedWeight = new ArrayList<>();
if (size == 0) {
return null;
}
// Find maximum weight and greatest common divisor of weight across all entities
double maxWeight = 0;
double sumWeight = 0;
Double gcd = null;
for (WeightedRoundRobin.Entity entity : entities) {
maxWeight = Math.max(maxWeight, entity.getWeight());
gcd = (gcd == null) ? entity.getWeight() : gcd(gcd, entity.getWeight());
sumWeight += entity.getWeight() > 0 ? entity.getWeight() : 0;
}
int count = 0;
while (count < sumWeight) {
lastSelectedEntity = (lastSelectedEntity + 1) % size;
if (lastSelectedEntity == 0) {
currentWeight = currentWeight - gcd;
if (currentWeight <= 0) {
currentWeight = maxWeight;
if (currentWeight == 0) {
return orderedWeight;
}
}
}
if (entities.get(lastSelectedEntity).getWeight() >= currentWeight) {
orderedWeight.add(entities.get(lastSelectedEntity));
count++;
}
}
return orderedWeight;
}
/**
* Return greatest common divisor for two integers
* https://en.wikipedia.org/wiki/Greatest_common_divisor#Using_Euclid.27s_algorithm
*
* @param a first number
* @param b second number
* @return greatest common divisor
*/
private double gcd(double a, double b) {
return (b == 0) ? a : gcd(b, a % b);
}
static final class Entity {
private double weight;
private T target;
public Entity(double weight, T target) {
this.weight = weight;
this.target = target;
}
public T getTarget() {
return this.target;
}
public void setTarget(T target) {
this.target = target;
}
public double getWeight() {
return this.weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
}
}