Compare commits

...

3 Commits

Author SHA1 Message Date
Mark Andrews
6f3caf2d5a skip small primes 2018-08-10 11:26:38 +10:00
Mark Andrews
bd89095d8c silence 'may be used uninitialized in' 2018-08-08 17:35:38 +10:00
Mark Andrews
666a32b89b provide full distributio with random 2018-08-08 17:24:04 +10:00

View File

@@ -400,6 +400,7 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
}
if ((shuffle || sort)) {
div_t q = { 0, 0 };
/*
* First we get handles to all of the rdata.
*/
@@ -417,9 +418,8 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
INSIST(i == count);
unsigned int j;
isc_uint32_t seed;
if (ISC_LIKELY(want_random)) {
seed = isc_random32();
q.quot = isc_random32() & 0x7fffffff;
j = 0;
}
@@ -433,7 +433,31 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
for (i = 0; i < count; i++) {
if (ISC_LIKELY(want_random)) {
swap_rdata(in, j, j + seed % (count - j));
/*
* We need to divide q.quot when the divisor
* is not a prime so that we don't use a
* factor of the divisor when sampling in a
* future iteration.
*
* To avoid reseeding more often than needed,
* we can skip updating q.quot when the
* divisor is prime. We do this for small
* primes.
*/
int d = count - j;
switch (d) {
case 1: case 2: case 3: case 5:
case 7: case 11: case 13: case 17:
q.rem = q.quot % d;
break;
default:
q = div(q.quot, d);
break;
}
swap_rdata(in, j, j + q.rem);
if (ISC_UNLIKELY(q.quot == 0)) {
q.quot = isc_random32() & 0x7fffffff;
}
}
out[i].key = (sort) ?