Skip to content

Commit e2eb7f9

Browse files
changed weights to short from int
1 parent 03de3f9 commit e2eb7f9

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -329,15 +329,20 @@ public boolean isEquivalentTo(RoundRobinPicker picker) {
329329
}
330330

331331
/*
332-
* Implementation of Static Stride Scheduler, replaces EDFScheduler.
332+
* The Static Stride Scheduler is an implementation of an earliest deadline first (EDF) scheduler
333+
* in which each object is chosen periodically with frequency proportional to its weight.
333334
* <p>
335+
* Specifically, each backend is given a deadline equal to the multiplicative inverse of
336+
* its weight. The place of each backend in its deadline is tracked, and each call to
337+
* pick a backend returns the backend index with the least remaining time in its deadline.
338+
* <p>
339+
* The way in which this is implemented is through a static stride scheduler.
334340
* The Static Stride Scheduler works by iterating through the list of subchannel weights
335341
* and using modular arithmetic to proportionally distribute picks, favoring entries
336342
* with higher weights. It is based on the observation that the intended sequence generated
337-
* from the EDF scheduler is a periodic one that can be achieved through modular arithmetic.
338-
* This scheduler generates a practically equivalent sequence of picks as the EDFScheduler.
339-
* The Static Stride Scheduler is more performant than the EDFScheduler, as it removes
340-
* the need for a priority queue (and thus mutex locks).
343+
* from an EDF scheduler is a periodic one that can be achieved through modular arithmetic.
344+
* The Static Stride Scheduler is more performant than other implementations of the EDF
345+
* Scheduler, as it removes the need for a priority queue (and thus mutex locks).
341346
* <p>
342347
* go/static-stride-scheduler
343348
* <p>
@@ -348,7 +353,7 @@ public boolean isEquivalentTo(RoundRobinPicker picker) {
348353
*/
349354
@VisibleForTesting
350355
static final class StaticStrideScheduler {
351-
private final int[] scaledWeights;
356+
private final short[] scaledWeights;
352357
private final int sizeDivisor;
353358
private final AtomicInteger sequence;
354359
private static final int K_MAX_WEIGHT = 0xFFFF;
@@ -359,7 +364,7 @@ static final class StaticStrideScheduler {
359364
int numWeightedChannels = 0;
360365
double sumWeight = 0;
361366
float maxWeight = 0;
362-
int meanWeight = 0;
367+
short meanWeight = 0;
363368
for (float weight : weights) {
364369
if (weight > 0) {
365370
sumWeight += weight;
@@ -370,18 +375,19 @@ static final class StaticStrideScheduler {
370375

371376
double scalingFactor = K_MAX_WEIGHT / maxWeight;
372377
if (numWeightedChannels > 0) {
373-
meanWeight = (int) Math.round(scalingFactor * sumWeight / numWeightedChannels);
378+
int value = (int) Math.round(scalingFactor * sumWeight / numWeightedChannels);
379+
meanWeight = (short) (value > 0x7FFF ? value - 0x10000 : value);
374380
} else {
375381
meanWeight = 1;
376382
}
377383

378384
// scales weights s.t. max(weights) == K_MAX_WEIGHT, meanWeight is scaled accordingly
379-
int[] scaledWeights = new int[numChannels];
385+
short[] scaledWeights = new short[numChannels];
380386
for (int i = 0; i < numChannels; i++) {
381387
if (weights[i] <= 0) {
382388
scaledWeights[i] = meanWeight;
383389
} else {
384-
scaledWeights[i] = (int) Math.round(weights[i] * scalingFactor);
390+
scaledWeights[i] = (short) Math.round(weights[i] * scalingFactor);
385391
}
386392
}
387393

@@ -414,7 +420,7 @@ int pick() {
414420
long sequence = this.nextSequence();
415421
int backendIndex = (int) (sequence % this.sizeDivisor);
416422
long generation = sequence / this.sizeDivisor;
417-
long weight = this.scaledWeights[backendIndex];
423+
int weight = Short.toUnsignedInt(this.scaledWeights[backendIndex]);
418424
long offset = (long) K_MAX_WEIGHT / 2 * backendIndex;
419425
if ((weight * generation + offset) % K_MAX_WEIGHT < K_MAX_WEIGHT - weight) {
420426
continue;

0 commit comments

Comments
 (0)