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

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

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

+ * The LCG subgenerator for {@link L64X1024MixRandom} 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 L64X1024MixRandom}}) and the addend + * is fixed (the same for all instances of {@link L64X1024MixRandom}}) 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 L64X1024MixRandom} is the {@code xoroshiro1024} + *

+ * The Xorshift subgenerator for {@link L64X1024MixRandom} is the {@code xoroshiro1024} * algorithm (parameters 25, 27, and 36), without any final scrambler such as "+" or "**". * Its state consists of an array {@code x} of sixteen {@code long} values, * which can take on any values provided that they are not all zero. * The period of this subgenerator is 21024-1. - * - *

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

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

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

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

+ * In fact, the 64-bit values produced by the {@code nextLong()} method are 16-equidistributed. + * To be precise: for any specific instance of {@link L64X1024MixRandom}, consider * the (overlapping) length-16 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(21024-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 L64X1024MixRandom} to another, as a function of the additive + * one instance of {@link L64X1024MixRandom} 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 16-equidistributed. - * - *

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

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

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

+ * Instances of {@link L64X1024MixRandom} 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 L64X1024MixRandom extends AbstractSplittableRng { +public final class L64X1024MixRandom 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 L64X1024MixRandom} + * that the values generated by two instances of {@link L64X1024MixRandom} * will be (approximately) independent if have different values for `a`. * * The default (no-argument) constructor, in essence, uses @@ -174,13 +174,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**1024 - 1) * 2**64. */ - private static final BigInteger thePeriod = - BigInteger.ONE.shiftLeft(N*64).subtract(BigInteger.ONE).shiftLeft(64); + private static final BigInteger PERIOD = + BigInteger.ONE.shiftLeft(N*64).subtract(BigInteger.ONE).shiftLeft(64); /* * Multiplier used in the LCG portion of the algorithm, taken from @@ -190,8 +190,8 @@ * Table 4 (first multiplier for size 264). */ - private static final long m = 2862933555777941757L; - + private static final long M = 2862933555777941757L; + /* ---------------- instance fields ---------------- */ /** @@ -236,16 +236,16 @@ * @param x15 sixteenth word of the initial state for the xorshift generator */ public L64X1024MixRandom(long a, long s, - long x0, long x1, long x2, long x3, - long x4, long x5, long x6, long x7, - long x8, long x9, long x10, long x11, - long x12, long x13, long x14, long x15) { - // Force a to be odd. + long x0, long x1, long x2, long x3, + long x4, long x5, long x6, long x7, + long x8, long x9, long x10, long x11, + long x12, long x13, long x14, long x15) { + // Force a to be odd. this.a = a | 1; this.s = s; - this.x = new long[N]; - this.x[0] = x0; - this.x[1] = x1; + this.x = new long[N]; + this.x[0] = x0; + this.x[1] = x1; this.x[2] = x2; this.x[3] = x3; this.x[4] = x4; @@ -260,113 +260,113 @@ this.x[13] = x13; this.x[14] = x14; this.x[15] = x15; - // If x0, x1, ..., x15 are all zero (very unlikely), we must choose nonzero values. + // If x0, x1, ..., x15 are all zero (very unlikely), we must choose nonzero values. if ((x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | x13 | x14 | x15) == 0) { - // At least fifteen of the sixteen values generated here will be nonzero. - for (int j = 0; j < N; j++) { - this.x[j] = RngSupport.mixStafford13(s += RngSupport.GOLDEN_RATIO_64); - } - } + // At least fifteen of the sixteen values generated here will be nonzero. + for (int j = 0; j < N; j++) { + this.x[j] = RNGSupport.mixStafford13(s += RNGSupport.GOLDEN_RATIO_64); + } + } } /** - * Creates a new instance of {@code L64X1024MixRandom} using the + * Creates a new instance of {@link L64X1024MixRandom} using the * specified {@code long} value as the initial seed. Instances of - * {@code L64X1024MixRandom} created with the same seed in the same + * {@link L64X1024MixRandom} created with the same seed in the same * program execution generate identical sequences of values. * * @param seed the initial seed */ public L64X1024MixRandom(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 `x[0]`, - // 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), - 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), - RngSupport.mixStafford13(seed += RngSupport.GOLDEN_RATIO_64), - RngSupport.mixStafford13(seed += RngSupport.GOLDEN_RATIO_64), - RngSupport.mixStafford13(seed += RngSupport.GOLDEN_RATIO_64), - RngSupport.mixStafford13(seed += RngSupport.GOLDEN_RATIO_64), - RngSupport.mixStafford13(seed += RngSupport.GOLDEN_RATIO_64), - RngSupport.mixStafford13(seed += RngSupport.GOLDEN_RATIO_64), - RngSupport.mixStafford13(seed += RngSupport.GOLDEN_RATIO_64), - RngSupport.mixStafford13(seed += RngSupport.GOLDEN_RATIO_64), - RngSupport.mixStafford13(seed += RngSupport.GOLDEN_RATIO_64), - 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 `x[0]`, + // 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), + 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), + RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64), + RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64), + RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64), + RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64), + RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64), + RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64), + RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64), + RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64), + RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64), + 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 L64X1024MixRandom} that is likely to + * Creates a new instance of {@link L64X1024MixRandom} 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 L64X1024MixRandom() { - // 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 L64X1024MixRandom} using the specified array of - * initial seed bytes. Instances of {@code L64X1024MixRandom} created with the same + * Creates a new instance of {@link L64X1024MixRandom} using the specified array of + * initial seed bytes. Instances of {@link L64X1024MixRandom} created with the same * seed array in the same program execution generate identical sequences of values. * * @param seed the initial seed */ public L64X1024MixRandom(byte[] seed) { - // Convert the seed to 18 long values, of which the last 16 are not all zero. - long[] data = RngSupport.convertSeedBytesToLongs(seed, 18, 16); - long a = data[0], s = data[1]; - // Force a to be odd. + // Convert the seed to 18 long values, of which the last 16 are not all zero. + long[] data = RNGSupport.convertSeedBytesToLongs(seed, 18, 16); + long a = data[0], s = data[1]; + // Force a to be odd. this.a = a | 1; this.s = s; - this.x = new long[N]; - for (int j = 0; j < N; j++) { - this.x[j] = data[2+j]; - } + this.x = new long[N]; + for (int j = 0; j < N; j++) { + this.x[j] = data[2+j]; + } } /* ---------------- public methods ---------------- */ /** - * Constructs and returns a new instance of {@code L64X1024MixRandom} + * Constructs and returns a new instance of {@link L64X1024MixRandom} * 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 L64X1024MixRandom} object. Either or both of the two + * a single {@link L64X1024MixRandom} 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 L64X1024MixRandom} + * @return a new instance of {@link L64X1024MixRandom} */ - public L64X1024MixRandom split(SplittableRng source) { - // Literally pick a new instance "at random". - return new L64X1024MixRandom(source.nextLong(), source.nextLong(), - source.nextLong(), source.nextLong(), - source.nextLong(), source.nextLong(), - source.nextLong(), source.nextLong(), - source.nextLong(), source.nextLong(), - source.nextLong(), source.nextLong(), - source.nextLong(), source.nextLong(), - source.nextLong(), source.nextLong(), - source.nextLong(), source.nextLong()); + public L64X1024MixRandom split(SplittableRNG source) { + // Literally pick a new instance "at random". + return new L64X1024MixRandom(source.nextLong(), source.nextLong(), + source.nextLong(), source.nextLong(), + source.nextLong(), source.nextLong(), + source.nextLong(), source.nextLong(), + source.nextLong(), source.nextLong(), + source.nextLong(), source.nextLong(), + source.nextLong(), source.nextLong(), + source.nextLong(), source.nextLong(), + source.nextLong(), source.nextLong()); } /** @@ -374,23 +374,24 @@ * * @return a pseudorandom {@code long} value */ - public long nextLong() { - // First part of xoroshiro1024: fetch array data - final int q = p; - final long s0 = x[p = (p + 1) & (N - 1)]; - long s15 = x[q]; + // First part of xoroshiro1024: fetch array data + final int q = p; + final long s0 = x[p = (p + 1) & (N - 1)]; + long s15 = x[q]; - final long z = s + s0; - s = m * s + a; // LCG + final long z = s + s0; + s = M * s + a; // LCG - // Second part of xoroshiro1024: update array data - s15 ^= s0; - x[q] = Long.rotateLeft(s0, 25) ^ s15 ^ (s15 << 27); - x[p] = Long.rotateLeft(s15, 36); - - return RngSupport.mixLea64(z); // mixing function + // Second part of xoroshiro1024: update array data + s15 ^= s0; + x[q] = Long.rotateLeft(s0, 25) ^ s15 ^ (s15 << 27); + x[p] = Long.rotateLeft(s15, 36); + + return RNGSupport.mixLea64(z); // mixing function } - public BigInteger period() { return thePeriod; } + public BigInteger period() { + return PERIOD; + } }