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.27 by jsr166, Sun Sep 13 16:28:14 2015 UTC vs.
Revision 1.41 by jsr166, Sun Dec 2 23:06:16 2018 UTC

# Line 80 | Line 80 | import java.util.stream.StreamSupport;
80   * in security-sensitive applications. Additionally,
81   * default-constructed instances do not use a cryptographically random
82   * seed unless the {@linkplain System#getProperty system property}
83 < * {@code java.util.secureRandomSeed} is set to {@code true}.
83 > * {@systemProperty java.util.secureRandomSeed} is set to {@code true}.
84   *
85   * @author  Guy Steele
86   * @author  Doug Lea
# Line 219 | Line 219 | public final class SplittableRandom {
219          return seed += gamma;
220      }
221  
222 +    // IllegalArgumentException messages
223 +    static final String BAD_BOUND = "bound must be positive";
224 +    static final String BAD_RANGE = "bound must be greater than origin";
225 +    static final String BAD_SIZE  = "size must be non-negative";
226 +
227      /**
228       * The seed generator for default constructors.
229       */
230 <    private static final AtomicLong defaultGen = new AtomicLong(initialSeed());
231 <
232 <    private static long initialSeed() {
233 <        String pp = java.security.AccessController.doPrivileged(
234 <                new sun.security.action.GetPropertyAction(
235 <                        "java.util.secureRandomSeed"));
236 <        if (pp != null && pp.equalsIgnoreCase("true")) {
230 >    private static final AtomicLong defaultGen
231 >        = new AtomicLong(mix64(System.currentTimeMillis()) ^
232 >                         mix64(System.nanoTime()));
233 >
234 >    // at end of <clinit> to survive static initialization circularity
235 >    static {
236 >        if (java.security.AccessController.doPrivileged(
237 >            new java.security.PrivilegedAction<Boolean>() {
238 >                public Boolean run() {
239 >                    return Boolean.getBoolean("java.util.secureRandomSeed");
240 >                }})) {
241              byte[] seedBytes = java.security.SecureRandom.getSeed(8);
242 <            long s = (long)(seedBytes[0]) & 0xffL;
242 >            long s = (long)seedBytes[0] & 0xffL;
243              for (int i = 1; i < 8; ++i)
244 <                s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
245 <            return s;
244 >                s = (s << 8) | ((long)seedBytes[i] & 0xffL);
245 >            defaultGen.set(s);
246          }
238        return (mix64(System.currentTimeMillis()) ^
239                mix64(System.nanoTime()));
247      }
248  
242    // IllegalArgumentException messages
243    static final String BadBound = "bound must be positive";
244    static final String BadRange = "bound must be greater than origin";
245    static final String BadSize  = "size must be non-negative";
246
249      /*
250       * Internal versions of nextX methods used by streams, as well as
251       * the public nextX(origin, bound) methods.  These exist mainly to
# Line 373 | Line 375 | public final class SplittableRandom {
375       * may, and typically does, vary across program invocations.
376       */
377      public SplittableRandom() { // emulate defaultGen.split()
378 <        long s = defaultGen.getAndAdd(2 * GOLDEN_GAMMA);
378 >        long s = defaultGen.getAndAdd(GOLDEN_GAMMA << 1);
379          this.seed = mix64(s);
380          this.gamma = mixGamma(s + GOLDEN_GAMMA);
381      }
# Line 397 | Line 399 | public final class SplittableRandom {
399      }
400  
401      /**
402 +     * Fills a user-supplied byte array with generated pseudorandom bytes.
403 +     *
404 +     * @param  bytes the byte array to fill with pseudorandom bytes
405 +     * @throws NullPointerException if bytes is null
406 +     * @since  10
407 +     */
408 +    public void nextBytes(byte[] bytes) {
409 +        int i = 0;
410 +        int len = bytes.length;
411 +        for (int words = len >> 3; words--> 0; ) {
412 +            long rnd = nextLong();
413 +            for (int n = 8; n--> 0; rnd >>>= Byte.SIZE)
414 +                bytes[i++] = (byte)rnd;
415 +        }
416 +        if (i < len)
417 +            for (long rnd = nextLong(); i < len; rnd >>>= Byte.SIZE)
418 +                bytes[i++] = (byte)rnd;
419 +    }
420 +
421 +    /**
422       * Returns a pseudorandom {@code int} value.
423       *
424       * @return a pseudorandom {@code int} value
# Line 416 | Line 438 | public final class SplittableRandom {
438       */
439      public int nextInt(int bound) {
440          if (bound <= 0)
441 <            throw new IllegalArgumentException(BadBound);
441 >            throw new IllegalArgumentException(BAD_BOUND);
442          // Specialize internalNextInt for origin 0
443          int r = mix32(nextSeed());
444          int m = bound - 1;
# Line 444 | Line 466 | public final class SplittableRandom {
466       */
467      public int nextInt(int origin, int bound) {
468          if (origin >= bound)
469 <            throw new IllegalArgumentException(BadRange);
469 >            throw new IllegalArgumentException(BAD_RANGE);
470          return internalNextInt(origin, bound);
471      }
472  
# Line 468 | Line 490 | public final class SplittableRandom {
490       */
491      public long nextLong(long bound) {
492          if (bound <= 0)
493 <            throw new IllegalArgumentException(BadBound);
493 >            throw new IllegalArgumentException(BAD_BOUND);
494          // Specialize internalNextLong for origin 0
495          long r = mix64(nextSeed());
496          long m = bound - 1;
# Line 496 | Line 518 | public final class SplittableRandom {
518       */
519      public long nextLong(long origin, long bound) {
520          if (origin >= bound)
521 <            throw new IllegalArgumentException(BadRange);
521 >            throw new IllegalArgumentException(BAD_RANGE);
522          return internalNextLong(origin, bound);
523      }
524  
# Line 522 | Line 544 | public final class SplittableRandom {
544       */
545      public double nextDouble(double bound) {
546          if (!(bound > 0.0))
547 <            throw new IllegalArgumentException(BadBound);
547 >            throw new IllegalArgumentException(BAD_BOUND);
548          double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound;
549          return (result < bound) ?  result : // correct for rounding
550              Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
# Line 541 | Line 563 | public final class SplittableRandom {
563       */
564      public double nextDouble(double origin, double bound) {
565          if (!(origin < bound))
566 <            throw new IllegalArgumentException(BadRange);
566 >            throw new IllegalArgumentException(BAD_RANGE);
567          return internalNextDouble(origin, bound);
568      }
569  
# Line 569 | Line 591 | public final class SplittableRandom {
591       */
592      public IntStream ints(long streamSize) {
593          if (streamSize < 0L)
594 <            throw new IllegalArgumentException(BadSize);
594 >            throw new IllegalArgumentException(BAD_SIZE);
595          return StreamSupport.intStream
596              (new RandomIntsSpliterator
597               (this, 0L, streamSize, Integer.MAX_VALUE, 0),
# Line 610 | Line 632 | public final class SplittableRandom {
632      public IntStream ints(long streamSize, int randomNumberOrigin,
633                            int randomNumberBound) {
634          if (streamSize < 0L)
635 <            throw new IllegalArgumentException(BadSize);
635 >            throw new IllegalArgumentException(BAD_SIZE);
636          if (randomNumberOrigin >= randomNumberBound)
637 <            throw new IllegalArgumentException(BadRange);
637 >            throw new IllegalArgumentException(BAD_RANGE);
638          return StreamSupport.intStream
639              (new RandomIntsSpliterator
640               (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
# Line 636 | Line 658 | public final class SplittableRandom {
658       */
659      public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
660          if (randomNumberOrigin >= randomNumberBound)
661 <            throw new IllegalArgumentException(BadRange);
661 >            throw new IllegalArgumentException(BAD_RANGE);
662          return StreamSupport.intStream
663              (new RandomIntsSpliterator
664               (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
# Line 655 | Line 677 | public final class SplittableRandom {
677       */
678      public LongStream longs(long streamSize) {
679          if (streamSize < 0L)
680 <            throw new IllegalArgumentException(BadSize);
680 >            throw new IllegalArgumentException(BAD_SIZE);
681          return StreamSupport.longStream
682              (new RandomLongsSpliterator
683               (this, 0L, streamSize, Long.MAX_VALUE, 0L),
# Line 696 | Line 718 | public final class SplittableRandom {
718      public LongStream longs(long streamSize, long randomNumberOrigin,
719                              long randomNumberBound) {
720          if (streamSize < 0L)
721 <            throw new IllegalArgumentException(BadSize);
721 >            throw new IllegalArgumentException(BAD_SIZE);
722          if (randomNumberOrigin >= randomNumberBound)
723 <            throw new IllegalArgumentException(BadRange);
723 >            throw new IllegalArgumentException(BAD_RANGE);
724          return StreamSupport.longStream
725              (new RandomLongsSpliterator
726               (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
# Line 722 | Line 744 | public final class SplittableRandom {
744       */
745      public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
746          if (randomNumberOrigin >= randomNumberBound)
747 <            throw new IllegalArgumentException(BadRange);
747 >            throw new IllegalArgumentException(BAD_RANGE);
748          return StreamSupport.longStream
749              (new RandomLongsSpliterator
750               (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
# Line 741 | Line 763 | public final class SplittableRandom {
763       */
764      public DoubleStream doubles(long streamSize) {
765          if (streamSize < 0L)
766 <            throw new IllegalArgumentException(BadSize);
766 >            throw new IllegalArgumentException(BAD_SIZE);
767          return StreamSupport.doubleStream
768              (new RandomDoublesSpliterator
769               (this, 0L, streamSize, Double.MAX_VALUE, 0.0),
# Line 777 | Line 799 | public final class SplittableRandom {
799       * @return a stream of pseudorandom {@code double} values,
800       *         each with the given origin (inclusive) and bound (exclusive)
801       * @throws IllegalArgumentException if {@code streamSize} is
802 <     *         less than zero
781 <     * @throws IllegalArgumentException if {@code randomNumberOrigin}
802 >     *         less than zero, or {@code randomNumberOrigin}
803       *         is greater than or equal to {@code randomNumberBound}
804       */
805      public DoubleStream doubles(long streamSize, double randomNumberOrigin,
806                                  double randomNumberBound) {
807          if (streamSize < 0L)
808 <            throw new IllegalArgumentException(BadSize);
808 >            throw new IllegalArgumentException(BAD_SIZE);
809          if (!(randomNumberOrigin < randomNumberBound))
810 <            throw new IllegalArgumentException(BadRange);
810 >            throw new IllegalArgumentException(BAD_RANGE);
811          return StreamSupport.doubleStream
812              (new RandomDoublesSpliterator
813               (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
# Line 810 | Line 831 | public final class SplittableRandom {
831       */
832      public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
833          if (!(randomNumberOrigin < randomNumberBound))
834 <            throw new IllegalArgumentException(BadRange);
834 >            throw new IllegalArgumentException(BAD_RANGE);
835          return StreamSupport.doubleStream
836              (new RandomDoublesSpliterator
837               (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
# Line 825 | Line 846 | public final class SplittableRandom {
846       * approach. The long and double versions of this class are
847       * identical except for types.
848       */
849 <    static final class RandomIntsSpliterator implements Spliterator.OfInt {
849 >    private static final class RandomIntsSpliterator
850 >            implements Spliterator.OfInt {
851          final SplittableRandom rng;
852          long index;
853          final long fence;
# Line 880 | Line 902 | public final class SplittableRandom {
902      /**
903       * Spliterator for long streams.
904       */
905 <    static final class RandomLongsSpliterator implements Spliterator.OfLong {
905 >    private static final class RandomLongsSpliterator
906 >            implements Spliterator.OfLong {
907          final SplittableRandom rng;
908          long index;
909          final long fence;
# Line 936 | Line 959 | public final class SplittableRandom {
959      /**
960       * Spliterator for double streams.
961       */
962 <    static final class RandomDoublesSpliterator implements Spliterator.OfDouble {
962 >    private static final class RandomDoublesSpliterator
963 >            implements Spliterator.OfDouble {
964          final SplittableRandom rng;
965          long index;
966          final long fence;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines