Commit 8006ee58 authored by Sergio Gelato's avatar Sergio Gelato Committed by Quanah Gibson-Mount
Browse files

ITS#8204 Improved RFC2782 shuffle when several, but not all, records have weight 0.

The fallback to a straight Fisher-Yates shuffle needs to occur whenever the
sum of the *remaining* weights is zero, or else the remaining records will
not be reordered. Testing only once at the beginning covers the case when
all weights are zero, and obviously no shuffling is needed when only one
weight is zero; but other weight combinations are possible, such as (1, 0, 0).
parent ee7502ac
Pipeline #487 passed with stage
in 27 minutes and 36 seconds
......@@ -216,36 +216,27 @@ static void srv_shuffle(srv_record *a, int n) {
for (i=0; i<n; i++)
total += a[i].weight;
/* all weights are zero, do a straight Fisher-Yates shuffle */
if (!total) {
while (n) {
srv_record t;
i = srv_rand() * n--;
t = a[n];
a[n] = a[i];
a[i] = t;
}
return;
}
/* Do a shuffle per RFC2782 Page 4 */
p = n;
for (i=0; i<n-1; i++) {
r = srv_rand() * total;
for (j=0; j<p; j++) {
r -= a[j].weight;
if (r < 0) {
if (j) {
srv_record t = a[0];
a[0] = a[j];
a[j] = t;
for (p=n; p>1; a++, p--) {
if (!total) {
/* all remaining weights are zero,
do a straight Fisher-Yates shuffle */
j = srv_rand() * p;
} else {
r = srv_rand() * total;
for (j=0; j<p; j++) {
r -= a[j].weight;
if (r < 0) {
total -= a[j].weight;
break;
}
total -= a[0].weight;
a++;
p--;
break;
}
}
if (j && j<p) {
srv_record t = a[0];
a[0] = a[j];
a[j] = t;
}
}
}
#endif /* HAVE_RES_QUERY */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment