Skip to content

Commit

Permalink
GH-237: Rename RandomInts to RandomNumbers and add methods operating …
Browse files Browse the repository at this point in the history
…on longs.
  • Loading branch information
dweiss committed Oct 13, 2016
1 parent 4db552c commit bbb3434
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 62 deletions.
6 changes: 6 additions & 0 deletions CHANGES.txt
Expand Up @@ -9,6 +9,9 @@ https://github.com/randomizedtesting/randomizedtesting/blob/master/CHANGES

Changes in Backwards Compatibility

* GH-237: Methods previously found in RandomInts have been moved to
RandomNumbers. (Dawid Weiss)

* GH-234: Run strict validation (thread-ownership, lifecycle) in
AssertingRandom only with assertions enabled. This change means that running
without -ea will from now on ignore the fact that random context's Random
Expand All @@ -28,6 +31,9 @@ Changes in Backwards Compatibility

New Features

* GH-237: Rename RandomInts to RandomNumbers and add methods operating
on longs. (Dawid Weiss).

* GH-235: A new class annotation was added: @TestContextRandomSupplier allows
declaring a custom class (RandomSupplier) that supplies a Random for the given
seed. This supplier can return any Random instance for the given initial
Expand Down
Expand Up @@ -26,7 +26,7 @@
import com.carrotsearch.randomizedtesting.annotations.Listeners;
import com.carrotsearch.randomizedtesting.annotations.Nightly;
import com.carrotsearch.randomizedtesting.generators.RandomBytes;
import com.carrotsearch.randomizedtesting.generators.RandomInts;
import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import com.carrotsearch.randomizedtesting.generators.RandomStrings;
import com.carrotsearch.randomizedtesting.generators.StringGenerator;
Expand Down Expand Up @@ -132,14 +132,21 @@ public static byte[] randomBytesOfLength(int minLength, int maxLength) {
}

//
// Delegates to RandomInts.
// Delegates to RandomNumbers.
//

/**
* A random integer from 0..max (inclusive).
*/
public static int randomInt(int max) {
return RandomInts.randomInt(getRandom(), max);
public static int randomInt(int max) {
return RandomNumbers.randomIntBetween(getRandom(), 0, max);
}

/**
* A random long from 0..max (inclusive).
*/
public static long randomLong(long max) {
return RandomNumbers.randomLongBetween(getRandom(), 0, max);
}

/**
Expand All @@ -148,7 +155,7 @@ public static int randomInt(int max) {
* @see #scaledRandomIntBetween(int, int)
*/
public static int randomIntBetween(int min, int max) {
return RandomInts.randomIntBetween(getRandom(), min, max);
return RandomNumbers.randomIntBetween(getRandom(), min, max);
}

/**
Expand All @@ -160,6 +167,20 @@ public static int between(int min, int max) {
return randomIntBetween(min, max);
}

/**
* A random long from <code>min</code> to <code>max</code> (inclusive).
*/
public static long randomLongBetween(long min, long max) {
return RandomNumbers.randomLongBetween(getRandom(), min, max);
}

/**
* An alias for {@link #randomLongBetween}.
*/
public static long between(long min, long max) {
return randomLongBetween(min, max);
}

/**
* Returns a random value greater or equal to <code>min</code>. The value
* picked is affected by {@link #isNightly()} and {@link #multiplier()}.
Expand Down
Expand Up @@ -70,7 +70,7 @@ public CodepointSetGenerator(String s) {

@Override
public String ofCodeUnitsLength(Random r, int minCodeUnits, int maxCodeUnits) {
int length = RandomInts.randomIntBetween(r, minCodeUnits, maxCodeUnits);
int length = RandomNumbers.randomIntBetween(r, minCodeUnits, maxCodeUnits);

// Check and cater for odd number of code units if no bmp characters are given.
if (bmp.length == 0 && isOdd(length)) {
Expand Down Expand Up @@ -108,7 +108,7 @@ public String ofCodeUnitsLength(Random r, int minCodeUnits, int maxCodeUnits) {

@Override
public String ofCodePointsLength(Random r, int minCodePoints, int maxCodePoints) {
int length = RandomInts.randomIntBetween(r, minCodePoints, maxCodePoints);
int length = RandomNumbers.randomIntBetween(r, minCodePoints, maxCodePoints);
int [] codepoints = new int [length];
while (length > 0) {
codepoints[--length] = all[r.nextInt(all.length)];
Expand Down
Expand Up @@ -22,7 +22,7 @@ public static byte[] randomBytesOfLength(Random r, int length) {
* @return Returns a byte array with random content.
*/
public static byte[] randomBytesOfLengthBetween(Random r, int minLength, int maxLength) {
byte[] bytes = new byte[RandomInts.randomIntBetween(r, minLength, maxLength)];
byte[] bytes = new byte[RandomNumbers.randomIntBetween(r, minLength, maxLength)];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) r.nextInt();
}
Expand Down

This file was deleted.

@@ -0,0 +1,78 @@
package com.carrotsearch.randomizedtesting.generators;

import java.util.Random;

/**
* Utility classes for selecting random numbers from within a range or the
* numeric domain for a given type.
*/
public final class RandomNumbers {
/**
* A random integer between <code>min</code> (inclusive) and <code>max</code> (inclusive).
*/
public static int randomIntBetween(Random r, int min, int max) {
assert max >= min : "max must be >= min: " + min + ", " + max;
long range = (long) max - (long) min;
if (range < Integer.MAX_VALUE) {
return min + r.nextInt(1 + (int) range);
} else {
return toIntExact(min + nextLong(r, 1 + range));
}
}

/**
* A random long between <code>min</code> (inclusive) and <code>max</code> (inclusive).
*/
public static long randomLongBetween(Random r, long min, long max) {
assert max >= min : "max must be >= min: " + min + ", " + max;
long range = max - min;
if (range < 0) {
range -= Long.MAX_VALUE;
if (range == Long.MIN_VALUE) {
// Full spectrum.
return r.nextLong();
} else {
long first = r.nextLong() & Long.MAX_VALUE;
long second = range == Long.MAX_VALUE ? (r.nextLong() & Long.MAX_VALUE) : nextLong(r, range + 1);
return min + first + second;
}
} else {
long second = range == Long.MAX_VALUE ? (r.nextLong() & Long.MAX_VALUE) : nextLong(r, range + 1);
return min + second;
}
}

/**
* Similar to {@link Random#nextInt(int)}, but returns a long between
* 0 (inclusive) and <code>n</code> (exclusive).
*
* @param rnd Random generator.
* @param n the bound on the random number to be returned. Must be
* positive.
* @return Returns a random number between 0 and n-1.
*/
public static long nextLong(Random rnd, long n) {
if (n <= 0) {
throw new IllegalArgumentException("n <= 0: " + n);
}

long value = rnd.nextLong();
long range = n - 1;
if ((n & range) == 0L) {
value &= range;
} else {
for (long u = value >>> 1; u + range - (value = u % n) < 0L;) {
u = rnd.nextLong() >>> 1;
}
}
return value;
}

private static int toIntExact(long value) {
if (value > Integer.MAX_VALUE) {
throw new ArithmeticException("Overflow: " + value);
} else {
return (int) value;
}
}
}
Expand Up @@ -62,12 +62,12 @@ public class RealisticUnicodeGenerator extends StringGenerator {

@Override
public String ofCodeUnitsLength(Random r, int minCodeUnits, int maxCodeUnits) {
int length = RandomInts.randomIntBetween(r, minCodeUnits, maxCodeUnits);
int length = RandomNumbers.randomIntBetween(r, minCodeUnits, maxCodeUnits);
final int block = r.nextInt(blockStarts.length);

final StringBuilder sb = new StringBuilder();
while (length > 0) {
int cp = RandomInts.randomIntBetween(r, blockStarts[block], blockEnds[block]);
int cp = RandomNumbers.randomIntBetween(r, blockStarts[block], blockEnds[block]);
if (length > Character.charCount(cp)) {
sb.appendCodePoint(cp);
length -= Character.charCount(cp);
Expand All @@ -82,11 +82,11 @@ public String ofCodeUnitsLength(Random r, int minCodeUnits, int maxCodeUnits) {

@Override
public String ofCodePointsLength(Random r, int minCodePoints, int maxCodePoints) {
final int length = RandomInts.randomIntBetween(r, minCodePoints, maxCodePoints);
final int length = RandomNumbers.randomIntBetween(r, minCodePoints, maxCodePoints);
final int block = r.nextInt(blockStarts.length);
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++)
sb.appendCodePoint(RandomInts.randomIntBetween(r, blockStarts[block], blockEnds[block]));
sb.appendCodePoint(RandomNumbers.randomIntBetween(r, blockStarts[block], blockEnds[block]));
return sb.toString();
}
}
Expand Up @@ -11,33 +11,33 @@ public class UnicodeGenerator extends StringGenerator {

@Override
public String ofCodeUnitsLength(Random r, int minCodeUnits, int maxCodeUnits) {
int length = RandomInts.randomIntBetween(r, minCodeUnits, maxCodeUnits);
int length = RandomNumbers.randomIntBetween(r, minCodeUnits, maxCodeUnits);
char [] chars = new char [length];
for (int i = 0; i < chars.length;) {
final int t = RandomInts.randomIntBetween(r, 0, 4);
final int t = RandomNumbers.randomIntBetween(r, 0, 4);
if (t == 0 && i < length - 1) {
// Make a surrogate pair
chars[i++] = (char) RandomInts.randomIntBetween(r, 0xd800, 0xdbff); // high
chars[i++] = (char) RandomInts.randomIntBetween(r, 0xdc00, 0xdfff); // low
chars[i++] = (char) RandomNumbers.randomIntBetween(r, 0xd800, 0xdbff); // high
chars[i++] = (char) RandomNumbers.randomIntBetween(r, 0xdc00, 0xdfff); // low
} else if (t <= 1) {
chars[i++] = (char) RandomInts.randomIntBetween(r, 0, 0x007f);
chars[i++] = (char) RandomNumbers.randomIntBetween(r, 0, 0x007f);
} else if (t == 2) {
chars[i++] = (char) RandomInts.randomIntBetween(r, 0x80, 0x07ff);
chars[i++] = (char) RandomNumbers.randomIntBetween(r, 0x80, 0x07ff);
} else if (t == 3) {
chars[i++] = (char) RandomInts.randomIntBetween(r, 0x800, 0xd7ff);
chars[i++] = (char) RandomNumbers.randomIntBetween(r, 0x800, 0xd7ff);
} else if (t == 4) {
chars[i++] = (char) RandomInts.randomIntBetween(r, 0xe000, 0xffff);
chars[i++] = (char) RandomNumbers.randomIntBetween(r, 0xe000, 0xffff);
}
}
return new String(chars);
}

@Override
public String ofCodePointsLength(Random r, int minCodePoints, int maxCodePoints) {
int length = RandomInts.randomIntBetween(r, minCodePoints, maxCodePoints);
int length = RandomNumbers.randomIntBetween(r, minCodePoints, maxCodePoints);
int [] chars = new int [length];
for (int i = 0; i < chars.length; i++) {
int v = RandomInts.randomIntBetween(r, 0, CODEPOINT_RANGE);
int v = RandomNumbers.randomIntBetween(r, 0, CODEPOINT_RANGE);
if (v >= Character.MIN_SURROGATE)
v += SURROGATE_RANGE;
chars[i] = v;
Expand All @@ -53,7 +53,7 @@ public String ofCodePointsLength(Random r, int minCodePoints, int maxCodePoints)
* @param maxUtf8Length Maximum UTF-8 representation length (inclusive).
*/
public String ofUtf8Length(Random r, int minUtf8Length, int maxUtf8Length) {
final int length = RandomInts.randomIntBetween(r, minUtf8Length, maxUtf8Length);
final int length = RandomNumbers.randomIntBetween(r, minUtf8Length, maxUtf8Length);
final char[] buffer = new char [length * 3];
int bytes = length;
int i = 0;
Expand All @@ -69,21 +69,21 @@ public String ofUtf8Length(Random r, int minUtf8Length, int maxUtf8Length) {
t = 0;
}
if (t == 0) {
buffer[i] = (char) RandomInts.randomIntBetween(r, 0, 0x7f);
buffer[i] = (char) RandomNumbers.randomIntBetween(r, 0, 0x7f);
bytes--;
} else if (1 == t) {
buffer[i] = (char) RandomInts.randomIntBetween(r, 0x80, 0x7ff);
buffer[i] = (char) RandomNumbers.randomIntBetween(r, 0x80, 0x7ff);
bytes -= 2;
} else if (2 == t) {
buffer[i] = (char) RandomInts.randomIntBetween(r, 0x800, 0xd7ff);
buffer[i] = (char) RandomNumbers.randomIntBetween(r, 0x800, 0xd7ff);
bytes -= 3;
} else if (3 == t) {
buffer[i] = (char) RandomInts.randomIntBetween(r, 0xe000, 0xffff);
buffer[i] = (char) RandomNumbers.randomIntBetween(r, 0xe000, 0xffff);
bytes -= 3;
} else if (4 == t) {
// Make a surrogate pair
buffer[i++] = (char) RandomInts.randomIntBetween(r, 0xd800, 0xdbff); // high
buffer[i] = (char) RandomInts.randomIntBetween(r, 0xdc00, 0xdfff); // low
buffer[i++] = (char) RandomNumbers.randomIntBetween(r, 0xd800, 0xdbff); // high
buffer[i] = (char) RandomNumbers.randomIntBetween(r, 0xdc00, 0xdfff); // low
bytes -= 4;
}
}
Expand Down
@@ -0,0 +1,61 @@
package com.carrotsearch.randomizedtesting;

import static org.junit.Assert.*;

import java.util.Random;

import org.junit.Test;

import com.carrotsearch.randomizedtesting.annotations.Repeat;
import com.carrotsearch.randomizedtesting.generators.RandomNumbers;

@Repeat(iterations = 100)
public class TestRandomNumbers extends RandomizedTest {
@Test
public void testRandomIntBetween() {
int max = Integer.MAX_VALUE;
int min = Integer.MIN_VALUE;

Random rnd = getRandom();
checkRandomInt(rnd, 1, 1);
checkRandomInt(rnd, 0, 100);
checkRandomInt(rnd, 0, max);
checkRandomInt(rnd, min, 0);
checkRandomInt(rnd, -1, max);
checkRandomInt(rnd, min, 1);
checkRandomInt(rnd, min, max);
}

@Test
public void testRandomLongBetween() {
long max = Long.MAX_VALUE;
long min = Long.MIN_VALUE;

Random rnd = getRandom();
checkRandomLong(rnd, 1, 1);
checkRandomLong(rnd, 0, 100);
checkRandomLong(rnd, 0, max);
checkRandomLong(rnd, min, 0);
checkRandomLong(rnd, -1, max);
checkRandomLong(rnd, min, 1);
checkRandomLong(rnd, min, max);
}

private void checkRandomInt(Random rnd, int min, int max) {
for (int i = 0; i < 100000; i++) {
int v = RandomNumbers.randomIntBetween(rnd, min, max);
if (v < min || v > max) {
fail(min + " " + max + ": " + v);
}
}
}

private void checkRandomLong(Random rnd, long min, long max) {
for (int i = 0; i < 100000; i++) {
long v = RandomNumbers.randomLongBetween(rnd, min, max);
if (v < min || v > max) {
fail(min + " " + max + ": " + v);
}
}
}
}

0 comments on commit bbb3434

Please sign in to comment.