diff -r 9a4184201823 -r b0c958c0e6c6 src/java.base/share/classes/java/util/random/JumpableRNG.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.base/share/classes/java/util/random/JumpableRNG.java Thu Jun 27 18:02:51 2019 -0300 @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.util; + +import java.math.BigInteger; +import java.util.stream.Stream; + +/** + * This interface is designed to provide a common protocol for objects + * that generate pseudorandom sequences of numbers (or Boolean values) + * and furthermore can easily jump forward (by a fixed amount) + * to a distant point in the state cycle. + * + *

Ideally, all {@code JumpableRng} objects produced by iterative + * jumping from a single original {@code JumpableRng} object are + * statistically independent of one another and individually uniform. + * In practice, one must settle for some approximation to independence + * and uniformity. In particular, a specific implementation may + * assume that each generator in a stream produced by the {@code jumps} + * method is used to produce a number of values no larger than either + * 264 or the square root of its period. Implementors are + * advised to use algorithms whose period is at least 2127. + * + *

Methods are provided to perform a single jump operation and also + * to produce a stream of generators produced from the original by + * iterative copying and jumping of internal state. A typical + * strategy for a multithreaded application is to create a single + * {@code JumpableRng} object, calls its {@code jumps} method exactly + * once, and then parcel out generators from the resulting stream, one + * to each thread. It is generally not a good idea to call {@code jump} + * on a generator that was itself produced by the {@code jumps} method, + * because the result may be a generator identical to another + * generator already produce by that call to the {@code jumps} method. + * For this reason, the return type of the {@code jumps} method is + * {@code Stream} rather than {@code Stream}, even + * though the actual generator objects in that stream likely do also + * implement the {@code JumpableRng} interface. + * + *

An implementation of the {@code JumpableRng} interface must provide + * concrete definitions for the methods {@code nextInt()}, {@code nextLong}, + * {@code period()}, {@code copy()}, {@code jump()}, and {@code defaultJumpDistance()}. + * Default implementations are provided for all other methods. + * + *

Objects that implement {@code java.util.JumpableRng} are + * typically not cryptographically secure. Consider instead using + * {@link java.security.SecureRandom} to get a cryptographically + * secure pseudo-random number generator for use by + * security-sensitive applications. + * + * @author Guy Steele + * @since 1.9 + */ +public interface JumpableRng extends StreamableRng { + /** + * Returns a new generator whose internal state is an exact copy + * of this generator (therefore their future behavior should be + * identical if subjected to the same series of operations). + * + * @return a new object that is a copy of this generator + */ + JumpableRng copy(); + + /** + * Alter the state of this pseudorandom number generator so as to + * jump forward a large, fixed distance (typically 264 + * or more) within its state cycle. + */ + void jump(); + + /** + * Returns the distance by which the {@code jump()} method will jump + * forward within the state cycle of this generator object. + * + * @return the default jump distance (as a {@code double} value) + */ + double defaultJumpDistance(); + + /** + * Returns an effectively unlimited stream of new pseudorandom + * number generators, each of which implements the {@code Rng} + * interface. + * + * @implNote It is permitted to implement this method in a manner + * equivalent to {@code jumps(Long.MAX_VALUE)}. + * + * @implNote The default implementation produces a sequential stream + * that repeatedly calls {@code copy()} and {@code jump()} on this generator, + * and the copies become the generators produced by the stream. + * + * @return a stream of objects that implement the {@code Rng} interface + */ + default Stream jumps() { + return Stream.generate(this::copyAndJump).sequential(); + } + + /** + * Returns a stream producing the given {@code streamSize} number of + * new pseudorandom number generators, each of which implements the + * {@code Rng} interface. + * + * @implNote The default implementation produces a sequential stream + * that repeatedly calls {@code copy()} and {@code jump()} on this generator, + * and the copies become the generators produced by the stream. + * + * @param streamSize the number of generators to generate + * @return a stream of objects that implement the {@code Rng} interface + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero + */ + default Stream jumps(long streamSize) { + return jumps().limit(streamSize); + } + + /** + * Returns an effectively unlimited stream of new pseudorandom + * number generators, each of which implements the {@code Rng} + * interface. Ideally the generators in the stream will appear + * to be statistically independent. + * + * @implNote The default implementation calls {@code jumps()}. + * + * @return a stream of objects that implement the {@code Rng} interface + */ + default Stream rngs() { + return this.jumps(); + } + + /** + * Returns a stream producing the given {@code streamSize} number of + * new pseudorandom number generators, each of which implements the + * {@code Rng} interface. Ideally the generators in the stream will + * appear to be statistically independent. + * + * @implNote The default implementation calls {@code jumps(streamSize)}. + * + * @param streamSize the number of generators to generate + * @return a stream of objects that implement the {@code Rng} interface + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero + */ + default Stream rngs(long streamSize) { + return this.jumps(streamSize); + } + + /** + * Copy this generator, jump this generator forward, then return the copy. + * + * @return a copy of this generator object before the jump occurred + */ + default Rng copyAndJump() { + Rng result = copy(); + jump(); + return result; + } + +}