return (a->key - b->key);
}
+static inline void
+swap_rdata(dns_rdata_t *in, unsigned int a, unsigned int b) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ rdata = in[a];
+ in[a] = in[b];
+ in[b] = rdata;
+}
+
static isc_result_t
towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
dns_compress_t *cctx, isc_buffer_t *target,
isc_boolean_t partial, unsigned int options,
unsigned int *countp, void **state)
{
- dns_rdata_t rdata = DNS_RDATA_INIT;
isc_region_t r;
isc_result_t result;
- unsigned int i, count = 0, added, choice;
+ unsigned int i, count = 0, added;
isc_buffer_t savedbuffer, rdlen, rrbuffer;
unsigned int headlen;
isc_boolean_t question = ISC_FALSE;
}
}
- if ((shuffle || sort) && count > MAX_SHUFFLE) {
- in = isc_mem_get(cctx->mctx, count * sizeof(*in));
- out = isc_mem_get(cctx->mctx, count * sizeof(*out));
- if (in == NULL || out == NULL)
- shuffle = sort = ISC_FALSE;
+ if ((shuffle || sort)) {
+ if (count > MAX_SHUFFLE) {
+ in = isc_mem_get(cctx->mctx, count * sizeof(*in));
+ out = isc_mem_get(cctx->mctx, count * sizeof(*out));
+ if (in == NULL || out == NULL) {
+ shuffle = sort = ISC_FALSE;
+ }
+ }
}
- if (shuffle || sort) {
+ if ((shuffle || sort)) {
/*
* First we get handles to all of the rdata.
*/
i++;
result = dns_rdataset_next(rdataset);
} while (result == ISC_R_SUCCESS);
- if (result != ISC_R_NOMORE)
+ if (result != ISC_R_NOMORE) {
goto cleanup;
+ }
INSIST(i == count);
- }
- if (shuffle) {
- if (want_random) {
- /*
- * 'Random' order.
- */
- isc_uint32_t val = isc_random32();
- for (i = 0; i < count; i++) {
- choice = i + val % (count - i);
- rdata = in[i];
- in[i] = in[choice];
- in[choice] = rdata;
- if (order != NULL)
- out[i].key = (*order)(&in[i],
- order_arg);
- else
- out[i].key = 0; /* Unused */
- out[i].rdata = &in[i];
- }
- } else if (want_cyclic) {
- /*
- * 'Cyclic' order.
- */
- isc_uint32_t val;
- unsigned int j;
+ unsigned int j, seed;
+ if (ISC_LIKELY(want_random)) {
+ seed = isc_random32();
+ j = 0;
+ }
- val = rdataset->count;
- if (val == ISC_UINT32_MAX) {
- val = isc_random32();
+ if (ISC_UNLIKELY(want_cyclic) && (rdataset->count < ISC_UINT32_MAX)) {
+ j = rdataset->count % count;
+ } else { /* Otherwise, just start from beginning */
+ j = 0;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (ISC_LIKELY(want_random)) {
+ swap_rdata(in, j, j + seed % (count - j));
}
- j = val % count;
- for (i = 0; i < count; i++) {
- if (order != NULL)
- out[i].key = (*order)(&in[j],
- order_arg);
- else
- out[i].key = 0; /* Unused */
- out[i].rdata = &in[j];
- j++;
- if (j == count)
- j = 0; /* Wrap around. */
+
+ out[i].key = (sort) ?
+ (*order)(&in[j], order_arg) :
+ 0;
+ out[i].rdata = &in[j];
+ if (++j == count) {
+ j = 0;
}
}
- } else if (sort) {
- for (i = 0; i < count; i++) {
- if (order != NULL)
- out[i].key = (*order)(&in[i], order_arg);
- else
- out[i].key = 0; /* Unused */
- out[i].rdata = &in[i];
+ /*
+ * Sortlist order.
+ */
+ if (sort) {
+ qsort(out, count, sizeof(out[0]), towire_compare);
}
}
- /*
- * Sortlist order.
- */
- if (sort) {
- qsort(out, count, sizeof(out[0]), towire_compare);
- }
-
savedbuffer = *target;
i = 0;
added = 0;
isc_buffer_putuint16(target, rdataset->type);
isc_buffer_putuint16(target, rdataset->rdclass);
if (!question) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+
isc_buffer_putuint32(target, rdataset->ttl);
/*