shuf: add a TODO, code shrink

function                                             old     new   delta
shuf_main                                            501     500      -1

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2021-09-07 22:51:42 +02:00
parent 574b9c446d
commit 6a9b3f7acf

View File

@ -44,21 +44,25 @@
*/ */
static void shuffle_lines(char **lines, unsigned numlines, unsigned outlines) static void shuffle_lines(char **lines, unsigned numlines, unsigned outlines)
{ {
unsigned i;
unsigned r;
char *tmp;
srand(monotonic_us()); srand(monotonic_us());
for (i = numlines - 1; outlines > 0; i--, outlines--) { while (outlines != 0) {
r = rand(); char *tmp;
unsigned r = rand();
/* RAND_MAX can be as small as 32767 */ /* RAND_MAX can be as small as 32767 */
if (i > RAND_MAX) if (numlines > RAND_MAX)
r ^= rand() << 15; r ^= rand() << 15;
r %= i + 1; r %= numlines;
tmp = lines[i]; //TODO: the above method is seriously non-uniform when numlines is very large.
lines[i] = lines[r]; //For example, with numlines of 0xf0000000,
//values of (r % numlines) in [0, 0x0fffffff] range
//are more likely: e.g. r=1 and r=0xf0000001 both map to 1,
//whereas only one value, r=0xefffffff, maps to 0xefffffff.
numlines--;
tmp = lines[numlines];
lines[numlines] = lines[r];
lines[r] = tmp; lines[r] = tmp;
outlines--;
} }
} }