On Tue, 17 Nov 2020 22:21:18 GMT, Jim Laskey <jlas...@openjdk.org> wrote:

>> This PR is to introduce a new random number API for the JDK. The primary API 
>> is found in RandomGenerator and RandomGeneratorFactory. Further description 
>> can be found in the JEP https://openjdk.java.net/jeps/356 .
>
> Jim Laskey has updated the pull request with a new target base due to a merge 
> or a rebase. The pull request now contains 40 commits:
> 
>  - Merge branch 'master' into 8248862
>  - 8248862: Implement Enhanced Pseudo-Random Number Generators
>    
>    Update package-info.java
>  - 8248862: Implement Enhanced Pseudo-Random Number Generators
>    
>    Updated RandomGeneratorFactory javadoc.
>  - 8248862: Implement Enhanced Pseudo-Random Number Generators
>    
>    Updated documentation for RandomGeneratorFactory.
>  - Merge branch 'master' into 8248862
>  - Merge branch 'master' into 8248862
>  - 8248862: Implement Enhanced Pseudo-Random Number Generators
>    
>    Move RandomGeneratorProperty
>  - Merge branch 'master' into 8248862
>  - 8248862: Implement Enhanced Pseudo-Random Number Generators
>    
>    Clear up javadoc
>  - 8248862; Implement Enhanced Pseudo-Random Number Generators
>    
>    remove RandomGeneratorProperty from API
>  - ... and 30 more: 
> https://git.openjdk.java.net/jdk/compare/f7517386...6fe94c68

I am unsure if the intent is also to support external libraries providing 
`RandomGenerator` implementations. Currently there is an implicit contract for 
properties (reflectively invoking a method returning a map with a set of 
entries with known keys). Since the service provider implementation is the 
`RandomGenerator` itself, rather than `RandomGeneratorFactory` it is harder 
expose the meta-data with a clearer contract.

src/java.base/share/classes/java/util/Random.java line 592:

> 590: 
> 591:     @Override
> 592:     public Spliterator.OfInt makeIntsSpliterator(long index, long fence, 
> int origin, int bound) {

Unsure if this and the other two methods are intended to be public or not, 
since they are at the end of the class and override methods of a module private 
class. In principle there is nothing wrong with such `Spliterator` factories, 
but wonder if they are really needed given the `Stream` returning methods. The 
arrangement of classes makes it awkward to hide these methods.

src/java.base/share/classes/java/util/SplittableRandom.java line 171:

> 169:      * RandomGenerator properties.
> 170:      */
> 171:     static Map<RandomGeneratorProperty, Object> getProperties() {

With records exiting preview in 16 this map of properties could i think be 
represented as a record instance, with better type safety, where 
`RandomSupport.RandomGeneratorProperty` enum values become typed fields 
declared on the record class. Something to consider after integration perhaps?

src/java.base/share/classes/java/util/SplittableRandom.java line 211:

> 209:      * 
> http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html
> 210:      */
> 211:     private static long mix64(long z) {

Usages be replaced with calls to `RandomSupport.mixStafford13`?

src/java.base/share/classes/module-info.java line 250:

> 248:     exports jdk.internal.util.xml.impl to
> 249:         jdk.jfr;
> 250:     exports jdk.internal.util.random;

Unqualified export, should this be `to jdk.random`?

src/jdk.random/share/classes/module-info.java line 50:

> 48:  */
> 49: module jdk.random {
> 50:     uses java.util.random.RandomGenerator;

Are these `uses` declarations needed? `ServiceLoader` is not used by this 
module, and `RandomSupport` is not a service interface.

src/jdk.random/share/classes/module-info.java line 53:

> 51:     uses RandomSupport;
> 52: 
> 53:     exports jdk.random to

Why is this needed?

src/java.base/share/classes/java/util/random/package-info.java line 50:

> 48:  * given its name.
> 49:  *
> 50:  * <p> The principal supporting class is {@link RandomGenertatorFactor}. 
> This

s/RandomGenertatorFactor/RandomGenertatorFactory

src/java.base/share/classes/java/util/random/package-info.java line 140:

> 138:  *
> 139:  * <p> For applications with no special requirements,
> 140:  * "L64X128MixRandom" has a good balance among speed, space,

The documentation assumes that the `jdk.random` module is present in the JDK 
image. Perhaps we need to spit the specifics to `jdk.random`?

src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java line 
1211:

> 1209:                         Udiff = -Udiff;
> 1210:                         U2 = U1;
> 1211:                         U1 -= Udiff;

Updated `U1` never used (recommend running the code through a checker e.g. use 
IntelliJ)

src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java line 
331:

> 329:         }
> 330:         // Finally, we need to make sure the last z words are not all 
> zero.
> 331:         search: {

Nice! a rarely used feature :-)

src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java line 
1157:

> 1155:         /*
> 1156:          * The tables themselves, as well as a number of associated 
> parameters, are
> 1157:          * defined in class java.util.DoubleZigguratTables, which is 
> automatically

`DoubleZigguratTables` is an inner class of `RandomSupport`

src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java line 
2895:

> 2893:      * distribution: 0.0330
> 2894:      */
> 2895:     static class DoubleZigguratTables {

make `final`

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 
167:

> 165:      * Return the properties map for the specified provider.
> 166:      *
> 167:      * @param provider  provider to locate.

Method has no such parameter

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 
173:

> 171:     @SuppressWarnings("unchecked")
> 172:     private Map<RandomGeneratorProperty, Object> getProperties() {
> 173:         if (properties == null) {

`properties` needs to be marked volatile, and it needs to be assigned at line 
182 or line 184.

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 
148:

> 146:      */
> 147:     private static Map<String, Provider<? extends RandomGenerator>> 
> getFactoryMap() {
> 148:         if (factoryMap == null) {

`factoryMap` needs to be marked volatile when using the double checked locking 
idiom.

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 
320:

> 318:                         }
> 319:                     }
> 320:                 }

Add an `assert` statement that `ctor`, `ctorLong` and `ctorBytes` are all 
non-null?

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 
331:

> 329:      */
> 330:     private void ensureConstructors() {
> 331:         if (ctor == null) {

This check occurs outside of the synchronized block, field may need to be 
marked volatile. Unsure about the other dependent fields. Might need to store 
values from loop in `getConstructors` in locals and then assign in appropriate 
order, assigning the volatile field last.

-------------

PR: https://git.openjdk.java.net/jdk/pull/1273

Reply via email to