newrandom/SplittableRng.java
branchbriangoetz-test-branch
changeset 57369 6d87e9f7a1ec
equal deleted inserted replaced
57366:c646b256fbcc 57369:6d87e9f7a1ec
       
     1 /*
       
     2  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
       
     3  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
       
     4  *
       
     5  *
       
     6  *
       
     7  *
       
     8  *
       
     9  *
       
    10  *
       
    11  *
       
    12  *
       
    13  *
       
    14  *
       
    15  *
       
    16  *
       
    17  *
       
    18  *
       
    19  *
       
    20  *
       
    21  *
       
    22  *
       
    23  *
       
    24  */
       
    25 // package java.util;
       
    26 
       
    27 import java.util.stream.Stream;
       
    28 import java.util.stream.StreamSupport;
       
    29 import java.util.stream.IntStream;
       
    30 import java.util.stream.LongStream;
       
    31 import java.util.stream.DoubleStream;
       
    32 
       
    33 /**
       
    34  * This interface is designed to provide a common protocol for objects
       
    35  * that generate sequences of pseudorandom numbers (or Boolean values)
       
    36  * and furthermore can be <it>split</it> into two objects (the original
       
    37  * one and a new one) each of which obey that same protocol (and therefore
       
    38  * can be recursively split indefinitely).
       
    39  *
       
    40  * <p>Ideally, all {@code SplittableRNG} objects produced by recursive
       
    41  * splitting from a single original {@code SplittableRNG} object are
       
    42  * statistically independent of one another and individually uniform.
       
    43  * Therefore we would expect the set of values collectively generated
       
    44  * by a set of such objects to have the same statistical properties as
       
    45  * if the same quantity of values were generated by a single thread
       
    46  * using a single {@code SplittableRNG} object.  In practice, one must
       
    47  * settle for some approximation to independence and uniformity.
       
    48  *
       
    49  * <p>Methods are provided to perform a single splitting operation and
       
    50  * also to produce a stream of generators split off from the original
       
    51  * (by either iterative or recursive splitting, or a combination).
       
    52  *
       
    53  * <p>An implementation of the {@code SplittableRng} interface must provide
       
    54  * concrete definitions for the methods {@code nextInt()}, {@code nextLong},
       
    55  * {@code period()}, {@code split()}, {@code split(SplittableRng)},
       
    56  * {@code splits()}, {@code splits(long)}, {@code splits(SplittableRng)},
       
    57  * and {@code splits(long, SplittableRng)}.  Perhaps the most convenient
       
    58  * way to implement this interface is to extend the abstract class
       
    59  * {@link java.util.AbstractSplittableRng}.
       
    60  *
       
    61  * <p>Objects that implement {@code java.util.SplittableRNG} are
       
    62  * typically not cryptographically secure.  Consider instead using
       
    63  * {@link java.security.SecureRandom} to get a cryptographically
       
    64  * secure pseudo-random number generator for use by
       
    65  * security-sensitive applications.
       
    66  *
       
    67  * @author  Guy Steele
       
    68  * @since   1.9
       
    69  */
       
    70 interface SplittableRng extends StreamableRng {
       
    71 
       
    72     /**
       
    73      * Returns a new pseudorandom number generator, split off from
       
    74      * this one, that implements the {@code Rng} and {@code SplittableRng}
       
    75      * interfaces.
       
    76      *
       
    77      * This pseudorandom number generator may be used as a source of
       
    78      * pseudorandom bits used to initialize the state the new one.
       
    79      *
       
    80      * @return a new object that implements the {@code Rng} and
       
    81      *         {@code SplittableRng} interfaces
       
    82      */
       
    83     SplittableRng split();
       
    84 
       
    85     /**
       
    86      * Returns a new pseudorandom number generator, split off from
       
    87      * this one, that implements the {@code Rng} and {@code SplittableRng}
       
    88      * interfaces.
       
    89      *
       
    90      * @param source a {@code SplittableRng} instance to be used instead
       
    91      *               of this one as a source of pseudorandom bits used to
       
    92      *               initialize the state of the new ones.
       
    93      *
       
    94      * @return an object that implements the {@code Rng} and
       
    95      *         {@code SplittableRng} interfaces
       
    96      */
       
    97     SplittableRng split(SplittableRng source);
       
    98 
       
    99     /**
       
   100      * Returns an effectively unlimited stream of new pseudorandom
       
   101      * number generators, each of which implements the {@code SplittableRng}
       
   102      * interface.
       
   103      *
       
   104      * This pseudorandom number generator may be used as a source of
       
   105      * pseudorandom bits used to initialize the state the new ones.
       
   106      *
       
   107      * @implNote It is permitted to implement this method in a manner
       
   108      * equivalent to {@code splits(Long.MAX_VALUE)}.
       
   109      *
       
   110      * @return a stream of {@code SplittableRng} objects
       
   111      */
       
   112     default Stream<SplittableRng> splits() {
       
   113 	return this.splits(this);
       
   114     }
       
   115 
       
   116     /**
       
   117      * Returns a stream producing the given {@code streamSize} number of
       
   118      * new pseudorandom number generators, each of which implements the
       
   119      * {@code SplittableRng} interface.
       
   120      *
       
   121      * This pseudorandom number generator may be used as a source of
       
   122      * pseudorandom bits used to initialize the state the new ones.
       
   123      *
       
   124      * @param streamSize the number of values to generate
       
   125      * @return a stream of {@code SplittableRng} objects
       
   126      * @throws IllegalArgumentException if {@code streamSize} is
       
   127      *         less than zero
       
   128      */
       
   129     Stream<SplittableRng> splits(long streamSize);
       
   130 
       
   131     /**
       
   132      * Returns an effectively unlimited stream of new pseudorandom
       
   133      * number generators, each of which implements the {@code SplittableRng}
       
   134      * interface.
       
   135      *
       
   136      * @implNote It is permitted to implement this method in a manner
       
   137      * equivalent to {@code splits(Long.MAX_VALUE, source)}.
       
   138      *
       
   139      * @param source a {@code SplittableRng} instance to be used instead
       
   140      *               of this one as a source of pseudorandom bits used to
       
   141      *               initialize the state of the new ones.
       
   142      *
       
   143      * @return a stream of {@code SplittableRng} objects
       
   144      */
       
   145     Stream<SplittableRng> splits(SplittableRng source);
       
   146 
       
   147     /**
       
   148      * Returns a stream producing the given {@code streamSize} number of
       
   149      * new pseudorandom number generators, each of which implements the
       
   150      * {@code SplittableRng} interface.
       
   151      *
       
   152      * @param streamSize the number of values to generate
       
   153      * @param source a {@code SplittableRng} instance to be used instead
       
   154      *               of this one as a source of pseudorandom bits used to
       
   155      *               initialize the state of the new ones.
       
   156      * @return a stream of {@code SplittableRng} objects
       
   157      * @throws IllegalArgumentException if {@code streamSize} is
       
   158      *         less than zero
       
   159      */
       
   160     Stream<SplittableRng> splits(long streamSize, SplittableRng source);
       
   161 
       
   162     /**
       
   163      * Returns an effectively unlimited stream of new pseudorandom
       
   164      * number generators, each of which implements the {@code Rng}
       
   165      * interface.  Ideally the generators in the stream will appear
       
   166      * to be statistically independent.
       
   167      *
       
   168      * @implNote The default implementation calls {@code splits()}.
       
   169      *
       
   170      * @return a stream of objects that implement the {@code Rng} interface
       
   171      */
       
   172     default Stream<Rng> rngs() {
       
   173 	return this.splits().map(x -> (Rng)x);
       
   174     }
       
   175 
       
   176     /**
       
   177      * Returns a stream producing the given {@code streamSize} number of
       
   178      * new pseudorandom number generators, each of which implements the
       
   179      * {@code Rng} interface.  Ideally the generators in the stream will
       
   180      * appear to be statistically independent.
       
   181      *
       
   182      * @implNote The default implementation calls {@code splits(streamSize)}.
       
   183      *
       
   184      * @param streamSize the number of generators to generate
       
   185      * @return a stream of objects that implement the {@code Rng} interface
       
   186      * @throws IllegalArgumentException if {@code streamSize} is
       
   187      *         less than zero
       
   188      */
       
   189     default Stream<Rng> rngs(long streamSize) {
       
   190 	return this.splits(streamSize).map(x -> (Rng)x);
       
   191     }
       
   192 }