1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.rng.examples.stress;
18
19 import org.apache.commons.rng.UniformRandomProvider;
20 import org.apache.commons.rng.core.source32.IntProvider;
21 import org.apache.commons.rng.core.source32.RandomIntSource;
22 import org.apache.commons.rng.core.source64.RandomLongSource;
23 import org.apache.commons.rng.core.util.NumberFactory;
24 import org.apache.commons.rng.core.source64.LongProvider;
25
26 import java.io.OutputStream;
27 import java.nio.ByteOrder;
28 import java.util.concurrent.ThreadLocalRandom;
29
30
31
32
33 final class RNGUtils {
34
35
36 private static final String BYTE_REVERSED = "Byte-reversed ";
37
38
39 private static final String BIT_REVERSED = "Bit-reversed ";
40
41
42 private static final String HASH_CODE = "HashCode ^ ";
43
44
45 private static final String TLR_MIXED = "ThreadLocalRandom ^ ";
46
47
48 private static final String XOR = " ^ ";
49
50
51 private static final String UNRECOGNISED_SOURCE_64_MODE = "Unrecognized source64 mode: ";
52
53
54 private static final String UNRECOGNISED_NATIVE_TYPE = "Unrecognized native output type: ";
55
56
57 private static final Source64Mode SOURCE_64_DEFAULT = Source64Mode.LO_HI;
58
59
60 private RNGUtils() {}
61
62
63
64
65
66
67 static Source64Mode getSource64Default() {
68 return SOURCE_64_DEFAULT;
69 }
70
71
72
73
74
75
76
77
78
79
80
81
82 static UniformRandomProvider createReverseBytesProvider(final UniformRandomProvider rng) {
83 if (rng instanceof RandomIntSource) {
84 return new IntProvider() {
85 @Override
86 public int next() {
87 return Integer.reverseBytes(rng.nextInt());
88 }
89
90 @Override
91 public String toString() {
92 return BYTE_REVERSED + rng.toString();
93 }
94 };
95 }
96 if (rng instanceof RandomLongSource) {
97 return new LongProvider() {
98 @Override
99 public long next() {
100 return Long.reverseBytes(rng.nextLong());
101 }
102
103 @Override
104 public String toString() {
105 return BYTE_REVERSED + rng.toString();
106 }
107 };
108 }
109 throw new ApplicationException(UNRECOGNISED_NATIVE_TYPE + rng);
110 }
111
112
113
114
115
116
117
118
119
120
121
122
123 static UniformRandomProvider createReverseBitsProvider(final UniformRandomProvider rng) {
124 if (rng instanceof RandomIntSource) {
125 return new IntProvider() {
126 @Override
127 public int next() {
128 return Integer.reverse(rng.nextInt());
129 }
130
131 @Override
132 public String toString() {
133 return BIT_REVERSED + rng.toString();
134 }
135 };
136 }
137 if (rng instanceof RandomLongSource) {
138 return new LongProvider() {
139 @Override
140 public long next() {
141 return Long.reverse(rng.nextLong());
142 }
143
144 @Override
145 public String toString() {
146 return BIT_REVERSED + rng.toString();
147 }
148 };
149 }
150 throw new ApplicationException(UNRECOGNISED_NATIVE_TYPE + rng);
151 }
152
153
154
155
156
157
158
159
160
161
162
163 static <R extends RandomLongSource & UniformRandomProvider>
164 UniformRandomProvider createIntProvider(final R rng, Source64Mode mode) {
165 switch (mode) {
166 case INT:
167 return createIntProvider(rng);
168 case LO_HI:
169 return createLongLowerUpperBitsIntProvider(rng);
170 case HI_LO:
171 return createLongUpperLowerBitsIntProvider(rng);
172 case HI:
173 return createLongUpperBitsIntProvider(rng);
174 case LO:
175 return createLongLowerBitsIntProvider(rng);
176 case LONG:
177 default:
178 throw new IllegalArgumentException("Unsupported mode " + mode);
179 }
180 }
181
182
183
184
185
186
187
188
189
190 private static UniformRandomProvider createIntProvider(final UniformRandomProvider rng) {
191 if (!(rng instanceof RandomIntSource)) {
192 return new IntProvider() {
193 @Override
194 public int next() {
195 return rng.nextInt();
196 }
197
198 @Override
199 public String toString() {
200 return "Int bits " + rng.toString();
201 }
202 };
203 }
204 return rng;
205 }
206
207
208
209
210
211
212
213
214
215 private static UniformRandomProvider createLongLowerUpperBitsIntProvider(final RandomLongSource rng) {
216 return new IntProvider() {
217 private long source = -1;
218
219 @Override
220 public int next() {
221 long next = source;
222 if (next < 0) {
223
224 next = rng.next();
225
226 source = next >>> 32;
227
228 return (int) next;
229 }
230 final int v = (int) next;
231
232 source = -1;
233 return v;
234 }
235
236 @Override
237 public String toString() {
238 return "Long lower-upper bits " + rng.toString();
239 }
240 };
241 }
242
243
244
245
246
247
248
249
250
251 private static UniformRandomProvider createLongUpperLowerBitsIntProvider(final RandomLongSource rng) {
252 return new IntProvider() {
253 private long source = -1;
254
255 @Override
256 public int next() {
257 long next = source;
258 if (next < 0) {
259
260 next = rng.next();
261
262 source = next & 0xffff_ffffL;
263
264 return (int) (next >>> 32);
265 }
266 final int v = (int) next;
267
268 source = -1;
269 return v;
270 }
271
272 @Override
273 public String toString() {
274 return "Long upper-lower bits " + rng.toString();
275 }
276 };
277 }
278
279
280
281
282
283
284
285
286
287
288 private static UniformRandomProvider createLongUpperBitsIntProvider(final RandomLongSource rng) {
289 return new IntProvider() {
290 @Override
291 public int next() {
292 return (int) (rng.next() >>> 32);
293 }
294
295 @Override
296 public String toString() {
297 return "Long upper-bits " + rng.toString();
298 }
299 };
300 }
301
302
303
304
305
306
307
308
309
310
311 private static UniformRandomProvider createLongLowerBitsIntProvider(final RandomLongSource rng) {
312 return new IntProvider() {
313 @Override
314 public int next() {
315 return (int) rng.next();
316 }
317
318 @Override
319 public String toString() {
320 return "Long lower-bits " + rng.toString();
321 }
322 };
323 }
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343 static UniformRandomProvider createHashCodeProvider(final UniformRandomProvider rng) {
344 if (rng instanceof RandomIntSource) {
345 return new IntProvider() {
346 @Override
347 public int next() {
348 return System.identityHashCode(new Object()) ^ rng.nextInt();
349 }
350
351 @Override
352 public String toString() {
353 return HASH_CODE + rng.toString();
354 }
355 };
356 }
357 if (rng instanceof RandomLongSource) {
358 return new LongProvider() {
359 @Override
360 public long next() {
361 final long mix = NumberFactory.makeLong(System.identityHashCode(new Object()),
362 System.identityHashCode(new Object()));
363 return mix ^ rng.nextLong();
364 }
365
366 @Override
367 public String toString() {
368 return HASH_CODE + rng.toString();
369 }
370 };
371 }
372 throw new ApplicationException(UNRECOGNISED_NATIVE_TYPE + rng);
373 }
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390 static UniformRandomProvider createThreadLocalRandomProvider(final UniformRandomProvider rng) {
391 if (rng instanceof RandomIntSource) {
392 return new IntProvider() {
393 @Override
394 public int next() {
395 return ThreadLocalRandom.current().nextInt() ^ rng.nextInt();
396 }
397
398 @Override
399 public String toString() {
400 return TLR_MIXED + rng.toString();
401 }
402 };
403 }
404 if (rng instanceof RandomLongSource) {
405 return new LongProvider() {
406 @Override
407 public long next() {
408 return ThreadLocalRandom.current().nextLong() ^ rng.nextLong();
409 }
410
411 @Override
412 public String toString() {
413 return TLR_MIXED + rng.toString();
414 }
415 };
416 }
417 throw new ApplicationException(UNRECOGNISED_NATIVE_TYPE + rng);
418 }
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436 static UniformRandomProvider createXorProvider(final UniformRandomProvider rng1,
437 final UniformRandomProvider rng2) {
438 if (rng1 instanceof RandomIntSource) {
439 return new IntProvider() {
440 @Override
441 public int next() {
442 return rng1.nextInt() ^ rng2.nextInt();
443 }
444
445 @Override
446 public String toString() {
447 return rng1.toString() + XOR + rng2.toString();
448 }
449 };
450 }
451 if (rng1 instanceof RandomLongSource) {
452 return new LongProvider() {
453 @Override
454 public long next() {
455 return rng1.nextLong() ^ rng2.nextLong();
456 }
457
458 @Override
459 public String toString() {
460 return rng1.toString() + XOR + rng2.toString();
461 }
462 };
463 }
464 throw new ApplicationException(UNRECOGNISED_NATIVE_TYPE + rng1);
465 }
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511 static RngDataOutput createDataOutput(final UniformRandomProvider rng, Source64Mode source64,
512 OutputStream out, int byteSize, ByteOrder byteOrder) {
513 if (rng instanceof RandomIntSource) {
514 return RngDataOutput.ofInt(out, byteSize / 4, byteOrder);
515 }
516 if (rng instanceof RandomLongSource) {
517 switch (source64) {
518 case HI_LO:
519 return RngDataOutput.ofLongAsHLInt(out, byteSize / 8, byteOrder);
520 case LO_HI:
521 return RngDataOutput.ofLongAsLHInt(out, byteSize / 8, byteOrder);
522 case LONG:
523 return RngDataOutput.ofLong(out, byteSize / 8, byteOrder);
524
525 case INT:
526 case LO:
527 case HI:
528 default:
529 throw new ApplicationException(UNRECOGNISED_SOURCE_64_MODE + source64);
530 }
531 }
532 throw new ApplicationException(UNRECOGNISED_NATIVE_TYPE + rng);
533 }
534
535
536
537
538
539
540
541
542
543
544
545
546 static Object parseArgument(String argument) {
547 try {
548
549
550
551
552 return Integer.parseInt(argument);
553 } catch (final NumberFormatException ex) {
554 throw new ApplicationException("Failed to parse RandomSource argument: " + argument, ex);
555 }
556 }
557 }