ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/SplittableRandom.java
(Generate patch)

Comparing jsr166/src/main/java/util/SplittableRandom.java (file contents):
Revision 1.11 by dl, Tue Jul 16 12:32:05 2013 UTC vs.
Revision 1.12 by dl, Sun Jul 21 14:02:23 2013 UTC

# Line 25 | Line 25
25  
26   package java.util;
27  
28 + import java.security.SecureRandom;
29   import java.util.concurrent.atomic.AtomicLong;
30   import java.util.Spliterator;
31   import java.util.function.IntConsumer;
# Line 121 | Line 122 | public class SplittableRandom {
122       * this generator as nextSplit, and uses mix64(nextSplit) as its
123       * own gamma value. Computations of gammas themselves use a fixed
124       * constant as the second argument to the addGammaModGeorge
125 <     * function, GAMMA_GAMMA, a "genuinely random" number from a
126 <     * radioactive decay reading (obtained from
127 <     * http://www.fourmilab.ch/hotbits/) meeting the above range
128 <     * constraint. Using a fixed constant maintains the invariant that
128 <     * the value of gamma is the same for every instance that is at
129 <     * the same split-distance from their common root. (Note: there is
130 <     * nothing especially magic about obtaining this constant from a
131 <     * "truly random" physical source rather than just choosing one
132 <     * arbitrarily; using "hotbits" was merely an aesthetically pleasing
133 <     * choice.  In either case, good statistical behavior of the
134 <     * algorithm should be, and was, verified by using the DieHarder
135 <     * test suite.)
125 >     * function, GAMMA_GAMMA. The value of GAMMA_GAMMA is arbitrary
126 >     * (except must be at least 13), but because it serves as the base
127 >     * of split sequences, should be subject to validation of
128 >     * consequent random number quality metrics.
129       *
130       * The mix64 bit-mixing function called by nextLong and other
131       * methods computes the same value as the "64-bit finalizer"
# Line 158 | Line 151 | public class SplittableRandom {
151       * SplittableRandom. Unlike other cases, this split must be
152       * performed in a thread-safe manner. We use
153       * AtomicLong.compareAndSet as the (typically) most efficient
154 <     * mechanism. To bootstrap, we start off using a function of the
155 <     * current System time as seed, and update using another
156 <     * "genuinely random" constant DEFAULT_SEED_GAMMA. The default
157 <     * constructor uses GAMMA_GAMMA, not 0, for its splitSeed argument
158 <     * (addGammaModGeorge(0, GAMMA_GAMMA) == GAMMA_GAMMA) to reflect
159 <     * that each is split from this root generator, even though the
160 <     * root is not explicitly represented as a SplittableRandom.  When
168 <     * establishing the initial seed, we use both
169 <     * System.currentTimeMillis and System.nanoTime(), to avoid
170 <     * regularities that may occur if using either alone.
154 >     * mechanism. To bootstrap, we start off using a SecureRandom
155 >     * initial default seed, and update using a fixed
156 >     * DEFAULT_SEED_GAMMA. The default constructor uses GAMMA_GAMMA,
157 >     * not 0, for its splitSeed argument (addGammaModGeorge(0,
158 >     * GAMMA_GAMMA) == GAMMA_GAMMA) to reflect that each is split from
159 >     * this root generator, even though the root is not explicitly
160 >     * represented as a SplittableRandom.
161       */
162  
163      /**
164 <     * The "genuinely random" value for producing new gamma values.
165 <     * The value is arbitrary, subject to the requirement that it be
166 <     * greater or equal to 13.
164 >     * The value for producing new gamma values. Must be greater or
165 >     * equal to 13. Otherwise, the value is arbitrary subject to
166 >     * validation of the resulting statistical quality of splits.
167       */
168      private static final long GAMMA_GAMMA = 0xF2281E2DBA6606F3L;
169  
170      /**
171 <     * The "genuinely random" seed update value for default constructors.
172 <     * The value is arbitrary, subject to the requirement that it be
183 <     * greater or equal to 13.
171 >     * The seed update value for default constructors.  Must be
172 >     * greater or equal to 13. Otherwise, the value is arbitrary.
173       */
174      private static final long DEFAULT_SEED_GAMMA = 0xBD24B73A95FB84D9L;
175  
# Line 200 | Line 189 | public class SplittableRandom {
189       * The next seed for default constructors.
190       */
191      private static final AtomicLong defaultSeedGenerator =
192 <        new AtomicLong(mix64(System.currentTimeMillis()) ^
204 <                       mix64(System.nanoTime()));
192 >        new AtomicLong(getInitialDefaultSeed());
193  
194      /**
195       * The seed, updated only via method nextSeed.
# Line 302 | Line 290 | public class SplittableRandom {
290          return mix64(newSeed);
291      }
292  
293 +    /**
294 +     * Returns an initial default seed.
295 +     */
296 +    private static long getInitialDefaultSeed() {
297 +        byte[] seedBytes = java.security.SecureRandom.getSeed(8);
298 +        long s = (long)(seedBytes[0]) & 0xffL;
299 +        for (int i = 1; i < 8; ++i)
300 +            s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
301 +        return s;
302 +    }
303 +
304      /*
305       * Internal versions of nextX methods used by streams, as well as
306       * the public nextX(origin, bound) methods.  These exist mainly to

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines