diff -r b0c958c0e6c6 -r f02ffcb61dce src/java.base/share/classes/java/util/random/L64X128MixRandom.java --- a/src/java.base/share/classes/java/util/random/L64X128MixRandom.java Thu Jun 27 18:02:51 2019 -0300 +++ b/src/java.base/share/classes/java/util/random/L64X128MixRandom.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 L64X128MixRandom} implements - * interfaces {@link java.util.Rng} and {@link java.util.SplittableRng}, + * generate subtasks. Class {@link L64X128MixRandom} 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 L64X128MixRandom} objects, + * as well as creating new split-off {@link L64X128MixRandom} 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,47 +48,47 @@ * 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 L64X128MixRandom} is a specific member of the LXM family of algorithms + *

+ * {@link L64X128MixRandom} 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 L64X128MixRandom} does use a mixing function). - * - *

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

+ * The LCG subgenerator for {@link L64X128MixRandom} has an update step of the * form {@code s = m * s + a}, where {@code s}, {@code m}, and {@code a} are all * of type {@code long}; {@code s} is the mutable state, the multiplier {@code m} - * is fixed (the same for all instances of {@code L64X128MixRandom}}) and the addend + * is fixed (the same for all instances of {@link L64X128MixRandom}}) 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 264); therefore there are 263 distinct choices * of parameter. - * - *

The Xorshift subgenerator for {@code L64X128MixRandom} is the {@code xoroshiro128} algorithm, + *

+ * The Xorshift subgenerator for {@link L64X128MixRandom} is the {@code xoroshiro128} algorithm, * version 1.0 (parameters 24, 16, 37), without any final scrambler such as "+" or "**". * Its state consists of two {@code long} fields {@code x0} and {@code x1}, * which can take on any values provided that they are not both zero. * The period of this subgenerator is 2128-1. - * - *

The mixing function for {@code L64X128MixRandom} is the 64-bit "starstar(5,7,9)" function. - * - *

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

+ * The mixing function for {@link L64X128MixRandom} is the 64-bit "starstar(5,7,9)" function. + *

+ * Because the periods 264 and 2128-1 of the two subgenerators + * are relatively prime, the period of any single {@link L64X128MixRandom} 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, 264(2128-1), * which is just slightly smaller than 2192. Moreover, if two distinct - * {@code L64X128MixRandom} objects have different {@code a} parameters, then their + * {@link L64X128MixRandom} 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 L64X128MixRandom}, 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 L64X128MixRandom}, over the course of its cycle each * of the 264 possible {@code long} values will be produced 2128-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 2-equidistributed. - * To be precise: for any specific instance of {@code L64X128MixRandom}, consider + *

+ * In fact, the 64-bit values produced by the {@code nextLong()} method are 2-equidistributed. + * To be precise: for any specific instance of {@link L64X128MixRandom}, 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 264(2128-1) such subsequences, and each subsequence, @@ -98,43 +99,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-64. * (Note that the set of 264 less-common subsequence values will differ from - * one instance of {@code L64X128MixRandom} to another, as a function of the additive + * one instance of {@link L64X128MixRandom} 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 2-equidistributed. - * - *

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

+ * Method {@link #split} constructs and returns a new {@link L64X128MixRandom} * 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 L64X128MixRandom} object. - * This is because, with high probability, distinct {@code L64X128MixRandom} objects + * generated by a single thread using a single {@link L64X128MixRandom} object. + * This is because, with high probability, distinct {@link L64X128MixRandom} 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 L64X128MixRandom} are not thread-safe. + *

+ * As with {@link java.util.SplittableRandom}, instances of + * {@link L64X128MixRandom} 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(someL64X128MixRandom.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 L64X128MixRandom} are not cryptographically + *

+ * Instances of {@link L64X128MixRandom} 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 L64X128MixRandom extends AbstractSplittableRng { +public final class L64X128MixRandom extends AbstractSplittableRNG { /* * Implementation Overview. @@ -145,7 +145,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 L64X128MixRandom} + * that the values generated by two instances of {@link L64X128MixRandom} * will be (approximately) independent if have different values for `a`. * * The default (no-argument) constructor, in essence, uses @@ -162,19 +162,19 @@ * File organization: First static fields, then instance * fields, then constructors, then instance methods. */ - + /* ---------------- static fields ---------------- */ /** * 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**128 - 1) * 2**64. */ - private static final BigInteger thePeriod = - BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE).shiftLeft(64); + private static final BigInteger PERIOD = + BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE).shiftLeft(64); /* * Multiplier used in the LCG portion of the algorithm, taken from @@ -184,7 +184,7 @@ * Table 4 (first multiplier for size 264). */ - private static final long m = 2862933555777941757L; + private static final long M = 2862933555777941757L; /* ---------------- instance fields ---------------- */ @@ -213,66 +213,66 @@ * @param x1 second word of the initial state for the xorshift generator */ public L64X128MixRandom(long a, long s, long x0, long x1) { - // Force a to be odd. + // Force a to be odd. this.a = a | 1; this.s = s; - this.x0 = x0; + this.x0 = x0; this.x1 = x1; - // If x0 and x1 are both zero, we must choose nonzero values. + // If x0 and x1 are both zero, we must choose nonzero values. if ((x0 | x1) == 0) { - // At least one of the two values generated here will be nonzero. - this.x0 = RngSupport.mixStafford13(s += RngSupport.GOLDEN_RATIO_64); - this.x1 = RngSupport.mixStafford13(s + RngSupport.GOLDEN_RATIO_64); - } + // At least one of the two values generated here will be nonzero. + this.x0 = RNGSupport.mixStafford13(s += RNGSupport.GOLDEN_RATIO_64); + this.x1 = RNGSupport.mixStafford13(s + RNGSupport.GOLDEN_RATIO_64); + } } /** - * Creates a new instance of {@code L64X128MixRandom} using the + * Creates a new instance of {@link L64X128MixRandom} using the * specified {@code long} value as the initial seed. Instances of - * {@code L64X128MixRandom} created with the same seed in the same + * {@link L64X128MixRandom} created with the same seed in the same * program generate identical sequences of values. * * @param seed the initial seed */ public L64X128MixRandom(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. - // Then x1 is 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), - 1, - RngSupport.mixStafford13(seed), - 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. + // Then x1 is 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), + 1, + RNGSupport.mixStafford13(seed), + RNGSupport.mixStafford13(seed + RNGSupport.GOLDEN_RATIO_64)); } /** - * Creates a new instance of {@code L64X128MixRandom} that is likely to + * Creates a new instance of {@link L64X128MixRandom} 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 L64X128MixRandom() { - // 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 L64X128MixRandom} using the specified array of - * initial seed bytes. Instances of {@code L64X128MixRandom} created with the same + * Creates a new instance of {@link L64X128MixRandom} using the specified array of + * initial seed bytes. Instances of {@link L64X128MixRandom} created with the same * seed array in the same program execution generate identical sequences of values. * * @param seed the initial seed */ public L64X128MixRandom(byte[] seed) { - // Convert the seed to 4 long values, of which the last 2 are not all zero. - long[] data = RngSupport.convertSeedBytesToLongs(seed, 4, 2); - long a = data[0], s = data[1], x0 = data[2], x1 = data[3]; - // Force a to be odd. + // Convert the seed to 4 long values, of which the last 2 are not all zero. + long[] data = RNGSupport.convertSeedBytesToLongs(seed, 4, 2); + long a = data[0], s = data[1], x0 = data[2], x1 = data[3]; + // Force a to be odd. this.a = a | 1; this.s = s; this.x0 = x0; @@ -280,27 +280,28 @@ } /* ---------------- public methods ---------------- */ - + /** - * Constructs and returns a new instance of {@code L64X128MixRandom} + * Constructs and returns a new instance of {@link L64X128MixRandom} * 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 L64X128MixRandom} object. Either or both of the two + * a single {@link L64X128MixRandom} 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 L64X128MixRandom} + * + * @return a new instance of {@link L64X128MixRandom} */ - public L64X128MixRandom split(SplittableRng source) { - // Literally pick a new instance "at random". + public L64X128MixRandom split(SplittableRNG source) { + // Literally pick a new instance "at random". return new L64X128MixRandom(source.nextLong(), source.nextLong(), - source.nextLong(), source.nextLong()); + source.nextLong(), source.nextLong()); } /** @@ -308,15 +309,16 @@ * * @return a pseudorandom {@code long} value */ - public long nextLong() { - final long z = s + x0; - s = m * s + a; // LCG - long q0 = x0, q1 = x1; - { q1 ^= q0; q0 = Long.rotateLeft(q0, 24); q0 = q0 ^ q1 ^ (q1 << 16); q1 = Long.rotateLeft(q1, 37); } // xoroshiro128v1_0 - x0 = q0; x1 = q1; - return Long.rotateLeft(z * 5, 7) * 9; // "starstar" mixing function + final long z = s + x0; + s = M * s + a; // LCG + long q0 = x0, q1 = x1; + { q1 ^= q0; q0 = Long.rotateLeft(q0, 24); q0 = q0 ^ q1 ^ (q1 << 16); q1 = Long.rotateLeft(q1, 37); } // xoroshiro128v1_0 + x0 = q0; x1 = q1; + return Long.rotateLeft(z * 5, 7) * 9; // "starstar" mixing function } - public BigInteger period() { return thePeriod; } + public BigInteger period() { + return PERIOD; + } }