|
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 } |