diff -r b0c958c0e6c6 -r f02ffcb61dce src/java.base/share/classes/java/util/random/L128X256MixRandom.java --- a/src/java.base/share/classes/java/util/random/L128X256MixRandom.java Thu Jun 27 18:02:51 2019 -0300 +++ b/src/java.base/share/classes/java/util/random/L128X256MixRandom.java Thu Jun 27 18:30:27 2019 -0300 @@ -22,7 +22,8 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package java.util; + +package java.util.random; import java.math.BigInteger; import java.util.concurrent.atomic.AtomicLong; @@ -30,14 +31,14 @@ /** * A generator of uniform pseudorandom values applicable for use in * (among other contexts) isolated parallel computations that may - * generate subtasks. Class {@code L128X256MixRandom} implements - * interfaces {@link java.util.Rng} and {@link java.util.SplittableRng}, + * generate subtasks. Class {@link L128X256MixRandom} implements + * interfaces {@link RandomNumberGenerator} and {@link SplittableRNG}, * and therefore supports methods for producing pseudorandomly chosen * numbers of type {@code int}, {@code long}, {@code float}, and {@code double} - * as well as creating new split-off {@code L128X256MixRandom} objects, + * as well as creating new split-off {@link L128X256MixRandom} objects, * with similar usages as for class {@link java.util.SplittableRandom}. - * - *

Series of generated values pass the TestU01 BigCrush and PractRand test suites + *

+ * Series of generated values pass the TestU01 BigCrush and PractRand test suites * that measure independence and uniformity properties of random number generators. * (Most recently validated with * version 1.2.3 of TestU01 @@ -47,56 +48,56 @@ * These tests validate only the methods for certain * types and ranges, but similar properties are expected to hold, at * least approximately, for others as well. - * - *

{@code L128X256MixRandom} is a specific member of the LXM family of algorithms + *

+ * {@link L128X256MixRandom} is a specific member of the LXM family of algorithms * for pseudorandom number generators. Every LXM generator consists of two * subgenerators; one is an LCG (Linear Congruential Generator) and the other is * an Xorshift generator. Each output of an LXM generator is the sum of one * output from each subgenerator, possibly processed by a final mixing function - * (and {@code L128X256MixRandom} does use a mixing function). - * - *

The LCG subgenerator for {@code L128X256MixRandom} has an update step of the + * (and {@link L128X256MixRandom} does use a mixing function). + *

+ * The LCG subgenerator for {@link L128X256MixRandom} has an update step of the * form {@code s = m * s + a}, where {@code s}, {@code m}, and {@code a} are all * 128-bit integers; {@code s} is the mutable state, the multiplier {@code m} - * is fixed (the same for all instances of {@code L128X256MixRandom}}) and the addend + * is fixed (the same for all instances of {@link L128X256MixRandom}}) and the addend * {@code a} is a parameter (a final field of the instance). The parameter * {@code a} is required to be odd (this allows the LCG to have the maximal * period, namely 2128); therefore there are 2127 distinct choices * of parameter. - * - *

The Xorshift subgenerator for {@code L128X256MixRandom} is the {@code xoshiro256} algorithm, + *

+ * The Xorshift subgenerator for {@link L128X256MixRandom} is the {@code xoshiro256} algorithm, * version 1.0 (parameters 17, 45), without any final scrambler such as "+" or "**". * Its state consists of four {@code long} fields {@code x0}, {@code x1}, {@code x2}, * and {@code x3}, which can take on any values provided that they are not all zero. * The period of this subgenerator is 2256-1. - * - *

The mixing function for {@code L128X256MixRandom} is the 64-bit MurmurHash3 finalizer. - * - *

Because the periods 2128 and 2256-1 of the two subgenerators - * are relatively prime, the period of any single {@code L128X256MixRandom} object + *

+ * The mixing function for {@link L128X256MixRandom} is the 64-bit MurmurHash3 finalizer. + *

+ * Because the periods 2128 and 2256-1 of the two subgenerators + * are relatively prime, the period of any single {@link L128X256MixRandom} object * (the length of the series of generated 64-bit values before it repeats) is the product * of the periods of the subgenerators, that is, 2128(2256-1), * which is just slightly smaller than 2384. Moreover, if two distinct - * {@code L128X256MixRandom} objects have different {@code a} parameters, then their + * {@link L128X256MixRandom} objects have different {@code a} parameters, then their * cycles of produced values will be different. - * - *

The 64-bit values produced by the {@code nextLong()} method are exactly equidistributed. - * For any specific instance of {@code L128X256MixRandom}, over the course of its cycle each + *

+ * The 64-bit values produced by the {@code nextLong()} method are exactly equidistributed. + * For any specific instance of {@link L128X256MixRandom}, over the course of its cycle each * of the 264 possible {@code long} values will be produced 2256-1 times. * The values produced by the {@code nextInt()}, {@code nextFloat()}, and {@code nextDouble()} * methods are likewise exactly equidistributed. - * - *

In fact, the 64-bit values produced by the {@code nextLong()} method are exactly - * 2-equidistributed. For any specific instance of {@code L128X256MixRandom}, consider + *

+ * In fact, the 64-bit values produced by the {@code nextLong()} method are exactly + * 2-equidistributed. For any specific instance of {@link L128X256MixRandom}, consider * the (overlapping) length-2 subsequences of the cycle of 64-bit values produced by * {@code nextLong()} (assuming no other methods are called that would affect the state). * There are 2128(2256-1) such subsequences, and each subsequence, * which consists of 2 64-bit values, can have one of 2128 values, and each * such value occurs 2256-1 times. The values produced by the {@code nextInt()}, * {@code nextFloat()}, and {@code nextDouble()} methods are likewise exactly 2-equidistributed. - * - *

Moreover, the 64-bit values produced by the {@code nextLong()} method are 4-equidistributed. - * To be precise: for any specific instance of {@code L128X256MixRandom}, consider + *

+ * Moreover, the 64-bit values produced by the {@code nextLong()} method are 4-equidistributed. + * To be precise: for any specific instance of {@link L128X256MixRandom}, consider * the (overlapping) length-4 subsequences of the cycle of 64-bit values produced by * {@code nextLong()} (assuming no other methods are called that would affect the state). * There are 128(2256-1) such subsequences, and each subsequence, @@ -107,43 +108,42 @@ * of the probability of getting one of the less common subsequence values and the * probability of getting one of the more common subsequence values is 1-2-128. * (Note that the set of 2128 less-common subsequence values will differ from - * one instance of {@code L128X256MixRandom} to another, as a function of the additive + * one instance of {@link L128X256MixRandom} to another, as a function of the additive * parameter of the LCG.) The values produced by the {@code nextInt()}, {@code nextFloat()}, * and {@code nextDouble()} methods are likewise 4-equidistributed. - * - *

Method {@link #split} constructs and returns a new {@code L128X256MixRandom} + *

+ * Method {@link #split} constructs and returns a new {@link L128X256MixRandom} * instance that shares no mutable state with the current instance. However, with * very high probability, the values collectively generated by the two objects * have the same statistical properties as if the same quantity of values were - * generated by a single thread using a single {@code L128X256MixRandom} object. - * This is because, with high probability, distinct {@code L128X256MixRandom} objects + * generated by a single thread using a single {@link L128X256MixRandom} object. + * This is because, with high probability, distinct {@link L128X256MixRandom} objects * have distinct {@code a} parameters and therefore use distinct members of the * algorithmic family; and even if their {@code a} parameters are the same, with * very high probability they will traverse different parts of their common state * cycle. - * - *

As with {@link java.util.SplittableRandom}, instances of - * {@code L128X256MixRandom} are not thread-safe. + *

+ * As with {@link java.util.SplittableRandom}, instances of + * {@link L128X256MixRandom} are not thread-safe. * They are designed to be split, not shared, across threads. For * example, a {@link java.util.concurrent.ForkJoinTask} fork/join-style * computation using random numbers might include a construction * of the form {@code new Subtask(someL128X256MixRandom.split()).fork()}. - * - *

This class provides additional methods for generating random + *

+ * This class provides additional methods for generating random * streams, that employ the above techniques when used in * {@code stream.parallel()} mode. - * - *

Instances of {@code L128X256MixRandom} are not cryptographically + *

+ * Instances of {@link L128X256MixRandom} are not cryptographically * secure. Consider instead using {@link java.security.SecureRandom} * in security-sensitive applications. Additionally, * default-constructed instances do not use a cryptographically random * seed unless the {@linkplain System#getProperty system property} * {@code java.util.secureRandomSeed} is set to {@code true}. * - * @author Guy Steele - * @since 1.9 + * @since 14 */ -public final class L128X256MixRandom extends AbstractSplittableRng { +public final class L128X256MixRandom extends AbstractSplittableRNG { /* * Implementation Overview. @@ -158,7 +158,7 @@ * * With extremely high probability, no two generators so chosen * will have the same `a` parameter, and testing has indicated - * that the values generated by two instances of {@code L128X256MixRandom} + * that the values generated by two instances of {@link L128X256MixRandom} * will be (approximately) independent if have different values for `a`. * * The default (no-argument) constructor, in essence, uses @@ -181,13 +181,13 @@ /** * The seed generator for default constructors. */ - private static final AtomicLong defaultGen = new AtomicLong(RngSupport.initialSeed()); + private static final AtomicLong defaultGen = new AtomicLong(RNGSupport.initialSeed()); /* * The period of this generator, which is (2**256 - 1) * 2**128. */ - private static final BigInteger thePeriod = - BigInteger.ONE.shiftLeft(256).subtract(BigInteger.ONE).shiftLeft(128); + private static final BigInteger PERIOD = + BigInteger.ONE.shiftLeft(256).subtract(BigInteger.ONE).shiftLeft(128); /* * The multiplier used in the LCG portion of the algorithm is 2**64 + m; @@ -205,7 +205,7 @@ * 64-bit arithmetic to work with. */ - private static final long m = 2862933555777941757L; + private static final long M = 2862933555777941757L; /* ---------------- instance fields ---------------- */ @@ -238,7 +238,7 @@ * @param x3 fourth word of the initial state for the xorshift generator */ public L128X256MixRandom(long ah, long al, long sh, long sl, long x0, long x1, long x2, long x3) { - // Force a to be odd. + // Force a to be odd. this.ah = ah; this.al = al | 1; this.sh = sh; @@ -247,67 +247,67 @@ this.x1 = x1; this.x2 = x2; this.x3 = x3; - // If x0, x1, x2, and x3 are all zero, we must choose nonzero values. + // If x0, x1, x2, and x3 are all zero, we must choose nonzero values. if ((x0 | x1 | x2 | x3) == 0) { - // At least three of the four values generated here will be nonzero. - this.x0 = RngSupport.mixStafford13(sh += RngSupport.GOLDEN_RATIO_64); - this.x1 = RngSupport.mixStafford13(sh += RngSupport.GOLDEN_RATIO_64); - this.x2 = RngSupport.mixStafford13(sh += RngSupport.GOLDEN_RATIO_64); - this.x3 = RngSupport.mixStafford13(sh + RngSupport.GOLDEN_RATIO_64); - } + // At least three of the four values generated here will be nonzero. + this.x0 = RNGSupport.mixStafford13(sh += RNGSupport.GOLDEN_RATIO_64); + this.x1 = RNGSupport.mixStafford13(sh += RNGSupport.GOLDEN_RATIO_64); + this.x2 = RNGSupport.mixStafford13(sh += RNGSupport.GOLDEN_RATIO_64); + this.x3 = RNGSupport.mixStafford13(sh + RNGSupport.GOLDEN_RATIO_64); + } } /** - * Creates a new instance of {@code L128X256MixRandom} using the + * Creates a new instance of {@link L128X256MixRandom} using the * specified {@code long} value as the initial seed. Instances of - * {@code L128X256MixRandom} created with the same seed in the same + * {@link L128X256MixRandom} created with the same seed in the same * program generate identical sequences of values. * * @param seed the initial seed */ public L128X256MixRandom(long seed) { - // Using a value with irregularly spaced 1-bits to xor the seed - // argument tends to improve "pedestrian" seeds such as 0 or - // other small integers. We may as well use SILVER_RATIO_64. - // - // The seed is hashed by mixMurmur64 to produce the `a` parameter. - // The seed is hashed by mixStafford13 to produce the initial `x0`, - // which will then be used to produce the first generated value. - // The other x values are filled in as if by a SplitMix PRNG with - // GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer. - this(RngSupport.mixMurmur64(seed ^= RngSupport.SILVER_RATIO_64), - RngSupport.mixMurmur64(seed += RngSupport.GOLDEN_RATIO_64), - 0, - 1, - RngSupport.mixStafford13(seed), - RngSupport.mixStafford13(seed += RngSupport.GOLDEN_RATIO_64), - RngSupport.mixStafford13(seed += RngSupport.GOLDEN_RATIO_64), - RngSupport.mixStafford13(seed + RngSupport.GOLDEN_RATIO_64)); + // Using a value with irregularly spaced 1-bits to xor the seed + // argument tends to improve "pedestrian" seeds such as 0 or + // other small integers. We may as well use SILVER_RATIO_64. + // + // The seed is hashed by mixMurmur64 to produce the `a` parameter. + // The seed is hashed by mixStafford13 to produce the initial `x0`, + // which will then be used to produce the first generated value. + // The other x values are filled in as if by a SplitMix PRNG with + // GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer. + this(RNGSupport.mixMurmur64(seed ^= RNGSupport.SILVER_RATIO_64), + RNGSupport.mixMurmur64(seed += RNGSupport.GOLDEN_RATIO_64), + 0, + 1, + RNGSupport.mixStafford13(seed), + RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64), + RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64), + RNGSupport.mixStafford13(seed + RNGSupport.GOLDEN_RATIO_64)); } /** - * Creates a new instance of {@code L128X256MixRandom} that is likely to + * Creates a new instance of {@link L128X256MixRandom} that is likely to * generate sequences of values that are statistically independent * of those of any other instances in the current program execution, * but may, and typically does, vary across program invocations. */ public L128X256MixRandom() { - // Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values. - this(defaultGen.getAndAdd(RngSupport.GOLDEN_RATIO_64)); + // Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values. + this(defaultGen.getAndAdd(RNGSupport.GOLDEN_RATIO_64)); } /** - * Creates a new instance of {@code L128X256MixRandom} using the specified array of - * initial seed bytes. Instances of {@code L128X256MixRandom} created with the same + * Creates a new instance of {@link L128X256MixRandom} using the specified array of + * initial seed bytes. Instances of {@link L128X256MixRandom} created with the same * seed array in the same program execution generate identical sequences of values. * * @param seed the initial seed */ public L128X256MixRandom(byte[] seed) { - // Convert the seed to 6 long values, of which the last 4 are not all zero. - long[] data = RngSupport.convertSeedBytesToLongs(seed, 6, 4); - long ah = data[0], al = data[1], sh = data[2], sl = data[3], x0 = data[4], x1 = data[5], x2 = data[6], x3 = data[7]; - // Force a to be odd. + // Convert the seed to 6 long values, of which the last 4 are not all zero. + long[] data = RNGSupport.convertSeedBytesToLongs(seed, 6, 4); + long ah = data[0], al = data[1], sh = data[2], sl = data[3], x0 = data[4], x1 = data[5], x2 = data[6], x3 = data[7]; + // Force a to be odd. this.ah = ah; this.al = al | 1; this.sh = sh; @@ -319,29 +319,29 @@ } /* ---------------- public methods ---------------- */ - + /** - * Constructs and returns a new instance of {@code L128X256MixRandom} + * Constructs and returns a new instance of {@link L128X256MixRandom} * that shares no mutable state with this instance. * However, with very high probability, the set of values collectively * generated by the two objects has the same statistical properties as if * same the quantity of values were generated by a single thread using - * a single {@code L128X256MixRandom} object. Either or both of the two + * a single {@link L128X256MixRandom} object. Either or both of the two * objects may be further split using the {@code split} method, * and the same expected statistical properties apply to the * entire set of generators constructed by such recursive splitting. * - * @param source a {@code SplittableRng} instance to be used instead + * @param source a {@link SplittableRNG} instance to be used instead * of this one as a source of pseudorandom bits used to * initialize the state of the new ones. - * @return a new instance of {@code L128X256MixRandom} + * @return a new instance of {@link L128X256MixRandom} */ - public L128X256MixRandom split(SplittableRng source) { - // Literally pick a new instance "at random". - return new L128X256MixRandom(source.nextLong(), source.nextLong(), - source.nextLong(), source.nextLong(), - source.nextLong(), source.nextLong(), - source.nextLong(), source.nextLong()); + public L128X256MixRandom split(SplittableRNG source) { + // Literally pick a new instance "at random". + return new L128X256MixRandom(source.nextLong(), source.nextLong(), + source.nextLong(), source.nextLong(), + source.nextLong(), source.nextLong(), + source.nextLong(), source.nextLong()); } /** @@ -349,19 +349,20 @@ * * @return a pseudorandom {@code long} value */ - public long nextLong() { - final long z = sh + x0; - // The LCG: in effect, s = ((1LL << 64) + m) * s + a, if only we had 128-bit arithmetic. - final long u = m * sl; - sh = (m * sh) + Math.multiplyHigh(m, sl) + sl + ah; - sl = u + al; - if (Long.compareUnsigned(sl, u) < 0) ++sh; // Handle the carry propagation from low half to high half. - long q0 = x0, q1 = x1, q2 = x2, q3 = x3; - { long t = q1 << 17; q2 ^= q0; q3 ^= q1; q1 ^= q2; q0 ^= q3; q2 ^= t; q3 = Long.rotateLeft(q3, 45); } // xoshiro256 1.0 - x0 = q0; x1 = q1; x2 = q2; x3 = q3; - return RngSupport.mixLea64(z); // mixing function + final long z = sh + x0; + // The LCG: in effect, s = ((1LL << 64) + M) * s + a, if only we had 128-bit arithmetic. + final long u = M * sl; + sh = (M * sh) + Math.multiplyHigh(M, sl) + sl + ah; + sl = u + al; + if (Long.compareUnsigned(sl, u) < 0) ++sh; // Handle the carry propagation from low half to high half. + long q0 = x0, q1 = x1, q2 = x2, q3 = x3; + { long t = q1 << 17; q2 ^= q0; q3 ^= q1; q1 ^= q2; q0 ^= q3; q2 ^= t; q3 = Long.rotateLeft(q3, 45); } // xoshiro256 1.0 + x0 = q0; x1 = q1; x2 = q2; x3 = q3; + return RNGSupport.mixLea64(z); // mixing function } - public BigInteger period() { return thePeriod; } + public BigInteger period() { + return PERIOD; + } }