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