1 /*
  2  * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 package nsk.share.test;
 25 
 26 import java.util.Random;
 27 import jdk.test.lib.Utils;
 28 import nsk.share.TestFailure;
 29 
 30 /**
 31  * Utility class which encapsulates all useful static methods.
 32  */
 33 public class LocalRandom {
 34     static {
 35         // ensure seed got printed out
 36         Utils.getRandomInstance();
 37     }
 38     private final static ThreadLocal<Random> random = new ThreadLocal<>() {
 39         protected Random initialValue() {
 40             // each thread gets its own seed independendly on the order they
 41             // use LocalRandom, yet it depends on the order threads are created.
 42             // main thread uses original seed
 43             return new Random(Utils.SEED ^ (Thread.currentThread().getId() - 1));
 44         }
 45     };
 46     private static int minPauseTime = 3000;
 47     private static int maxPauseTime = 5000;
 48     private static int maxRandomCount = 65536;
 49 
 50 
 51     /*
 52      * Initializes a thread-local instance to ensure that there is enough memory.
 53      * Useful for tests that exhaust memory.
 54      */
 55     public static void init() {
 56         random.get();
 57     }
 58 
 59     /*
 60      * Return next random double number.
 61      *
 62      * @return random double
 63      */
 64     public static double random() {
 65         return random.get().nextDouble();
 66     }
 67 
 68     public static double nextDouble() {
 69         return random.get().nextDouble();
 70     }
 71 
 72     public static byte nextByte() {
 73         return (byte) nextInt(Byte.MIN_VALUE, Byte.MAX_VALUE);
 74     }
 75 
 76     public static char nextChar() {
 77         return (char) nextInt(Character.MIN_VALUE, Character.MAX_VALUE);
 78     }
 79 
 80     public static short nextShort() {
 81         return (short) nextInt(Short.MIN_VALUE, Short.MAX_VALUE);
 82     }
 83 
 84     public static boolean nextBoolean() {
 85         return random.get().nextBoolean();
 86     }
 87 
 88     public static void nextBytes(byte[] arr) {
 89         if (arr.length == 0) {
 90             return;
 91         }
 92         int k = Math.max(1, arr.length / maxRandomCount);
 93         byte hash = 0;
 94         byte b;
 95         for (int i = 0; i < arr.length - k; i += k) {
 96             b = nextByte();
 97             arr[i] = b;
 98             hash ^= b;
 99         }
100         arr[arr.length - k] = hash;
101     }
102 
103     public static void validate(byte[] arr) {
104         int k = Math.max(1, arr.length / maxRandomCount);
105         byte hash = 0;
106         for (int i = 0; i < arr.length; i += k) {
107             hash ^= arr[i];
108         }
109         if (hash != 0) {
110             throw new TestFailure(
111                     "Validation failure: " + arr.getClass() + " hash: " + hash);
112         }
113     }
114 
115     public static void nextShorts(short[] arr) {
116         if (arr.length == 0) {
117             return;
118         }
119         int k = Math.max(1, arr.length / maxRandomCount);
120         short hash = 0;
121         short s;
122         for (int i = 0; i < arr.length - k; i += k) {
123             s = nextShort();
124             arr[i] = s;
125             hash ^= s;
126         }
127         arr[arr.length - k] = hash;
128     }
129 
130     public static void validate(short[] arr) {
131         int k = Math.max(1, arr.length / maxRandomCount);
132         short hash = 0;
133         for (int i = 0; i < arr.length; i += k) {
134             hash ^= arr[i];
135         }
136         if (hash != 0) {
137             throw new TestFailure(
138                     "Validation failure: " + arr.getClass() + " hash: " + hash);
139         }
140     }
141 
142     public static void nextChars(char[] arr) {
143         if (arr.length == 0) {
144             return;
145         }
146         int k = Math.max(1, arr.length / maxRandomCount);
147         char hash = 0;
148         char c;
149         for (int i = 0; i < arr.length - k; i += k) {
150             c = nextChar();
151             arr[i] = c;
152             hash ^= c;
153         }
154         arr[arr.length - k] = hash;
155     }
156 
157     public static void validate(char[] arr) {
158         int k = Math.max(1, arr.length / maxRandomCount);
159         char hash = 0;
160         for (int i = 0; i < arr.length; i += k) {
161             hash ^= arr[i];
162         }
163         if (hash != 0) {
164             throw new TestFailure(
165                     "Validation failure: " + arr.getClass() + " hash: " + hash);
166         }
167     }
168 
169     public static void nextInts(int[] arr) {
170         if (arr.length == 0) {
171             return;
172         }
173         int k = Math.max(1, arr.length / maxRandomCount);
174         int hash = 0;
175         int in;
176         for (int i = 0; i < arr.length - k; i += k) {
177             in = nextInt();
178             hash ^= in;
179             arr[i] = in;
180         }
181         arr[arr.length - k] = hash;
182     }
183 
184     public static void validate(int[] arr) {
185         int k = Math.max(1, arr.length / maxRandomCount);
186         int hash = 0;
187         for (int i = 0; i < arr.length; i += k) {
188             hash ^= arr[i];
189         }
190         if (hash != 0) {
191             throw new TestFailure(
192                     "Validation failure: " + arr.getClass() + " hash: " + hash);
193         }
194     }
195 
196     public static void nextBooleans(boolean[] arr) {
197         if (arr.length == 0) {
198             return;
199         }
200         int k = Math.max(1, arr.length / maxRandomCount);
201         boolean hash = false;
202         boolean b;
203         for (int i = 0; i < arr.length - k; i += k) {
204             b = nextBoolean();
205             hash ^= b;
206             arr[i] = b;
207         }
208         arr[arr.length - k] = hash;
209     }
210 
211     public static void validate(boolean[] arr) {
212         int k = Math.max(1, arr.length / maxRandomCount);
213         boolean hash = false;
214         for (int i = 0; i < arr.length; i += k) {
215             hash ^= arr[i];
216         }
217         if (hash != false) {
218             throw new TestFailure(
219                     "Validation failure: " + arr.getClass() + " hash: " + hash);
220         }
221     }
222 
223     public static void nextLongs(long[] arr) {
224         if (arr.length == 0) {
225             return;
226         }
227         int k = Math.max(1, arr.length / maxRandomCount);
228         long hash = 0;
229         long l;
230         for (int i = 0; i < arr.length - k; i += k) {
231             l = nextLong();
232             hash ^= l;
233             arr[i] = l;
234         }
235         arr[arr.length - k] = hash;
236     }
237 
238     public static void validate(long[] arr) {
239         int k = Math.max(1, arr.length / maxRandomCount);
240         long hash = 0;
241         for (int i = 0; i < arr.length; i += k) {
242             hash ^= arr[i];
243         }
244         if (hash != 0) {
245             throw new TestFailure(
246                     "Validation failure: " + arr.getClass() + " hash: " + hash);
247         }
248     }
249 
250     public static void nextFloats(float[] arr) {
251         if (arr.length == 0) {
252             return;
253         }
254         int k = Math.max(1, arr.length / maxRandomCount);
255         for (int i = 0; i < arr.length - k; i += k) {
256             arr[i] = nextFloat();
257         }
258     }
259 
260     public static void validate(float[] arr) {
261     }
262 
263     public static void nextDoubles(double[] arr) {
264         if (arr.length == 0) {
265             return;
266         }
267         int k = Math.max(1, arr.length / maxRandomCount);
268         for (int i = 0; i < arr.length - k; i += k) {
269             arr[i] = nextDouble();
270         }
271     }
272 
273     public static void validate(double[] arr) {
274     }
275 
276     public static int nextInt() {
277         return random.get().nextInt();
278     }
279 
280     /**
281      * Return next integer value from 0..n range.
282      *
283      * @param n maximum value
284      * @return random integer
285      */
286     public static int nextInt(int n) {
287         return random.get().nextInt(n);
288     }
289 
290     public static long nextLong() {
291         return random.get().nextLong();
292     }
293 
294     /**
295      * Return next random integer from min..max range.
296      *
297      * @param min minimum value
298      * @param max maximum value
299      * @return random integer
300      */
301     public static int nextInt(int min, int max) {
302         return min + nextInt(max - min);
303     }
304 
305     /**
306      * Return next random float number.
307      *
308      * @return random double
309      */
310     public static float nextFloat() {
311         return random.get().nextFloat();
312     }
313 
314     /**
315      * Return random pause time.
316      */
317     public static long randomPauseTime() {
318         return nextInt(minPauseTime, maxPauseTime);
319     }
320 
321     /**
322      * Set minimum pause time.
323      *
324      * @param minPauseTime minimum pause time
325      */
326     public static void setMinPauseTime(int minPauseTime) {
327         LocalRandom.minPauseTime = minPauseTime;
328     }
329 
330     /**
331      * Set maximum pause time.
332      *
333      * @param maxPauseTime maximum pause time
334      */
335     public static void setMaxPauseTime(int maxPauseTime) {
336         LocalRandom.maxPauseTime = maxPauseTime;
337     }
338 }