src/java.base/share/classes/java/util/random/RandomSupport.java
branchJDK-8193209-branch
changeset 59080 1b314be4feb2
parent 57684 7cb325557832
equal deleted inserted replaced
57940:7e791393cc4d 59080:1b314be4feb2
    49 
    49 
    50     /*
    50     /*
    51      * Implementation Overview.
    51      * Implementation Overview.
    52      *
    52      *
    53      * This class provides utility methods and constants frequently
    53      * This class provides utility methods and constants frequently
    54      * useful in the implentation of pseudorandom number generators
    54      * useful in the implementation of pseudorandom number generators
    55      * that satisfy the interface {@link RandomGenerator}.
    55      * that satisfy the interface {@link RandomGenerator}.
    56      *
    56      *
    57      * File organization: First some message strings, then the main
    57      * File organization: First some message strings, then the main
    58      * public methods, followed by a non-public base spliterator class.
    58      * public methods, followed by a non-public base spliterator class.
    59      */
    59      */
    82     /**
    82     /**
    83      * Check a {@code double} proposed jump distance for validity.
    83      * Check a {@code double} proposed jump distance for validity.
    84      *
    84      *
    85      * @param distance the proposed jump distance
    85      * @param distance the proposed jump distance
    86      *
    86      *
    87      * @throws IllegalArgumentException if {@code size} not positive, finite, and an exact integer
    87      * @throws IllegalArgumentException if {@code size} fails to be positive, finite, and an exact integer
    88      */
    88      */
    89     public static void checkJumpDistance(double distance) {
    89     public static void checkJumpDistance(double distance) {
    90         if (!(distance > 0.0 && distance < Float.POSITIVE_INFINITY
    90         if (!(distance > 0.0 && distance < Float.POSITIVE_INFINITY
    91                              && distance == Math.floor(distance))) {
    91                              && distance == Math.floor(distance))) {
    92             throw new IllegalArgumentException(BAD_DISTANCE);
    92             throw new IllegalArgumentException(BAD_DISTANCE);
    96     /**
    96     /**
    97      * Checks a {@code float} upper bound value for validity.
    97      * Checks a {@code float} upper bound value for validity.
    98      *
    98      *
    99      * @param bound the upper bound (exclusive)
    99      * @param bound the upper bound (exclusive)
   100      *
   100      *
   101      * @throws IllegalArgumentException if {@code bound} is not positive and finite
   101      * @throws IllegalArgumentException if {@code bound} fails to be positive and finite
   102      */
   102      */
   103     public static void checkBound(float bound) {
   103     public static void checkBound(float bound) {
   104         if (!(bound > 0.0 && bound < Float.POSITIVE_INFINITY)) {
   104         if (!(bound > 0.0 && bound < Float.POSITIVE_INFINITY)) {
   105             throw new IllegalArgumentException(BAD_FLOATING_BOUND);
   105             throw new IllegalArgumentException(BAD_FLOATING_BOUND);
   106         }
   106         }
   109     /**
   109     /**
   110      * Checks a {@code double} upper bound value for validity.
   110      * Checks a {@code double} upper bound value for validity.
   111      *
   111      *
   112      * @param bound the upper bound (exclusive)
   112      * @param bound the upper bound (exclusive)
   113      *
   113      *
   114      * @throws IllegalArgumentException if {@code bound} is not positive and finite
   114      * @throws IllegalArgumentException if {@code bound} fails to be positive and finite
   115      */
   115      */
   116     public static void checkBound(double bound) {
   116     public static void checkBound(double bound) {
   117         if (!(bound > 0.0 && bound < Double.POSITIVE_INFINITY)) {
   117         if (!(bound > 0.0 && bound < Double.POSITIVE_INFINITY)) {
   118             throw new IllegalArgumentException(BAD_FLOATING_BOUND);
   118             throw new IllegalArgumentException(BAD_FLOATING_BOUND);
   119         }
   119         }
   149      * Checks a {@code float} range for validity.
   149      * Checks a {@code float} range for validity.
   150      *
   150      *
   151      * @param origin the least value (inclusive) in the range
   151      * @param origin the least value (inclusive) in the range
   152      * @param bound  the upper bound (exclusive) of the range
   152      * @param bound  the upper bound (exclusive) of the range
   153      *
   153      *
   154      * @throws IllegalArgumentException unless {@code origin} is finite, {@code bound} is finite,
   154      * @throws IllegalArgumentException if {@code origin} is not finite, {@code bound} is not finite,
   155      *                                  and {@code bound - origin} is finite
   155      *                                  or {@code bound - origin} is not finite
   156      */
   156      */
   157     public static void checkRange(float origin, float bound) {
   157     public static void checkRange(float origin, float bound) {
   158         if (!(origin < bound && (bound - origin) < Float.POSITIVE_INFINITY)) {
   158         if (!(origin < bound && (bound - origin) < Float.POSITIVE_INFINITY)) {
   159             throw new IllegalArgumentException(BAD_RANGE);
   159             throw new IllegalArgumentException(BAD_RANGE);
   160         }
   160         }
   164      * Checks a {@code double} range for validity.
   164      * Checks a {@code double} range for validity.
   165      *
   165      *
   166      * @param origin the least value (inclusive) in the range
   166      * @param origin the least value (inclusive) in the range
   167      * @param bound  the upper bound (exclusive) of the range
   167      * @param bound  the upper bound (exclusive) of the range
   168      *
   168      *
   169      * @throws IllegalArgumentException unless {@code origin} is finite, {@code bound} is finite,
   169      * @throws IllegalArgumentException if {@code origin} is not finite, {@code bound} is not finite,
   170      *                                  and {@code bound - origin} is finite
   170      *                                  or {@code bound - origin} is not finite
   171      */
   171      */
   172     public static void checkRange(double origin, double bound) {
   172     public static void checkRange(double origin, double bound) {
   173         if (!(origin < bound && (bound - origin) < Double.POSITIVE_INFINITY)) {
   173         if (!(origin < bound && (bound - origin) < Double.POSITIVE_INFINITY)) {
   174             throw new IllegalArgumentException(BAD_RANGE);
   174             throw new IllegalArgumentException(BAD_RANGE);
   175         }
   175         }
  1139          * File organization: First the non-public abstract methods needed
  1139          * File organization: First the non-public abstract methods needed
  1140          * to create spliterators, then the main public methods.
  1140          * to create spliterators, then the main public methods.
  1141          */
  1141          */
  1142 
  1142 
  1143         /**
  1143         /**
  1144          * Needs comment (was made public to be overridden out of package.)
  1144          * Create an instance of {@link Spliterator.OfInt} that for each traversal position
  1145          *
  1145 	 * between the specified index (inclusive) and the specified fence (exclusive) generates
  1146          * @param index low
  1146 	 * a pseudorandomly chosen {@code int} value between the specified origin (inclusive) and
  1147          * @param fence high
  1147 	 * the specified bound (exclusive).
  1148          * @param origin low
  1148          *
  1149          * @param bound high
  1149          * @param index the (inclusive) lower bound on traversal positions
  1150          * @return result
  1150          * @param fence the (exclusive) upper bound on traversal positions
       
  1151          * @param origin the (inclusive) lower bound on the pseudorandom values to be generated
       
  1152          * @param bound the (exclusive) upper bound on the pseudorandom values to be generated
       
  1153          * @return an instance of {@link Spliterator.OfInt}
  1151          */
  1154          */
  1152         public abstract Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound);
  1155         public abstract Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound);
  1153 
  1156 
  1154         /**
  1157         /**
  1155          * Needs comment (was made public to be overridden out of package.)
  1158          * Create an instance of {@link Spliterator.OfLong} that for each traversal position
  1156          *
  1159 	 * between the specified index (inclusive) and the specified fence (exclusive) generates
  1157          * @param index low
  1160 	 * a pseudorandomly chosen {@code long} value between the specified origin (inclusive) and
  1158          * @param fence high
  1161 	 * the specified bound (exclusive).
  1159          * @param origin low
  1162          *
  1160          * @param bound high
  1163          * @param index the (inclusive) lower bound on traversal positions
  1161          * @return result
  1164          * @param fence the (exclusive) upper bound on traversal positions
       
  1165          * @param origin the (inclusive) lower bound on the pseudorandom values to be generated
       
  1166          * @param bound the (exclusive) upper bound on the pseudorandom values to be generated
       
  1167          * @return an instance of {@link Spliterator.OfLong}
  1162          */
  1168          */
  1163         public abstract Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound);
  1169         public abstract Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound);
  1164 
  1170 
  1165         /**
  1171         /**
  1166          * Needs comment (was made public to be overridden out of package.)
  1172          * Create an instance of {@link Spliterator.OfDouble} that for each traversal position
  1167          *
  1173 	 * between the specified index (inclusive) and the specified fence (exclusive) generates
  1168          * @param index low
  1174 	 * a pseudorandomly chosen {@code double} value between the specified origin (inclusive) and
  1169          * @param fence high
  1175 	 * the specified bound (exclusive).
  1170          * @param origin low
  1176          *
  1171          * @param bound high
  1177          * @param index the (inclusive) lower bound on traversal positions
  1172          * @return result
  1178          * @param fence the (exclusive) upper bound on traversal positions
       
  1179          * @param origin the (inclusive) lower bound on the pseudorandom values to be generated
       
  1180          * @param bound the (exclusive) upper bound on the pseudorandom values to be generated
       
  1181          * @return an instance of {@link Spliterator.OfDouble}
  1173          */
  1182          */
  1174         public abstract Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound);
  1183         public abstract Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound);
  1175 
  1184 
  1176         /* ---------------- public methods ---------------- */
  1185         /* ---------------- public methods ---------------- */
  1177 
  1186 
  1920      * <p>
  1929      * <p>
  1921      * To implement a pseudorandom number generator, the programmer needs only to extend this class and
  1930      * To implement a pseudorandom number generator, the programmer needs only to extend this class and
  1922      * provide implementations for the methods {@code nextInt()}, {@code nextLong()}, {@code period()},
  1931      * provide implementations for the methods {@code nextInt()}, {@code nextLong()}, {@code period()},
  1923      * and {@code split(SplittableGenerator)}.
  1932      * and {@code split(SplittableGenerator)}.
  1924      * <p>
  1933      * <p>
  1925      * (If the pseudorandom number generator also has the ability to jump, then the programmer may wish
  1934      * (If the pseudorandom number generator also has the ability to jump an arbitrary
  1926      * to consider instead extending the class {@link ArbitrarilyJumpableGenerator}.  But if the pseudorandom
  1935      * specified distance, then the programmer may wish to consider instead extending the
  1927      * number generator furthermore has the ability to jump an arbitrary specified distance, then the
  1936      * class {@link AbstractArbitrarilyJumpableGenerator}.  See also the class
  1928      * programmer may wish to consider instead extending the class {@link
  1937      * {@link AbstractSplittableWithBrineGenerator}.)
  1929      * AbstractArbitrarilyJumpableGenerator}.)
       
  1930      * <p>
  1938      * <p>
  1931      * The programmer should generally provide at least three constructors: one that takes no arguments,
  1939      * The programmer should generally provide at least three constructors: one that takes no arguments,
  1932      * one that accepts a {@code long} seed value, and one that accepts an array of seed {@code byte}
  1940      * one that accepts a {@code long} seed value, and one that accepts an array of seed {@code byte}
  1933      * values. This class provides a public {@code initialSeed()} method that may be useful in
  1941      * values. This class provides a public {@code initialSeed()} method that may be useful in
  1934      * initializing some static state from which to derive defaults seeds for use by the no-argument
  1942      * initializing some static state from which to derive defaults seeds for use by the no-argument
  1935      * constructor.
  1943      * constructor.
  1936      * <p>
  1944      * <p>
  1937      * For the stream methods (such as {@code ints()} and {@code splits()}), this class provides {@link
  1945      * For the stream methods (such as {@code ints()} and {@code splits()}), this class provides
  1938      * Spliterator} based implementations that allow parallel execution when appropriate.
  1946      * {@link Spliterator}-based implementations that allow parallel execution when appropriate.
  1939      * <p>
  1947      * <p>
  1940      * The documentation for each non-abstract method in this class describes its implementation in
  1948      * The documentation for each non-abstract method in this class describes its implementation in
  1941      * detail. Each of these methods may be overridden if the pseudorandom number generator being
  1949      * detail. Each of these methods may be overridden if the pseudorandom number generator being
  1942      * implemented admits a more efficient implementation.
  1950      * implemented admits a more efficient implementation.
  1943      *
  1951      *
  1947 
  1955 
  1948         /*
  1956         /*
  1949          * Implementation Overview.
  1957          * Implementation Overview.
  1950          *
  1958          *
  1951          * This class provides most of the "user API" methods needed to
  1959          * This class provides most of the "user API" methods needed to
  1952          * satisfy the interface JumpableGenerator.  Most of these methods
  1960          * satisfy the interface SplittableGenerator.  Most of these methods
  1953          * are in turn inherited from AbstractGenerator and the non-public class
  1961          * are in turn inherited from AbstractGenerator and the non-public class
  1954          * AbstractSpliteratorGenerator; this file implements two versions of the
  1962          * AbstractSpliteratorGenerator; this class provides two versions of the
  1955          * splits method and defines the spliterators necessary to support
  1963          * splits method and defines the spliterators necessary to support
  1956          * them.
  1964          * them.
  1957          *
       
  1958          * The abstract split() method from interface SplittableGenerator is redeclared
       
  1959          * here so as to narrow the return type to AbstractSplittableGenerator.
       
  1960          *
  1965          *
  1961          * File organization: First the non-public methods needed by the class
  1966          * File organization: First the non-public methods needed by the class
  1962          * AbstractSpliteratorGenerator, then the main public methods, followed by some
  1967          * AbstractSpliteratorGenerator, then the main public methods, followed by some
  1963          * custom spliterator classes.
  1968          * custom spliterator classes.
  1964          */
  1969          */
  1980         }
  1985         }
  1981 
  1986 
  1982         /* ---------------- public methods ---------------- */
  1987         /* ---------------- public methods ---------------- */
  1983 
  1988 
  1984         /**
  1989         /**
  1985          * Implements the @code{split()} method as {@code this.split(this) }.
  1990          * Implements the @code{split()} method as {@code this.split(this)}.
  1986          *
  1991          *
  1987          * @return the new {@link AbstractSplittableGenerator} instance
  1992          * @return the new {@link SplittableGenerator} instance
  1988          */
  1993          */
  1989         public SplittableGenerator split() {
  1994         public SplittableGenerator split() {
  1990             return this.split(this);
  1995             return this.split(this);
  1991         }
  1996         }
  1992 
  1997 
  2198         /**
  2203         /**
  2199          * Spliterator for stream of generators of type SplittableGenerator.  We multiplex the two
  2204          * Spliterator for stream of generators of type SplittableGenerator.  We multiplex the two
  2200          * versions into one class by treating "infinite" as equivalent to Long.MAX_VALUE.
  2205          * versions into one class by treating "infinite" as equivalent to Long.MAX_VALUE.
  2201          * For splits, it uses the standard divide-by-two approach.
  2206          * For splits, it uses the standard divide-by-two approach.
  2202          */
  2207          */
  2203         static class RandomSplitsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator<SplittableGenerator> {
  2208         static class RandomSplitsSpliterator extends RandomSpliterator implements Spliterator<SplittableGenerator> {
  2204             final SplittableGenerator generatingGenerator;
  2209             final SplittableGenerator generatingGenerator;
  2205             final SplittableGenerator constructingGenerator;
  2210             final SplittableGenerator constructingGenerator;
  2206 
  2211 
  2207             RandomSplitsSpliterator(SplittableGenerator generatingGenerator, long index, long fence, SplittableGenerator constructingGenerator) {
  2212             RandomSplitsSpliterator(SplittableGenerator generatingGenerator,
       
  2213 				    long index, long fence,
       
  2214 				    SplittableGenerator constructingGenerator) {
  2208                 super(index, fence);
  2215                 super(index, fence);
  2209                 this.generatingGenerator = generatingGenerator;
  2216                 this.generatingGenerator = generatingGenerator;
  2210                 this.constructingGenerator = constructingGenerator;
  2217                 this.constructingGenerator = constructingGenerator;
  2211             }
  2218             }
  2212 
  2219 
  2242             }
  2249             }
  2243         }
  2250         }
  2244 
  2251 
  2245     }
  2252     }
  2246 
  2253 
       
  2254     /**
       
  2255      * This class provides much of the implementation of the {@link SplittableGenerator} interface, to
       
  2256      * minimize the effort required to implement this interface.  It is similar to the class
       
  2257      * {@link AbstractSplittableGenerator} but makes use of the brine technique for ensuring that
       
  2258      * distinct generators created by a single call to a {@code splits} method have distinct state cycles.
       
  2259      * <p>
       
  2260      * To implement a pseudorandom number generator, the programmer needs only to extend this class and
       
  2261      * provide implementations for the methods {@code nextInt()}, {@code nextLong()}, {@code period()},
       
  2262      * and {@code split(SplittableGenerator, long)}.
       
  2263      * <p>
       
  2264      * The programmer should generally provide at least three constructors: one that takes no arguments,
       
  2265      * one that accepts a {@code long} seed value, and one that accepts an array of seed {@code byte}
       
  2266      * values. This class provides a public {@code initialSeed()} method that may be useful in
       
  2267      * initializing some static state from which to derive defaults seeds for use by the no-argument
       
  2268      * constructor.
       
  2269      * <p>
       
  2270      * For the stream methods (such as {@code ints()} and {@code splits()}), this class provides
       
  2271      * {@link Spliterator}-based implementations that allow parallel execution when appropriate.
       
  2272      * <p>
       
  2273      * The documentation for each non-abstract method in this class describes its implementation in
       
  2274      * detail. Each of these methods may be overridden if the pseudorandom number generator being
       
  2275      * implemented admits a more efficient implementation.
       
  2276      *
       
  2277      * @since 14
       
  2278      */
       
  2279     public abstract static class AbstractSplittableWithBrineGenerator
       
  2280 	extends AbstractSplittableGenerator {
       
  2281 
       
  2282 	/*
       
  2283 	 * Implementation Overview.
       
  2284 	 *
       
  2285          * This class provides most of the "user API" methods needed to
       
  2286          * satisfy the interface SplittableGenerator.  Most of these methods
       
  2287          * are in turn inherited from AbstractSplittableGenerator and the non-public class
       
  2288          * AbstractSpliteratorGenerator; this class provides four versions of the
       
  2289          * splits method and defines the spliterators necessary to support
       
  2290          * them.
       
  2291 	 *
       
  2292 	 * File organization: First the non-public methods needed by the class
       
  2293 	 * AbstractSplittableWithBrineGenerator, then the main public methods,
       
  2294 	 * followed by some custom spliterator classes needed for stream methods.
       
  2295 	 */
       
  2296 
       
  2297 	// The salt consists groups of bits each SALT_SHIFT in size, starting from
       
  2298 	// the left-hand (high-order) end of the word.  We can regard them as
       
  2299 	// digits base (1 << SALT_SHIFT).  If SALT_SHIFT does not divide 64
       
  2300 	// evenly, then any leftover bits at the low end of the word are zero.
       
  2301 	// The lowest digit of the salt is set to the largest possible digit
       
  2302 	// (all 1-bits, or ((1 << SALT_SHIFT) - 1)); all other digits are set
       
  2303 	// to a randomly chosen value less than that largest possible digit.
       
  2304 	// The salt may be shifted left by SALT_SHIFT any number of times.
       
  2305 	// If any salt remains in the word, its right-hand end can be identified
       
  2306 	// by searching from left to right for an occurrence of a digit that is
       
  2307 	// all 1-bits (not that we ever do that; this is simply a proof that one
       
  2308 	// can identify the boundary between the salt and the index if any salt
       
  2309 	// remains in the word).  The idea is that before computing the bitwise OR
       
  2310 	// of an index and the salt, one can first check to see whether the
       
  2311 	// bitwise AND is nonzero; if so, one can shift the salt left by
       
  2312 	// SALT_SHIFT and try again.  In this way, when the bitwise OR is
       
  2313 	// computed, if the salt is nonzero then its rightmost 1-bit is to the
       
  2314 	// left of the leftmost 1-bit of the index.
       
  2315 
       
  2316 	// We need 2 <= SALT_SHIFT <= 63 (3 through 8 are good values; 4 is probably best)
       
  2317 	static final int SALT_SHIFT = 4;
       
  2318 
       
  2319 	// Methods required by class AbstractSpliteratorGenerator (override)
       
  2320 	Spliterator<SplittableGenerator> makeSplitsSpliterator(long index, long fence, SplittableGenerator source) {
       
  2321 	    // This little algorithm to generate a new salt value is carefully
       
  2322 	    // designed to work even if SALT_SHIFT does not evenly divide 64
       
  2323 	    // (the number of bits in a long value).
       
  2324 	    long bits = nextLong();
       
  2325 	    long multiplier = (1 << SALT_SHIFT) - 1;
       
  2326 	    long salt = multiplier << (64 - SALT_SHIFT);
       
  2327 	    while ((salt & multiplier) != 0) {
       
  2328 		long digit = Math.multiplyHigh(bits, multiplier);
       
  2329 		salt = (salt >>> SALT_SHIFT) | (digit << (64 - SALT_SHIFT));
       
  2330 		bits *= multiplier;
       
  2331 	    }
       
  2332 	    // This is the point at which newly generated salt gets injected into
       
  2333 	    // the root of a newly created brine-generating splits-spliterator.
       
  2334 	    return new RandomSplitsSpliteratorWithSalt(source, index, fence, this, salt);
       
  2335 	}
       
  2336 
       
  2337 	/* ---------------- public methods ---------------- */
       
  2338 
       
  2339 	// Stream methods for splitting
       
  2340 
       
  2341 	/**
       
  2342 	 * Constructs and returns a new instance of {@code AbstractSplittableWithBrineGenerator}
       
  2343 	 * that shares no mutable state with this instance. However, with very high
       
  2344 	 * probability, the set of values collectively generated by the two objects
       
  2345 	 * should have the same statistical properties as if the same quantity of
       
  2346 	 * values were generated by a single thread using a single may be
       
  2347 	 * {@code AbstractSplittableWithBrineGenerator} object. Either or both of the two objects
       
  2348 	 * further split using the {@code split()} method, and the same expected
       
  2349 	 * statistical properties apply to the entire set of generators constructed
       
  2350 	 * by such recursive splitting.
       
  2351 	 *
       
  2352 	 * @param brine a long value, of which the low 63 bits provide a unique id
       
  2353 	 * among calls to this method for constructing a single series of Generator objects.
       
  2354 	 *
       
  2355 	 * @return the new {@code AbstractSplittableWithBrineGenerator} instance
       
  2356 	 */
       
  2357 	public SplittableGenerator split(long brine) {
       
  2358 	    return this.split(this, brine);
       
  2359 	}
       
  2360 
       
  2361 	/**
       
  2362 	 * Constructs and returns a new instance of {@code L64X128MixRandom}
       
  2363 	 * that shares no mutable state with this instance.
       
  2364 	 * However, with very high probability, the set of values collectively
       
  2365 	 * generated by the two objects has the same statistical properties as if
       
  2366 	 * same the quantity of values were generated by a single thread using
       
  2367 	 * a single {@code L64X128MixRandom} object.  Either or both of the two
       
  2368 	 * objects may be further split using the {@code split} method,
       
  2369 	 * and the same expected statistical properties apply to the
       
  2370 	 * entire set of generators constructed by such recursive splitting.
       
  2371 	 *
       
  2372 	 * @param source a {@code SplittableGenerator} instance to be used instead
       
  2373 	 *               of this one as a source of pseudorandom bits used to
       
  2374 	 *               initialize the state of the new ones.
       
  2375 	 * @return a new instance of {@code L64X128MixRandom}
       
  2376 	 */
       
  2377 	public SplittableGenerator split(SplittableGenerator source) {
       
  2378 	    // It's a one-off: supply randomly chosen brine
       
  2379 	    return this.split(source, source.nextLong());
       
  2380 	}
       
  2381 
       
  2382 	/**
       
  2383 	 * Constructs and returns a new instance of {@code AbstractSplittableWithBrineGenerator}
       
  2384 	 * that shares no mutable state with this instance. However, with very high
       
  2385 	 * probability, the set of values collectively generated by the two objects
       
  2386 	 * should have the same statistical properties as if the same quantity of
       
  2387 	 * values were generated by a single thread using a single may be
       
  2388 	 * {@code AbstractSplittableWithBrineGenerator} object. Either or both of the two objects
       
  2389 	 * further split using the {@code split()} method, and the same expected
       
  2390 	 * statistical properties apply to the entire set of generators constructed
       
  2391 	 * by such recursive splitting.
       
  2392 	 *
       
  2393 	 * @param source a {@code SplittableGenerator} instance to be used instead
       
  2394 	 *               of this one as a source of pseudorandom bits used to
       
  2395 	 *               initialize the state of the new ones.
       
  2396 	 * @param brine a long value, of which the low 63 bits provide a unique id
       
  2397 	 *              among calls to this method for constructing a single series of
       
  2398 	 *              {@code RandomGenerator} objects.
       
  2399 	 *
       
  2400 	 * @return the new {@code AbstractSplittableWithBrineGenerator} instance
       
  2401 	 */
       
  2402 	public abstract SplittableGenerator split(SplittableGenerator source, long brine);
       
  2403 
       
  2404 
       
  2405 	/* ---------------- spliterator ---------------- */
       
  2406 	/**
       
  2407 	 * Alternate spliterator for stream of generators of type SplittableGenerator.  We multiplex
       
  2408 	 * the two versions into one class by treating "infinite" as equivalent to Long.MAX_VALUE.
       
  2409 	 * For splits, it uses the standard divide-by-two approach.
       
  2410 	 *
       
  2411 	 * This differs from {@code SplittableGenerator.RandomSplitsSpliterator} in that it provides
       
  2412 	 * a brine argument (a mixture of salt and an index) when calling the {@code split} method.
       
  2413 	 */
       
  2414 	static class RandomSplitsSpliteratorWithSalt
       
  2415 	    extends RandomSpliterator implements Spliterator<SplittableGenerator> {
       
  2416 
       
  2417 	    final SplittableGenerator generatingGenerator;
       
  2418 	    final AbstractSplittableWithBrineGenerator constructingGenerator;
       
  2419 	    long salt;
       
  2420 
       
  2421 	    // Important invariant: 0 <= index <= fence
       
  2422 
       
  2423 	    // Important invariant: if salt and index are both nonzero,
       
  2424 	    // the rightmost 1-bit of salt is to the left of the leftmost 1-bit of index.
       
  2425 	    // If necessary, the salt can be leftshifted by SALT_SHIFT as many times as
       
  2426 	    // necessary to maintain the invariant.
       
  2427 
       
  2428 	    RandomSplitsSpliteratorWithSalt(SplittableGenerator generatingGenerator, long index, long fence,
       
  2429 					    AbstractSplittableWithBrineGenerator constructingGenerator, long salt) {
       
  2430 		super(index, fence);
       
  2431 		this.generatingGenerator = generatingGenerator;
       
  2432 		this.constructingGenerator = constructingGenerator;
       
  2433 		while ((salt != 0) && (Long.compareUnsigned(salt & -salt, index) <= 0)) {
       
  2434 		    salt = salt << SALT_SHIFT;
       
  2435 		}
       
  2436 		this.salt = salt;
       
  2437 	    }
       
  2438 
       
  2439             public Spliterator<SplittableGenerator> trySplit() {
       
  2440                 long i = index, m = (i + fence) >>> 1;
       
  2441                 if (m <= i) return null;
       
  2442 		RandomSplitsSpliteratorWithSalt result =
       
  2443 		    new RandomSplitsSpliteratorWithSalt(generatingGenerator.split(), i, m, constructingGenerator, salt);
       
  2444                 index = m;
       
  2445 		while ((salt != 0) && (Long.compareUnsigned(salt & -salt, index) <= 0)) {
       
  2446 		    salt = salt << SALT_SHIFT;
       
  2447 		}
       
  2448 		return result;
       
  2449             }
       
  2450 
       
  2451 	    public boolean tryAdvance(Consumer<? super SplittableGenerator> consumer) {
       
  2452 		if (consumer == null) throw new NullPointerException();
       
  2453 		long i = index, f = fence;
       
  2454 		if (i < f) {
       
  2455 		    consumer.accept(constructingGenerator.split(generatingGenerator, salt | i));
       
  2456 		    ++i;
       
  2457 		    index = i;
       
  2458 		    if ((i & salt) != 0) salt <<= SALT_SHIFT;
       
  2459 		    return true;
       
  2460 		}
       
  2461 		return false;
       
  2462 	    }
       
  2463 
       
  2464 	    public void forEachRemaining(Consumer<? super SplittableGenerator> consumer) {
       
  2465 		if (consumer == null) throw new NullPointerException();
       
  2466 		long i = index, f = fence;
       
  2467 		if (i < f) {
       
  2468 		    index = f;
       
  2469 		    AbstractSplittableWithBrineGenerator c = constructingGenerator;
       
  2470 		    SplittableGenerator r = generatingGenerator;
       
  2471 		    do {
       
  2472 			consumer.accept(c.split(r, salt | i));
       
  2473 			++i;
       
  2474 			if ((i & salt) != 0) salt <<= SALT_SHIFT;
       
  2475 		    } while (i < f);
       
  2476 		}
       
  2477 	    }
       
  2478 	}
       
  2479 
       
  2480     }
       
  2481 
  2247 }
  2482 }
  2248