mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
Merge
This commit is contained in:
commit
7d0edb5743
19 changed files with 314 additions and 88 deletions
|
@ -26,6 +26,8 @@ package java.util;
|
|||
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.random.RandomGenerator.SplittableGenerator;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
|
@ -86,13 +88,12 @@ import jdk.internal.util.random.RandomSupport.RandomGeneratorProperties;
|
|||
* @author Doug Lea
|
||||
* @since 1.8
|
||||
*/
|
||||
@SuppressWarnings("exports")
|
||||
@RandomGeneratorProperties(
|
||||
name = "SplittableRandom",
|
||||
i = 64, j = 0, k = 0,
|
||||
equidistribution = 1
|
||||
)
|
||||
public final class SplittableRandom extends AbstractSplittableGenerator {
|
||||
public final class SplittableRandom implements RandomGenerator, SplittableGenerator {
|
||||
|
||||
/*
|
||||
* Implementation Overview.
|
||||
|
@ -182,6 +183,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
private SplittableRandom(long seed, long gamma) {
|
||||
this.seed = seed;
|
||||
this.gamma = gamma;
|
||||
this.proxy = new AbstractSplittableGeneratorProxy();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -216,6 +218,31 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
return (n < 24) ? z ^ 0xaaaaaaaaaaaaaaaaL : z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy class to non-public RandomSupportAbstractSplittableGenerator.
|
||||
*/
|
||||
private class AbstractSplittableGeneratorProxy extends AbstractSplittableGenerator {
|
||||
@Override
|
||||
public int nextInt() {
|
||||
return SplittableRandom.this.nextInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nextLong() {
|
||||
return SplittableRandom.this.nextLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.SplittableRandom split(SplittableGenerator source) {
|
||||
return new SplittableRandom(source.nextLong(), mixGamma(source.nextLong()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy object to non-public RandomSupportAbstractSplittableGenerator.
|
||||
*/
|
||||
private AbstractSplittableGeneratorProxy proxy;
|
||||
|
||||
/**
|
||||
* Adds gamma to seed.
|
||||
*/
|
||||
|
@ -251,6 +278,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
long s = defaultGen.getAndAdd(2 * GOLDEN_GAMMA);
|
||||
this.seed = mix64(s);
|
||||
this.gamma = mixGamma(s + GOLDEN_GAMMA);
|
||||
this.proxy = new AbstractSplittableGeneratorProxy();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -297,7 +325,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public void nextBytes(byte[] bytes) {
|
||||
super.nextBytes(bytes);
|
||||
proxy.nextBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -307,7 +335,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public Stream<SplittableGenerator> splits() {
|
||||
return super.splits();
|
||||
return proxy.splits();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -318,7 +346,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public Stream<SplittableGenerator> splits(long streamSize) {
|
||||
return super.splits(streamSize, this);
|
||||
return proxy.splits(streamSize, this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -329,7 +357,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public Stream<SplittableGenerator> splits(SplittableGenerator source) {
|
||||
return super.splits(Long.MAX_VALUE, source);
|
||||
return proxy.splits(Long.MAX_VALUE, source);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -341,7 +369,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public Stream<SplittableGenerator> splits(long streamSize, SplittableGenerator source) {
|
||||
return super.splits(streamSize, source);
|
||||
return proxy.splits(streamSize, source);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -356,7 +384,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public IntStream ints(long streamSize) {
|
||||
return super.ints(streamSize);
|
||||
return proxy.ints(streamSize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -370,7 +398,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public IntStream ints() {
|
||||
return super.ints();
|
||||
return proxy.ints();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -390,7 +418,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound) {
|
||||
return super.ints(streamSize, randomNumberOrigin, randomNumberBound);
|
||||
return proxy.ints(streamSize, randomNumberOrigin, randomNumberBound);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -410,7 +438,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
|
||||
return super.ints(randomNumberOrigin, randomNumberBound);
|
||||
return proxy.ints(randomNumberOrigin, randomNumberBound);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -425,7 +453,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public LongStream longs(long streamSize) {
|
||||
return super.longs(streamSize);
|
||||
return proxy.longs(streamSize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -439,7 +467,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public LongStream longs() {
|
||||
return super.longs();
|
||||
return proxy.longs();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -459,7 +487,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public LongStream longs(long streamSize, long randomNumberOrigin, long randomNumberBound) {
|
||||
return super.longs(streamSize, randomNumberOrigin, randomNumberBound);
|
||||
return proxy.longs(streamSize, randomNumberOrigin, randomNumberBound);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -479,7 +507,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
|
||||
return super.longs(randomNumberOrigin, randomNumberBound);
|
||||
return proxy.longs(randomNumberOrigin, randomNumberBound);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -494,7 +522,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public DoubleStream doubles(long streamSize) {
|
||||
return super.doubles(streamSize);
|
||||
return proxy.doubles(streamSize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -509,7 +537,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public DoubleStream doubles() {
|
||||
return super.doubles();
|
||||
return proxy.doubles();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -529,7 +557,7 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) {
|
||||
return super.doubles(streamSize, randomNumberOrigin, randomNumberBound);
|
||||
return proxy.doubles(streamSize, randomNumberOrigin, randomNumberBound);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -549,6 +577,6 @@ public final class SplittableRandom extends AbstractSplittableGenerator {
|
|||
*/
|
||||
@Override
|
||||
public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
|
||||
return super.doubles(randomNumberOrigin, randomNumberBound);
|
||||
return proxy.doubles(randomNumberOrigin, randomNumberBound);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -516,9 +516,10 @@ public interface RandomGenerator {
|
|||
* @throws IllegalArgumentException if {@code bound} is not
|
||||
* both positive and finite
|
||||
*
|
||||
* @implSpec The default implementation simply calls
|
||||
* {@link RandomSupport#checkBound checkBound}(bound) and then
|
||||
* {@link RandomSupport#boundedNextFloat boundedNextFloat}(this, bound).
|
||||
* @implSpec The default implementation checks that {@code bound} is a
|
||||
* positive finite float. Then invokes {@code nextFloat()}, scaling
|
||||
* the result so that the final result lies between {@code 0.0f} (inclusive)
|
||||
* and {@code bound} (exclusive).
|
||||
*/
|
||||
default float nextFloat(float bound) {
|
||||
RandomSupport.checkBound(bound);
|
||||
|
@ -540,9 +541,11 @@ public interface RandomGenerator {
|
|||
* or {@code bound} is not finite, or {@code origin}
|
||||
* is greater than or equal to {@code bound}
|
||||
*
|
||||
* @implSpec The default implementation simply calls
|
||||
* {@link RandomSupport#checkBound checkBound}(bound) and then
|
||||
* {@link RandomSupport#boundedNextFloat boundedNextFloat}(this, bound).
|
||||
* @implSpec The default implementation checks that {@code origin} and
|
||||
* {@code bound} are positive finite floats. Then invokes
|
||||
* {@code nextFloat()}, scaling and translating the result so that the final
|
||||
* result lies between {@code origin} (inclusive) and {@code bound}
|
||||
* (exclusive).
|
||||
*/
|
||||
default float nextFloat(float origin, float bound) {
|
||||
RandomSupport.checkRange(origin, bound);
|
||||
|
@ -577,9 +580,10 @@ public interface RandomGenerator {
|
|||
* @throws IllegalArgumentException if {@code bound} is not
|
||||
* both positive and finite
|
||||
*
|
||||
* @implSpec The default implementation simply calls
|
||||
* {@link RandomSupport#checkBound checkBound}(bound) and then
|
||||
* {@link RandomSupport#boundedNextDouble boundedNextDouble}(this, bound).
|
||||
* @implSpec The default implementation checks that {@code bound} is a
|
||||
* positive finite double. Then invokes {@code nextDouble()}, scaling
|
||||
* the result so that the final result lies between {@code 0.0} (inclusive)
|
||||
* and {@code bound} (exclusive).
|
||||
*/
|
||||
default double nextDouble(double bound) {
|
||||
RandomSupport.checkBound(bound);
|
||||
|
@ -601,9 +605,11 @@ public interface RandomGenerator {
|
|||
* or {@code bound} is not finite, or {@code origin}
|
||||
* is greater than or equal to {@code bound}
|
||||
*
|
||||
* @implSpec The default implementation simply calls
|
||||
* {@link RandomSupport#checkBound checkBound}(bound) and then
|
||||
* {@link RandomSupport#boundedNextDouble boundedNextDouble}(this, bound).
|
||||
* @implSpec The default implementation checks that {@code origin} and
|
||||
* {@code bound} are positive finite doubles. Then calls
|
||||
* {@code nextDouble()}, scaling and translating the result so that the final
|
||||
* result lies between {@code origin} (inclusive) and {@code bound}
|
||||
* (exclusive).
|
||||
*/
|
||||
default double nextDouble(double origin, double bound) {
|
||||
RandomSupport.checkRange(origin, bound);
|
||||
|
@ -627,16 +633,20 @@ public interface RandomGenerator {
|
|||
* Returns a pseudorandomly chosen {@code int} value between zero
|
||||
* (inclusive) and the specified bound (exclusive).
|
||||
*
|
||||
* @param bound the upper bound (exclusive) for the returned value. Must be positive.
|
||||
* @param bound the upper bound (exclusive) for the returned value.
|
||||
* Must be positive.
|
||||
*
|
||||
* @return a pseudorandomly chosen {@code int} value between
|
||||
* zero (inclusive) and the bound (exclusive)
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code bound} is not positive
|
||||
*
|
||||
* @implSpec The default implementation simply calls
|
||||
* {@link RandomSupport#checkBound checkBound}(bound) and then
|
||||
* {@link RandomSupport#boundedNextInt boundedNextInt}(this, bound).
|
||||
* @implSpec The default implementation checks that {@code bound} is a
|
||||
* positive {@code int}. Then invokes {@code nextInt()}, limiting the result
|
||||
* to be greater than or equal zero and less than {@code bound}. If {@code bound}
|
||||
* is a power of two then limiting is a simple masking operation. Otherwise,
|
||||
* the result is re-calculated by invoking {@code nextInt()} until the
|
||||
* result is greater than or equal zero and less than {@code bound}.
|
||||
*/
|
||||
default int nextInt(int bound) {
|
||||
RandomSupport.checkBound(bound);
|
||||
|
@ -657,9 +667,13 @@ public interface RandomGenerator {
|
|||
* @throws IllegalArgumentException if {@code origin} is greater than
|
||||
* or equal to {@code bound}
|
||||
*
|
||||
* @implSpec The default implementation simply calls
|
||||
* {@link RandomSupport#checkBound(long) checkBound}(bound) and then
|
||||
* {@link RandomSupport#boundedNextInt(RandomGenerator, int) boundedNextInt}(this, bound).
|
||||
* @implSpec The default implementation checks that {@code origin} and
|
||||
* {@code bound} are positive {@code ints}. Then invokes {@code nextInt()},
|
||||
* limiting the result to be greater that or equal {@code origin} and less
|
||||
* than {@code bound}. If {@code bound} is a power of two then limiting is a
|
||||
* simple masking operation. Otherwise, the result is re-calculated by
|
||||
* invoking {@code nextInt()} until the result is greater than or equal
|
||||
* {@code origin} and less than {@code bound}.
|
||||
*/
|
||||
default int nextInt(int origin, int bound) {
|
||||
RandomSupport.checkRange(origin, bound);
|
||||
|
@ -678,16 +692,21 @@ public interface RandomGenerator {
|
|||
* Returns a pseudorandomly chosen {@code long} value between zero
|
||||
* (inclusive) and the specified bound (exclusive).
|
||||
*
|
||||
* @param bound the upper bound (exclusive) for the returned value. Must be positive.
|
||||
* @param bound the upper bound (exclusive) for the returned value.
|
||||
* Must be positive.
|
||||
*
|
||||
* @return a pseudorandomly chosen {@code long} value between
|
||||
* zero (inclusive) and the bound (exclusive)
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code bound} is not positive
|
||||
*
|
||||
* @implSpec The default implementation simply calls
|
||||
* {@link RandomSupport#checkBound checkBound}(bound) and then
|
||||
* {@link RandomSupport#boundedNextLong boundedNextLong}(this, bound).
|
||||
* @implSpec The default implementation checks that {@code bound} is a
|
||||
* positive {@code long}. Then invokes {@code nextLong()}, limiting the
|
||||
* result to be greater than or equal zero and less than {@code bound}. If
|
||||
* {@code bound} is a power of two then limiting is a simple masking
|
||||
* operation. Otherwise, the result is re-calculated by invoking
|
||||
* {@code nextLong()} until the result is greater than or equal zero and
|
||||
* less than {@code bound}.
|
||||
*/
|
||||
default long nextLong(long bound) {
|
||||
RandomSupport.checkBound(bound);
|
||||
|
@ -708,9 +727,13 @@ public interface RandomGenerator {
|
|||
* @throws IllegalArgumentException if {@code origin} is greater than
|
||||
* or equal to {@code bound}
|
||||
*
|
||||
* @implSpec The default implementation simply calls
|
||||
* {@link RandomSupport#checkBound checkBound}(bound) and then
|
||||
* {@link RandomSupport#boundedNextLong boundedNextLong}(this, bound).
|
||||
* @implSpec The default implementation checks that {@code origin} and
|
||||
* {@code bound} are positive {@code longs}. Then invokes {@code nextLong()},
|
||||
* limiting the result to be greater than or equal {@code origin} and less
|
||||
* than {@code bound}. If {@code bound} is a power of two then limiting is a
|
||||
* simple masking operation. Otherwise, the result is re-calculated by
|
||||
* invoking {@code nextLong()} until the result is greater than or equal
|
||||
* {@code origin} and less than {@code bound}.
|
||||
*/
|
||||
default long nextLong(long origin, long bound) {
|
||||
RandomSupport.checkRange(origin, bound);
|
||||
|
@ -892,10 +915,6 @@ public interface RandomGenerator {
|
|||
* Returns an instance of {@link SplittableGenerator} that utilizes the
|
||||
* {@code name} <a href="package-summary.html#algorithms">algorithm</a>.
|
||||
*
|
||||
* @implNote Availability is determined by RandomGeneratorFactory using the
|
||||
* service provider API to locate implementations of the RandomGenerator
|
||||
* interface and filtering on the SplittableGenerator interface.
|
||||
*
|
||||
* @param name Name of random number generator
|
||||
* <a href="package-summary.html#algorithms">algorithm</a>
|
||||
*
|
||||
|
|
|
@ -374,7 +374,7 @@ public final class RandomGeneratorFactory<T extends RandomGenerator> {
|
|||
/**
|
||||
* Returns a non-empty stream of available {@link RandomGeneratorFactory RandomGeneratorFactory(s)}.
|
||||
*
|
||||
* RandomGenerators that are marked as deprecated or are not properly configured are not included in the result.
|
||||
* RandomGenerators that are marked as deprecated are not included in the result.
|
||||
*
|
||||
* @implSpec Availability is determined by RandomGeneratorFactory using the service provider API
|
||||
* to locate implementations of the RandomGenerator interface.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue