New Rnd class.
This commit is contained in:
parent
850c075c0e
commit
f3907293c8
@ -16,442 +16,129 @@
|
||||
*/
|
||||
package com.l2jmobius.commons.util;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class Rnd
|
||||
{
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
* Thread-specific random number generator.<br>
|
||||
* Each is seeded with the thread ID, so the sequence of random numbers are unique between threads.
|
||||
*/
|
||||
public static final class NonAtomicRandom extends Random
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<>()
|
||||
{
|
||||
private volatile long _seed;
|
||||
|
||||
public NonAtomicRandom()
|
||||
{
|
||||
this(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
|
||||
public NonAtomicRandom(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
protected Random initialValue()
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
return new Random(System.nanoTime() + Thread.currentThread().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
protected static final class RandomContainer
|
||||
{
|
||||
private final Random _random;
|
||||
|
||||
protected RandomContainer(Random random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public final Random directRandom()
|
||||
{
|
||||
return _random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public final double get()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public final int get(int n)
|
||||
{
|
||||
return (int) (_random.nextDouble() * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public final int get(int min, int max)
|
||||
{
|
||||
return min + (int) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public final long get(long min, long max)
|
||||
{
|
||||
return min + (long) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
*/
|
||||
public final boolean nextBoolean()
|
||||
{
|
||||
return _random.nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
*/
|
||||
public final void nextBytes(byte[] array)
|
||||
{
|
||||
_random.nextBytes(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
*/
|
||||
public final double nextDouble()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
*/
|
||||
public final float nextFloat()
|
||||
{
|
||||
return _random.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public final double nextGaussian()
|
||||
{
|
||||
return _random.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public final int nextInt()
|
||||
{
|
||||
return _random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public final long nextLong()
|
||||
{
|
||||
return _random.nextLong();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
public enum RandomType
|
||||
{
|
||||
/**
|
||||
* For best random quality.
|
||||
* @see java.security.SecureRandom
|
||||
*/
|
||||
SECURE,
|
||||
|
||||
/**
|
||||
* For average random quality.
|
||||
* @see java.util.Random
|
||||
*/
|
||||
UNSECURE_ATOMIC,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Each thread has it`s own random instance.<br>
|
||||
* Provides best parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.ThreadLocalRandom
|
||||
*/
|
||||
UNSECURE_THREAD_LOCAL,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Provides much faster parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.NonAtomicRandom
|
||||
*/
|
||||
UNSECURE_VOLATILE
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using thread local ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is the fastest, never generates the same seed for 2 threads.<br>
|
||||
* Each thread has it`s own random instance.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
*/
|
||||
public static final class ThreadLocalRandom extends Random
|
||||
{
|
||||
private static final class Seed
|
||||
{
|
||||
long _seed;
|
||||
|
||||
Seed(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
final int next(int bits)
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
}
|
||||
|
||||
final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<Seed> _seedLocal;
|
||||
|
||||
public ThreadLocalRandom()
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ThreadLocalRandom(long seed)
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(seed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
{
|
||||
return _seedLocal.get().next(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
if (_seedLocal != null)
|
||||
{
|
||||
_seedLocal.get().setSeed(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long ADDEND = 0xBL;
|
||||
|
||||
private static final long MASK = (1L << 48) - 1;
|
||||
|
||||
private static final long MULTIPLIER = 0x5DEECE66DL;
|
||||
|
||||
private static final RandomContainer rnd = newInstance(RandomType.UNSECURE_THREAD_LOCAL);
|
||||
|
||||
protected static volatile long SEED_UNIQUIFIER = 8682522807148012L;
|
||||
|
||||
public static Random directRandom()
|
||||
{
|
||||
return rnd.directRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public static double get()
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public static int get(int n)
|
||||
{
|
||||
return rnd.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public static int get(int min, int max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public static long get(long min, long max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
public static RandomContainer newInstance(RandomType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UNSECURE_ATOMIC:
|
||||
{
|
||||
return new RandomContainer(new Random());
|
||||
}
|
||||
case UNSECURE_VOLATILE:
|
||||
{
|
||||
return new RandomContainer(new NonAtomicRandom());
|
||||
}
|
||||
case UNSECURE_THREAD_LOCAL:
|
||||
{
|
||||
return new RandomContainer(new ThreadLocalRandom());
|
||||
}
|
||||
case SECURE:
|
||||
{
|
||||
return new RandomContainer(new SecureRandom());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
* @return a random boolean value.
|
||||
*/
|
||||
public static boolean nextBoolean()
|
||||
{
|
||||
return rnd.nextBoolean();
|
||||
return RANDOM.get().nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
* Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array.
|
||||
* @param bytes the byte array to fill with random bytes.
|
||||
*/
|
||||
public static void nextBytes(byte[] array)
|
||||
public static void nextBytes(byte[] bytes)
|
||||
{
|
||||
rnd.nextBytes(array);
|
||||
RANDOM.get().nextBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
* @param bound (int)
|
||||
* @return a random int value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
public static int get(int bound)
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
return (int) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
* @param origin (int)
|
||||
* @param bound (int)
|
||||
* @return a random int value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static float nextFloat()
|
||||
public static int get(int origin, int bound)
|
||||
{
|
||||
return rnd.nextFloat();
|
||||
return origin + (int) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return rnd.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
* @return a random int value.
|
||||
*/
|
||||
public static int nextInt()
|
||||
{
|
||||
return rnd.nextInt();
|
||||
return RANDOM.get().nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* @return int
|
||||
* @see com.l2jmobius.commons.util.Rnd#get(int n)
|
||||
* @param bound (long)
|
||||
* @return a random long value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static int nextInt(int n)
|
||||
public static long get(long bound)
|
||||
{
|
||||
return get(n);
|
||||
return (long) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
* @param origin (long)
|
||||
* @param bound (long)
|
||||
* @return a random long value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static long get(long origin, long bound)
|
||||
{
|
||||
return origin + (long) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random long value.
|
||||
*/
|
||||
public static long nextLong()
|
||||
{
|
||||
return rnd.nextLong();
|
||||
return RANDOM.get().nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bound (double)
|
||||
* @return a random double value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double get(double bound)
|
||||
{
|
||||
return RANDOM.get().nextDouble() * bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param origin (double)
|
||||
* @param bound (double)
|
||||
* @return a random double value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static double get(double origin, double bound)
|
||||
{
|
||||
return origin + (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random double value between zero (inclusive) and one (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
{
|
||||
return RANDOM.get().nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the next random, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return RANDOM.get().nextGaussian();
|
||||
}
|
||||
}
|
||||
|
@ -16,442 +16,129 @@
|
||||
*/
|
||||
package com.l2jmobius.commons.util;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class Rnd
|
||||
{
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
* Thread-specific random number generator.<br>
|
||||
* Each is seeded with the thread ID, so the sequence of random numbers are unique between threads.
|
||||
*/
|
||||
public static final class NonAtomicRandom extends Random
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<>()
|
||||
{
|
||||
private volatile long _seed;
|
||||
|
||||
public NonAtomicRandom()
|
||||
{
|
||||
this(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
|
||||
public NonAtomicRandom(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
protected Random initialValue()
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
return new Random(System.nanoTime() + Thread.currentThread().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
protected static final class RandomContainer
|
||||
{
|
||||
private final Random _random;
|
||||
|
||||
protected RandomContainer(Random random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public final Random directRandom()
|
||||
{
|
||||
return _random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public final double get()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public final int get(int n)
|
||||
{
|
||||
return (int) (_random.nextDouble() * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public final int get(int min, int max)
|
||||
{
|
||||
return min + (int) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public final long get(long min, long max)
|
||||
{
|
||||
return min + (long) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
*/
|
||||
public final boolean nextBoolean()
|
||||
{
|
||||
return _random.nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
*/
|
||||
public final void nextBytes(byte[] array)
|
||||
{
|
||||
_random.nextBytes(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
*/
|
||||
public final double nextDouble()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
*/
|
||||
public final float nextFloat()
|
||||
{
|
||||
return _random.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public final double nextGaussian()
|
||||
{
|
||||
return _random.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public final int nextInt()
|
||||
{
|
||||
return _random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public final long nextLong()
|
||||
{
|
||||
return _random.nextLong();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
public enum RandomType
|
||||
{
|
||||
/**
|
||||
* For best random quality.
|
||||
* @see java.security.SecureRandom
|
||||
*/
|
||||
SECURE,
|
||||
|
||||
/**
|
||||
* For average random quality.
|
||||
* @see java.util.Random
|
||||
*/
|
||||
UNSECURE_ATOMIC,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Each thread has it`s own random instance.<br>
|
||||
* Provides best parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.ThreadLocalRandom
|
||||
*/
|
||||
UNSECURE_THREAD_LOCAL,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Provides much faster parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.NonAtomicRandom
|
||||
*/
|
||||
UNSECURE_VOLATILE
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using thread local ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is the fastest, never generates the same seed for 2 threads.<br>
|
||||
* Each thread has it`s own random instance.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
*/
|
||||
public static final class ThreadLocalRandom extends Random
|
||||
{
|
||||
private static final class Seed
|
||||
{
|
||||
long _seed;
|
||||
|
||||
Seed(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
final int next(int bits)
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
}
|
||||
|
||||
final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<Seed> _seedLocal;
|
||||
|
||||
public ThreadLocalRandom()
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ThreadLocalRandom(long seed)
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(seed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
{
|
||||
return _seedLocal.get().next(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
if (_seedLocal != null)
|
||||
{
|
||||
_seedLocal.get().setSeed(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long ADDEND = 0xBL;
|
||||
|
||||
private static final long MASK = (1L << 48) - 1;
|
||||
|
||||
private static final long MULTIPLIER = 0x5DEECE66DL;
|
||||
|
||||
private static final RandomContainer rnd = newInstance(RandomType.UNSECURE_THREAD_LOCAL);
|
||||
|
||||
protected static volatile long SEED_UNIQUIFIER = 8682522807148012L;
|
||||
|
||||
public static Random directRandom()
|
||||
{
|
||||
return rnd.directRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public static double get()
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public static int get(int n)
|
||||
{
|
||||
return rnd.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public static int get(int min, int max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public static long get(long min, long max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
public static RandomContainer newInstance(RandomType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UNSECURE_ATOMIC:
|
||||
{
|
||||
return new RandomContainer(new Random());
|
||||
}
|
||||
case UNSECURE_VOLATILE:
|
||||
{
|
||||
return new RandomContainer(new NonAtomicRandom());
|
||||
}
|
||||
case UNSECURE_THREAD_LOCAL:
|
||||
{
|
||||
return new RandomContainer(new ThreadLocalRandom());
|
||||
}
|
||||
case SECURE:
|
||||
{
|
||||
return new RandomContainer(new SecureRandom());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
* @return a random boolean value.
|
||||
*/
|
||||
public static boolean nextBoolean()
|
||||
{
|
||||
return rnd.nextBoolean();
|
||||
return RANDOM.get().nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
* Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array.
|
||||
* @param bytes the byte array to fill with random bytes.
|
||||
*/
|
||||
public static void nextBytes(byte[] array)
|
||||
public static void nextBytes(byte[] bytes)
|
||||
{
|
||||
rnd.nextBytes(array);
|
||||
RANDOM.get().nextBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
* @param bound (int)
|
||||
* @return a random int value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
public static int get(int bound)
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
return (int) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
* @param origin (int)
|
||||
* @param bound (int)
|
||||
* @return a random int value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static float nextFloat()
|
||||
public static int get(int origin, int bound)
|
||||
{
|
||||
return rnd.nextFloat();
|
||||
return origin + (int) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return rnd.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
* @return a random int value.
|
||||
*/
|
||||
public static int nextInt()
|
||||
{
|
||||
return rnd.nextInt();
|
||||
return RANDOM.get().nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* @return int
|
||||
* @see com.l2jmobius.commons.util.Rnd#get(int n)
|
||||
* @param bound (long)
|
||||
* @return a random long value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static int nextInt(int n)
|
||||
public static long get(long bound)
|
||||
{
|
||||
return get(n);
|
||||
return (long) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
* @param origin (long)
|
||||
* @param bound (long)
|
||||
* @return a random long value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static long get(long origin, long bound)
|
||||
{
|
||||
return origin + (long) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random long value.
|
||||
*/
|
||||
public static long nextLong()
|
||||
{
|
||||
return rnd.nextLong();
|
||||
return RANDOM.get().nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bound (double)
|
||||
* @return a random double value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double get(double bound)
|
||||
{
|
||||
return RANDOM.get().nextDouble() * bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param origin (double)
|
||||
* @param bound (double)
|
||||
* @return a random double value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static double get(double origin, double bound)
|
||||
{
|
||||
return origin + (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random double value between zero (inclusive) and one (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
{
|
||||
return RANDOM.get().nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the next random, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return RANDOM.get().nextGaussian();
|
||||
}
|
||||
}
|
||||
|
@ -16,442 +16,129 @@
|
||||
*/
|
||||
package com.l2jmobius.commons.util;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class Rnd
|
||||
{
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
* Thread-specific random number generator.<br>
|
||||
* Each is seeded with the thread ID, so the sequence of random numbers are unique between threads.
|
||||
*/
|
||||
public static final class NonAtomicRandom extends Random
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<>()
|
||||
{
|
||||
private volatile long _seed;
|
||||
|
||||
public NonAtomicRandom()
|
||||
{
|
||||
this(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
|
||||
public NonAtomicRandom(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
protected Random initialValue()
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
return new Random(System.nanoTime() + Thread.currentThread().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
protected static final class RandomContainer
|
||||
{
|
||||
private final Random _random;
|
||||
|
||||
protected RandomContainer(Random random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public final Random directRandom()
|
||||
{
|
||||
return _random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public final double get()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public final int get(int n)
|
||||
{
|
||||
return (int) (_random.nextDouble() * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public final int get(int min, int max)
|
||||
{
|
||||
return min + (int) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public final long get(long min, long max)
|
||||
{
|
||||
return min + (long) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
*/
|
||||
public final boolean nextBoolean()
|
||||
{
|
||||
return _random.nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
*/
|
||||
public final void nextBytes(byte[] array)
|
||||
{
|
||||
_random.nextBytes(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
*/
|
||||
public final double nextDouble()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
*/
|
||||
public final float nextFloat()
|
||||
{
|
||||
return _random.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public final double nextGaussian()
|
||||
{
|
||||
return _random.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public final int nextInt()
|
||||
{
|
||||
return _random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public final long nextLong()
|
||||
{
|
||||
return _random.nextLong();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
public enum RandomType
|
||||
{
|
||||
/**
|
||||
* For best random quality.
|
||||
* @see java.security.SecureRandom
|
||||
*/
|
||||
SECURE,
|
||||
|
||||
/**
|
||||
* For average random quality.
|
||||
* @see java.util.Random
|
||||
*/
|
||||
UNSECURE_ATOMIC,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Each thread has it`s own random instance.<br>
|
||||
* Provides best parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.ThreadLocalRandom
|
||||
*/
|
||||
UNSECURE_THREAD_LOCAL,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Provides much faster parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.NonAtomicRandom
|
||||
*/
|
||||
UNSECURE_VOLATILE
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using thread local ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is the fastest, never generates the same seed for 2 threads.<br>
|
||||
* Each thread has it`s own random instance.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
*/
|
||||
public static final class ThreadLocalRandom extends Random
|
||||
{
|
||||
private static final class Seed
|
||||
{
|
||||
long _seed;
|
||||
|
||||
Seed(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
final int next(int bits)
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
}
|
||||
|
||||
final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<Seed> _seedLocal;
|
||||
|
||||
public ThreadLocalRandom()
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ThreadLocalRandom(long seed)
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(seed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
{
|
||||
return _seedLocal.get().next(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
if (_seedLocal != null)
|
||||
{
|
||||
_seedLocal.get().setSeed(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long ADDEND = 0xBL;
|
||||
|
||||
private static final long MASK = (1L << 48) - 1;
|
||||
|
||||
private static final long MULTIPLIER = 0x5DEECE66DL;
|
||||
|
||||
private static final RandomContainer rnd = newInstance(RandomType.UNSECURE_THREAD_LOCAL);
|
||||
|
||||
protected static volatile long SEED_UNIQUIFIER = 8682522807148012L;
|
||||
|
||||
public static Random directRandom()
|
||||
{
|
||||
return rnd.directRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public static double get()
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public static int get(int n)
|
||||
{
|
||||
return rnd.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public static int get(int min, int max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public static long get(long min, long max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
public static RandomContainer newInstance(RandomType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UNSECURE_ATOMIC:
|
||||
{
|
||||
return new RandomContainer(new Random());
|
||||
}
|
||||
case UNSECURE_VOLATILE:
|
||||
{
|
||||
return new RandomContainer(new NonAtomicRandom());
|
||||
}
|
||||
case UNSECURE_THREAD_LOCAL:
|
||||
{
|
||||
return new RandomContainer(new ThreadLocalRandom());
|
||||
}
|
||||
case SECURE:
|
||||
{
|
||||
return new RandomContainer(new SecureRandom());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
* @return a random boolean value.
|
||||
*/
|
||||
public static boolean nextBoolean()
|
||||
{
|
||||
return rnd.nextBoolean();
|
||||
return RANDOM.get().nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
* Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array.
|
||||
* @param bytes the byte array to fill with random bytes.
|
||||
*/
|
||||
public static void nextBytes(byte[] array)
|
||||
public static void nextBytes(byte[] bytes)
|
||||
{
|
||||
rnd.nextBytes(array);
|
||||
RANDOM.get().nextBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
* @param bound (int)
|
||||
* @return a random int value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
public static int get(int bound)
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
return (int) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
* @param origin (int)
|
||||
* @param bound (int)
|
||||
* @return a random int value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static float nextFloat()
|
||||
public static int get(int origin, int bound)
|
||||
{
|
||||
return rnd.nextFloat();
|
||||
return origin + (int) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return rnd.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
* @return a random int value.
|
||||
*/
|
||||
public static int nextInt()
|
||||
{
|
||||
return rnd.nextInt();
|
||||
return RANDOM.get().nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* @return int
|
||||
* @see com.l2jmobius.commons.util.Rnd#get(int n)
|
||||
* @param bound (long)
|
||||
* @return a random long value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static int nextInt(int n)
|
||||
public static long get(long bound)
|
||||
{
|
||||
return get(n);
|
||||
return (long) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
* @param origin (long)
|
||||
* @param bound (long)
|
||||
* @return a random long value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static long get(long origin, long bound)
|
||||
{
|
||||
return origin + (long) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random long value.
|
||||
*/
|
||||
public static long nextLong()
|
||||
{
|
||||
return rnd.nextLong();
|
||||
return RANDOM.get().nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bound (double)
|
||||
* @return a random double value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double get(double bound)
|
||||
{
|
||||
return RANDOM.get().nextDouble() * bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param origin (double)
|
||||
* @param bound (double)
|
||||
* @return a random double value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static double get(double origin, double bound)
|
||||
{
|
||||
return origin + (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random double value between zero (inclusive) and one (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
{
|
||||
return RANDOM.get().nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the next random, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return RANDOM.get().nextGaussian();
|
||||
}
|
||||
}
|
||||
|
@ -16,442 +16,129 @@
|
||||
*/
|
||||
package com.l2jmobius.commons.util;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class Rnd
|
||||
{
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
* Thread-specific random number generator.<br>
|
||||
* Each is seeded with the thread ID, so the sequence of random numbers are unique between threads.
|
||||
*/
|
||||
public static final class NonAtomicRandom extends Random
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<>()
|
||||
{
|
||||
private volatile long _seed;
|
||||
|
||||
public NonAtomicRandom()
|
||||
{
|
||||
this(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
|
||||
public NonAtomicRandom(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
protected Random initialValue()
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
return new Random(System.nanoTime() + Thread.currentThread().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
protected static final class RandomContainer
|
||||
{
|
||||
private final Random _random;
|
||||
|
||||
protected RandomContainer(Random random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public final Random directRandom()
|
||||
{
|
||||
return _random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public final double get()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public final int get(int n)
|
||||
{
|
||||
return (int) (_random.nextDouble() * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public final int get(int min, int max)
|
||||
{
|
||||
return min + (int) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public final long get(long min, long max)
|
||||
{
|
||||
return min + (long) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
*/
|
||||
public final boolean nextBoolean()
|
||||
{
|
||||
return _random.nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
*/
|
||||
public final void nextBytes(byte[] array)
|
||||
{
|
||||
_random.nextBytes(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
*/
|
||||
public final double nextDouble()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
*/
|
||||
public final float nextFloat()
|
||||
{
|
||||
return _random.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public final double nextGaussian()
|
||||
{
|
||||
return _random.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public final int nextInt()
|
||||
{
|
||||
return _random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public final long nextLong()
|
||||
{
|
||||
return _random.nextLong();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
public enum RandomType
|
||||
{
|
||||
/**
|
||||
* For best random quality.
|
||||
* @see java.security.SecureRandom
|
||||
*/
|
||||
SECURE,
|
||||
|
||||
/**
|
||||
* For average random quality.
|
||||
* @see java.util.Random
|
||||
*/
|
||||
UNSECURE_ATOMIC,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Each thread has it`s own random instance.<br>
|
||||
* Provides best parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.ThreadLocalRandom
|
||||
*/
|
||||
UNSECURE_THREAD_LOCAL,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Provides much faster parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.NonAtomicRandom
|
||||
*/
|
||||
UNSECURE_VOLATILE
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using thread local ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is the fastest, never generates the same seed for 2 threads.<br>
|
||||
* Each thread has it`s own random instance.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
*/
|
||||
public static final class ThreadLocalRandom extends Random
|
||||
{
|
||||
private static final class Seed
|
||||
{
|
||||
long _seed;
|
||||
|
||||
Seed(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
final int next(int bits)
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
}
|
||||
|
||||
final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<Seed> _seedLocal;
|
||||
|
||||
public ThreadLocalRandom()
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ThreadLocalRandom(long seed)
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(seed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
{
|
||||
return _seedLocal.get().next(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
if (_seedLocal != null)
|
||||
{
|
||||
_seedLocal.get().setSeed(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long ADDEND = 0xBL;
|
||||
|
||||
private static final long MASK = (1L << 48) - 1;
|
||||
|
||||
private static final long MULTIPLIER = 0x5DEECE66DL;
|
||||
|
||||
private static final RandomContainer rnd = newInstance(RandomType.UNSECURE_THREAD_LOCAL);
|
||||
|
||||
protected static volatile long SEED_UNIQUIFIER = 8682522807148012L;
|
||||
|
||||
public static Random directRandom()
|
||||
{
|
||||
return rnd.directRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public static double get()
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public static int get(int n)
|
||||
{
|
||||
return rnd.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public static int get(int min, int max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public static long get(long min, long max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
public static RandomContainer newInstance(RandomType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UNSECURE_ATOMIC:
|
||||
{
|
||||
return new RandomContainer(new Random());
|
||||
}
|
||||
case UNSECURE_VOLATILE:
|
||||
{
|
||||
return new RandomContainer(new NonAtomicRandom());
|
||||
}
|
||||
case UNSECURE_THREAD_LOCAL:
|
||||
{
|
||||
return new RandomContainer(new ThreadLocalRandom());
|
||||
}
|
||||
case SECURE:
|
||||
{
|
||||
return new RandomContainer(new SecureRandom());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
* @return a random boolean value.
|
||||
*/
|
||||
public static boolean nextBoolean()
|
||||
{
|
||||
return rnd.nextBoolean();
|
||||
return RANDOM.get().nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
* Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array.
|
||||
* @param bytes the byte array to fill with random bytes.
|
||||
*/
|
||||
public static void nextBytes(byte[] array)
|
||||
public static void nextBytes(byte[] bytes)
|
||||
{
|
||||
rnd.nextBytes(array);
|
||||
RANDOM.get().nextBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
* @param bound (int)
|
||||
* @return a random int value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
public static int get(int bound)
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
return (int) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
* @param origin (int)
|
||||
* @param bound (int)
|
||||
* @return a random int value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static float nextFloat()
|
||||
public static int get(int origin, int bound)
|
||||
{
|
||||
return rnd.nextFloat();
|
||||
return origin + (int) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return rnd.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
* @return a random int value.
|
||||
*/
|
||||
public static int nextInt()
|
||||
{
|
||||
return rnd.nextInt();
|
||||
return RANDOM.get().nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* @return int
|
||||
* @see com.l2jmobius.commons.util.Rnd#get(int n)
|
||||
* @param bound (long)
|
||||
* @return a random long value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static int nextInt(int n)
|
||||
public static long get(long bound)
|
||||
{
|
||||
return get(n);
|
||||
return (long) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
* @param origin (long)
|
||||
* @param bound (long)
|
||||
* @return a random long value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static long get(long origin, long bound)
|
||||
{
|
||||
return origin + (long) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random long value.
|
||||
*/
|
||||
public static long nextLong()
|
||||
{
|
||||
return rnd.nextLong();
|
||||
return RANDOM.get().nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bound (double)
|
||||
* @return a random double value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double get(double bound)
|
||||
{
|
||||
return RANDOM.get().nextDouble() * bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param origin (double)
|
||||
* @param bound (double)
|
||||
* @return a random double value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static double get(double origin, double bound)
|
||||
{
|
||||
return origin + (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random double value between zero (inclusive) and one (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
{
|
||||
return RANDOM.get().nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the next random, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return RANDOM.get().nextGaussian();
|
||||
}
|
||||
}
|
||||
|
@ -16,442 +16,129 @@
|
||||
*/
|
||||
package com.l2jmobius.commons.util;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class Rnd
|
||||
{
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
* Thread-specific random number generator.<br>
|
||||
* Each is seeded with the thread ID, so the sequence of random numbers are unique between threads.
|
||||
*/
|
||||
public static final class NonAtomicRandom extends Random
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<>()
|
||||
{
|
||||
private volatile long _seed;
|
||||
|
||||
public NonAtomicRandom()
|
||||
{
|
||||
this(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
|
||||
public NonAtomicRandom(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
protected Random initialValue()
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
return new Random(System.nanoTime() + Thread.currentThread().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
protected static final class RandomContainer
|
||||
{
|
||||
private final Random _random;
|
||||
|
||||
protected RandomContainer(Random random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public final Random directRandom()
|
||||
{
|
||||
return _random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public final double get()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public final int get(int n)
|
||||
{
|
||||
return (int) (_random.nextDouble() * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public final int get(int min, int max)
|
||||
{
|
||||
return min + (int) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public final long get(long min, long max)
|
||||
{
|
||||
return min + (long) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
*/
|
||||
public final boolean nextBoolean()
|
||||
{
|
||||
return _random.nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
*/
|
||||
public final void nextBytes(byte[] array)
|
||||
{
|
||||
_random.nextBytes(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
*/
|
||||
public final double nextDouble()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
*/
|
||||
public final float nextFloat()
|
||||
{
|
||||
return _random.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public final double nextGaussian()
|
||||
{
|
||||
return _random.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public final int nextInt()
|
||||
{
|
||||
return _random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public final long nextLong()
|
||||
{
|
||||
return _random.nextLong();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
public enum RandomType
|
||||
{
|
||||
/**
|
||||
* For best random quality.
|
||||
* @see java.security.SecureRandom
|
||||
*/
|
||||
SECURE,
|
||||
|
||||
/**
|
||||
* For average random quality.
|
||||
* @see java.util.Random
|
||||
*/
|
||||
UNSECURE_ATOMIC,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Each thread has it`s own random instance.<br>
|
||||
* Provides best parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.ThreadLocalRandom
|
||||
*/
|
||||
UNSECURE_THREAD_LOCAL,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Provides much faster parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.NonAtomicRandom
|
||||
*/
|
||||
UNSECURE_VOLATILE
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using thread local ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is the fastest, never generates the same seed for 2 threads.<br>
|
||||
* Each thread has it`s own random instance.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
*/
|
||||
public static final class ThreadLocalRandom extends Random
|
||||
{
|
||||
private static final class Seed
|
||||
{
|
||||
long _seed;
|
||||
|
||||
Seed(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
final int next(int bits)
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
}
|
||||
|
||||
final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<Seed> _seedLocal;
|
||||
|
||||
public ThreadLocalRandom()
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ThreadLocalRandom(long seed)
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(seed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
{
|
||||
return _seedLocal.get().next(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
if (_seedLocal != null)
|
||||
{
|
||||
_seedLocal.get().setSeed(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long ADDEND = 0xBL;
|
||||
|
||||
private static final long MASK = (1L << 48) - 1;
|
||||
|
||||
private static final long MULTIPLIER = 0x5DEECE66DL;
|
||||
|
||||
private static final RandomContainer rnd = newInstance(RandomType.UNSECURE_THREAD_LOCAL);
|
||||
|
||||
protected static volatile long SEED_UNIQUIFIER = 8682522807148012L;
|
||||
|
||||
public static Random directRandom()
|
||||
{
|
||||
return rnd.directRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public static double get()
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public static int get(int n)
|
||||
{
|
||||
return rnd.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public static int get(int min, int max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public static long get(long min, long max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
public static RandomContainer newInstance(RandomType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UNSECURE_ATOMIC:
|
||||
{
|
||||
return new RandomContainer(new Random());
|
||||
}
|
||||
case UNSECURE_VOLATILE:
|
||||
{
|
||||
return new RandomContainer(new NonAtomicRandom());
|
||||
}
|
||||
case UNSECURE_THREAD_LOCAL:
|
||||
{
|
||||
return new RandomContainer(new ThreadLocalRandom());
|
||||
}
|
||||
case SECURE:
|
||||
{
|
||||
return new RandomContainer(new SecureRandom());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
* @return a random boolean value.
|
||||
*/
|
||||
public static boolean nextBoolean()
|
||||
{
|
||||
return rnd.nextBoolean();
|
||||
return RANDOM.get().nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
* Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array.
|
||||
* @param bytes the byte array to fill with random bytes.
|
||||
*/
|
||||
public static void nextBytes(byte[] array)
|
||||
public static void nextBytes(byte[] bytes)
|
||||
{
|
||||
rnd.nextBytes(array);
|
||||
RANDOM.get().nextBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
* @param bound (int)
|
||||
* @return a random int value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
public static int get(int bound)
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
return (int) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
* @param origin (int)
|
||||
* @param bound (int)
|
||||
* @return a random int value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static float nextFloat()
|
||||
public static int get(int origin, int bound)
|
||||
{
|
||||
return rnd.nextFloat();
|
||||
return origin + (int) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return rnd.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
* @return a random int value.
|
||||
*/
|
||||
public static int nextInt()
|
||||
{
|
||||
return rnd.nextInt();
|
||||
return RANDOM.get().nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* @return int
|
||||
* @see com.l2jmobius.commons.util.Rnd#get(int n)
|
||||
* @param bound (long)
|
||||
* @return a random long value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static int nextInt(int n)
|
||||
public static long get(long bound)
|
||||
{
|
||||
return get(n);
|
||||
return (long) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
* @param origin (long)
|
||||
* @param bound (long)
|
||||
* @return a random long value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static long get(long origin, long bound)
|
||||
{
|
||||
return origin + (long) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random long value.
|
||||
*/
|
||||
public static long nextLong()
|
||||
{
|
||||
return rnd.nextLong();
|
||||
return RANDOM.get().nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bound (double)
|
||||
* @return a random double value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double get(double bound)
|
||||
{
|
||||
return RANDOM.get().nextDouble() * bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param origin (double)
|
||||
* @param bound (double)
|
||||
* @return a random double value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static double get(double origin, double bound)
|
||||
{
|
||||
return origin + (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random double value between zero (inclusive) and one (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
{
|
||||
return RANDOM.get().nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the next random, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return RANDOM.get().nextGaussian();
|
||||
}
|
||||
}
|
||||
|
@ -16,442 +16,129 @@
|
||||
*/
|
||||
package com.l2jmobius.commons.util;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class Rnd
|
||||
{
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
* Thread-specific random number generator.<br>
|
||||
* Each is seeded with the thread ID, so the sequence of random numbers are unique between threads.
|
||||
*/
|
||||
public static final class NonAtomicRandom extends Random
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<>()
|
||||
{
|
||||
private volatile long _seed;
|
||||
|
||||
public NonAtomicRandom()
|
||||
{
|
||||
this(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
|
||||
public NonAtomicRandom(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
protected Random initialValue()
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
return new Random(System.nanoTime() + Thread.currentThread().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
protected static final class RandomContainer
|
||||
{
|
||||
private final Random _random;
|
||||
|
||||
protected RandomContainer(Random random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public final Random directRandom()
|
||||
{
|
||||
return _random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public final double get()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public final int get(int n)
|
||||
{
|
||||
return (int) (_random.nextDouble() * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public final int get(int min, int max)
|
||||
{
|
||||
return min + (int) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public final long get(long min, long max)
|
||||
{
|
||||
return min + (long) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
*/
|
||||
public final boolean nextBoolean()
|
||||
{
|
||||
return _random.nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
*/
|
||||
public final void nextBytes(byte[] array)
|
||||
{
|
||||
_random.nextBytes(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
*/
|
||||
public final double nextDouble()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
*/
|
||||
public final float nextFloat()
|
||||
{
|
||||
return _random.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public final double nextGaussian()
|
||||
{
|
||||
return _random.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public final int nextInt()
|
||||
{
|
||||
return _random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public final long nextLong()
|
||||
{
|
||||
return _random.nextLong();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
public enum RandomType
|
||||
{
|
||||
/**
|
||||
* For best random quality.
|
||||
* @see java.security.SecureRandom
|
||||
*/
|
||||
SECURE,
|
||||
|
||||
/**
|
||||
* For average random quality.
|
||||
* @see java.util.Random
|
||||
*/
|
||||
UNSECURE_ATOMIC,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Each thread has it`s own random instance.<br>
|
||||
* Provides best parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.ThreadLocalRandom
|
||||
*/
|
||||
UNSECURE_THREAD_LOCAL,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Provides much faster parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.NonAtomicRandom
|
||||
*/
|
||||
UNSECURE_VOLATILE
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using thread local ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is the fastest, never generates the same seed for 2 threads.<br>
|
||||
* Each thread has it`s own random instance.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
*/
|
||||
public static final class ThreadLocalRandom extends Random
|
||||
{
|
||||
private static final class Seed
|
||||
{
|
||||
long _seed;
|
||||
|
||||
Seed(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
final int next(int bits)
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
}
|
||||
|
||||
final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<Seed> _seedLocal;
|
||||
|
||||
public ThreadLocalRandom()
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ThreadLocalRandom(long seed)
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(seed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
{
|
||||
return _seedLocal.get().next(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
if (_seedLocal != null)
|
||||
{
|
||||
_seedLocal.get().setSeed(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long ADDEND = 0xBL;
|
||||
|
||||
private static final long MASK = (1L << 48) - 1;
|
||||
|
||||
private static final long MULTIPLIER = 0x5DEECE66DL;
|
||||
|
||||
private static final RandomContainer rnd = newInstance(RandomType.UNSECURE_THREAD_LOCAL);
|
||||
|
||||
protected static volatile long SEED_UNIQUIFIER = 8682522807148012L;
|
||||
|
||||
public static Random directRandom()
|
||||
{
|
||||
return rnd.directRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public static double get()
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public static int get(int n)
|
||||
{
|
||||
return rnd.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public static int get(int min, int max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public static long get(long min, long max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
public static RandomContainer newInstance(RandomType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UNSECURE_ATOMIC:
|
||||
{
|
||||
return new RandomContainer(new Random());
|
||||
}
|
||||
case UNSECURE_VOLATILE:
|
||||
{
|
||||
return new RandomContainer(new NonAtomicRandom());
|
||||
}
|
||||
case UNSECURE_THREAD_LOCAL:
|
||||
{
|
||||
return new RandomContainer(new ThreadLocalRandom());
|
||||
}
|
||||
case SECURE:
|
||||
{
|
||||
return new RandomContainer(new SecureRandom());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
* @return a random boolean value.
|
||||
*/
|
||||
public static boolean nextBoolean()
|
||||
{
|
||||
return rnd.nextBoolean();
|
||||
return RANDOM.get().nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
* Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array.
|
||||
* @param bytes the byte array to fill with random bytes.
|
||||
*/
|
||||
public static void nextBytes(byte[] array)
|
||||
public static void nextBytes(byte[] bytes)
|
||||
{
|
||||
rnd.nextBytes(array);
|
||||
RANDOM.get().nextBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
* @param bound (int)
|
||||
* @return a random int value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
public static int get(int bound)
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
return (int) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
* @param origin (int)
|
||||
* @param bound (int)
|
||||
* @return a random int value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static float nextFloat()
|
||||
public static int get(int origin, int bound)
|
||||
{
|
||||
return rnd.nextFloat();
|
||||
return origin + (int) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return rnd.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
* @return a random int value.
|
||||
*/
|
||||
public static int nextInt()
|
||||
{
|
||||
return rnd.nextInt();
|
||||
return RANDOM.get().nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* @return int
|
||||
* @see com.l2jmobius.commons.util.Rnd#get(int n)
|
||||
* @param bound (long)
|
||||
* @return a random long value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static int nextInt(int n)
|
||||
public static long get(long bound)
|
||||
{
|
||||
return get(n);
|
||||
return (long) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
* @param origin (long)
|
||||
* @param bound (long)
|
||||
* @return a random long value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static long get(long origin, long bound)
|
||||
{
|
||||
return origin + (long) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random long value.
|
||||
*/
|
||||
public static long nextLong()
|
||||
{
|
||||
return rnd.nextLong();
|
||||
return RANDOM.get().nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bound (double)
|
||||
* @return a random double value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double get(double bound)
|
||||
{
|
||||
return RANDOM.get().nextDouble() * bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param origin (double)
|
||||
* @param bound (double)
|
||||
* @return a random double value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static double get(double origin, double bound)
|
||||
{
|
||||
return origin + (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random double value between zero (inclusive) and one (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
{
|
||||
return RANDOM.get().nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the next random, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return RANDOM.get().nextGaussian();
|
||||
}
|
||||
}
|
||||
|
@ -16,464 +16,129 @@
|
||||
*/
|
||||
package com.l2jmobius.commons.util;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class Rnd
|
||||
{
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
* Thread-specific random number generator.<br>
|
||||
* Each is seeded with the thread ID, so the sequence of random numbers are unique between threads.
|
||||
*/
|
||||
public static final class NonAtomicRandom extends Random
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<Random>()
|
||||
{
|
||||
private volatile long _seed;
|
||||
|
||||
public NonAtomicRandom()
|
||||
{
|
||||
this(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
|
||||
public NonAtomicRandom(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
protected Random initialValue()
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
return new Random(System.nanoTime() + Thread.currentThread().getId());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return a random boolean value.
|
||||
*/
|
||||
public static boolean nextBoolean()
|
||||
{
|
||||
return RANDOM.get().nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array.
|
||||
* @param bytes the byte array to fill with random bytes.
|
||||
*/
|
||||
public static final class RandomContainer
|
||||
public static void nextBytes(byte[] bytes)
|
||||
{
|
||||
private final Random _random;
|
||||
|
||||
protected RandomContainer(Random random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public final Random directRandom()
|
||||
{
|
||||
return _random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
*/
|
||||
public final double get()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public final int get(int n)
|
||||
{
|
||||
return (int) (_random.nextDouble() * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public final int get(int min, int max)
|
||||
{
|
||||
return min + (int) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public final long get(long min, long max)
|
||||
{
|
||||
return min + (long) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
*/
|
||||
public final boolean nextBoolean()
|
||||
{
|
||||
return _random.nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
*/
|
||||
public final void nextBytes(byte[] array)
|
||||
{
|
||||
_random.nextBytes(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
*/
|
||||
public final double nextDouble()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
*/
|
||||
public final float nextFloat()
|
||||
{
|
||||
return _random.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public final double nextGaussian()
|
||||
{
|
||||
return _random.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public final int nextInt()
|
||||
{
|
||||
return _random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public final long nextLong()
|
||||
{
|
||||
return _random.nextLong();
|
||||
}
|
||||
RANDOM.get().nextBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* @param bound (int)
|
||||
* @return a random int value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public enum RandomType
|
||||
public static int get(int bound)
|
||||
{
|
||||
/**
|
||||
* For best random quality.
|
||||
* @see java.security.SecureRandom
|
||||
*/
|
||||
SECURE,
|
||||
|
||||
/**
|
||||
* For average random quality.
|
||||
* @see java.util.Random
|
||||
*/
|
||||
UNSECURE_ATOMIC,
|
||||
|
||||
/**
|
||||
* Each thread has it`s own random instance.<br>
|
||||
* Provides best parallel access speed.
|
||||
*/
|
||||
UNSECURE_THREAD_LOCAL,
|
||||
|
||||
/**
|
||||
* Provides much faster parallel access speed.
|
||||
*/
|
||||
UNSECURE_VOLATILE
|
||||
return (int) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using thread local ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is the fastest, never generates the same seed for 2 threads.<br>
|
||||
* Each thread has it`s own random instance.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
* @param origin (int)
|
||||
* @param bound (int)
|
||||
* @return a random int value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static final class ThreadLocalRandom extends Random
|
||||
public static int get(int origin, int bound)
|
||||
{
|
||||
private static final class Seed
|
||||
{
|
||||
long _seed;
|
||||
|
||||
Seed(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
final int next(int bits)
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
}
|
||||
|
||||
final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<Seed> _seedLocal;
|
||||
|
||||
public ThreadLocalRandom()
|
||||
{
|
||||
_seedLocal = new ThreadLocal<Seed>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ThreadLocalRandom(long seed)
|
||||
{
|
||||
_seedLocal = new ThreadLocal<Seed>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(seed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
{
|
||||
return _seedLocal.get().next(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
if (_seedLocal != null)
|
||||
{
|
||||
_seedLocal.get().setSeed(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long ADDEND = 0xBL;
|
||||
|
||||
private static final long MASK = (1L << 48) - 1;
|
||||
|
||||
private static final long MULTIPLIER = 0x5DEECE66DL;
|
||||
|
||||
private static final RandomContainer rnd = newInstance(RandomType.UNSECURE_THREAD_LOCAL);
|
||||
|
||||
protected static volatile long SEED_UNIQUIFIER = 8682522807148012L;
|
||||
|
||||
public static final Random directRandom()
|
||||
{
|
||||
return rnd.directRandom();
|
||||
return origin + (int) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @return a random int value.
|
||||
*/
|
||||
public static final double get()
|
||||
public static int nextInt()
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
return RANDOM.get().nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
* @param bound (long)
|
||||
* @return a random long value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static final int get(int n)
|
||||
public static long get(long bound)
|
||||
{
|
||||
return rnd.get(n);
|
||||
return (long) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
* @param origin (long)
|
||||
* @param bound (long)
|
||||
* @return a random long value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static final int get(int min, int max)
|
||||
public static long get(long origin, long bound)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
return origin + (long) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
* @return a random long value.
|
||||
*/
|
||||
public static final long get(long min, long max)
|
||||
public static long nextLong()
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
public static final RandomContainer newInstance(RandomType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UNSECURE_ATOMIC:
|
||||
{
|
||||
return new RandomContainer(new Random());
|
||||
}
|
||||
case UNSECURE_VOLATILE:
|
||||
{
|
||||
return new RandomContainer(new NonAtomicRandom());
|
||||
}
|
||||
case UNSECURE_THREAD_LOCAL:
|
||||
{
|
||||
return new RandomContainer(new ThreadLocalRandom());
|
||||
}
|
||||
case SECURE:
|
||||
{
|
||||
return new RandomContainer(new SecureRandom());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
return RANDOM.get().nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
* @param bound (double)
|
||||
* @return a random double value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static final boolean nextBoolean()
|
||||
public static double get(double bound)
|
||||
{
|
||||
return rnd.nextBoolean();
|
||||
return RANDOM.get().nextDouble() * bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
* @param origin (double)
|
||||
* @param bound (double)
|
||||
* @return a random double value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static final void nextBytes(byte[] array)
|
||||
public static double get(double origin, double bound)
|
||||
{
|
||||
rnd.nextBytes(array);
|
||||
return origin + (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
* @return a random double value between zero (inclusive) and one (exclusive).
|
||||
*/
|
||||
public static final double nextDouble()
|
||||
public static double nextDouble()
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
return RANDOM.get().nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
* @return the next random, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.
|
||||
*/
|
||||
public static final float nextFloat()
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return rnd.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public static final double nextGaussian()
|
||||
{
|
||||
return rnd.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public static final int nextInt()
|
||||
{
|
||||
return rnd.nextInt();
|
||||
}
|
||||
|
||||
public static final int nextInt(int n)
|
||||
{
|
||||
return get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public static final long nextLong()
|
||||
{
|
||||
return rnd.nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a randomly selected element taken from the given list.
|
||||
* @param <T> type of list elements.
|
||||
* @param list a list.
|
||||
* @return a randomly selected element.
|
||||
*/
|
||||
public static final <T> T get(List<T> list)
|
||||
{
|
||||
if ((list == null) || (list.size() == 0))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return list.get(get(list.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a randomly selected element taken from the given array.
|
||||
* @param <T> type of array elements.
|
||||
* @param array an array.
|
||||
* @return a randomly selected element.
|
||||
*/
|
||||
public static final <T> T get(T[] array)
|
||||
{
|
||||
if ((array == null) || (array.length == 0))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return array[get(array.length)];
|
||||
return RANDOM.get().nextGaussian();
|
||||
}
|
||||
}
|
||||
|
@ -16,442 +16,129 @@
|
||||
*/
|
||||
package com.l2jmobius.commons.util;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class Rnd
|
||||
{
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
* Thread-specific random number generator.<br>
|
||||
* Each is seeded with the thread ID, so the sequence of random numbers are unique between threads.
|
||||
*/
|
||||
public static final class NonAtomicRandom extends Random
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<>()
|
||||
{
|
||||
private volatile long _seed;
|
||||
|
||||
public NonAtomicRandom()
|
||||
{
|
||||
this(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
|
||||
public NonAtomicRandom(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
protected Random initialValue()
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
return new Random(System.nanoTime() + Thread.currentThread().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
protected static final class RandomContainer
|
||||
{
|
||||
private final Random _random;
|
||||
|
||||
protected RandomContainer(Random random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public final Random directRandom()
|
||||
{
|
||||
return _random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public final double get()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public final int get(int n)
|
||||
{
|
||||
return (int) (_random.nextDouble() * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public final int get(int min, int max)
|
||||
{
|
||||
return min + (int) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public final long get(long min, long max)
|
||||
{
|
||||
return min + (long) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
*/
|
||||
public final boolean nextBoolean()
|
||||
{
|
||||
return _random.nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
*/
|
||||
public final void nextBytes(byte[] array)
|
||||
{
|
||||
_random.nextBytes(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
*/
|
||||
public final double nextDouble()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
*/
|
||||
public final float nextFloat()
|
||||
{
|
||||
return _random.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public final double nextGaussian()
|
||||
{
|
||||
return _random.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public final int nextInt()
|
||||
{
|
||||
return _random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public final long nextLong()
|
||||
{
|
||||
return _random.nextLong();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
public enum RandomType
|
||||
{
|
||||
/**
|
||||
* For best random quality.
|
||||
* @see java.security.SecureRandom
|
||||
*/
|
||||
SECURE,
|
||||
|
||||
/**
|
||||
* For average random quality.
|
||||
* @see java.util.Random
|
||||
*/
|
||||
UNSECURE_ATOMIC,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Each thread has it`s own random instance.<br>
|
||||
* Provides best parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.ThreadLocalRandom
|
||||
*/
|
||||
UNSECURE_THREAD_LOCAL,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Provides much faster parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.NonAtomicRandom
|
||||
*/
|
||||
UNSECURE_VOLATILE
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using thread local ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is the fastest, never generates the same seed for 2 threads.<br>
|
||||
* Each thread has it`s own random instance.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
*/
|
||||
public static final class ThreadLocalRandom extends Random
|
||||
{
|
||||
private static final class Seed
|
||||
{
|
||||
long _seed;
|
||||
|
||||
Seed(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
final int next(int bits)
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
}
|
||||
|
||||
final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<Seed> _seedLocal;
|
||||
|
||||
public ThreadLocalRandom()
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ThreadLocalRandom(long seed)
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(seed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
{
|
||||
return _seedLocal.get().next(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
if (_seedLocal != null)
|
||||
{
|
||||
_seedLocal.get().setSeed(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long ADDEND = 0xBL;
|
||||
|
||||
private static final long MASK = (1L << 48) - 1;
|
||||
|
||||
private static final long MULTIPLIER = 0x5DEECE66DL;
|
||||
|
||||
private static final RandomContainer rnd = newInstance(RandomType.UNSECURE_THREAD_LOCAL);
|
||||
|
||||
protected static volatile long SEED_UNIQUIFIER = 8682522807148012L;
|
||||
|
||||
public static Random directRandom()
|
||||
{
|
||||
return rnd.directRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public static double get()
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public static int get(int n)
|
||||
{
|
||||
return rnd.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public static int get(int min, int max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public static long get(long min, long max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
public static RandomContainer newInstance(RandomType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UNSECURE_ATOMIC:
|
||||
{
|
||||
return new RandomContainer(new Random());
|
||||
}
|
||||
case UNSECURE_VOLATILE:
|
||||
{
|
||||
return new RandomContainer(new NonAtomicRandom());
|
||||
}
|
||||
case UNSECURE_THREAD_LOCAL:
|
||||
{
|
||||
return new RandomContainer(new ThreadLocalRandom());
|
||||
}
|
||||
case SECURE:
|
||||
{
|
||||
return new RandomContainer(new SecureRandom());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
* @return a random boolean value.
|
||||
*/
|
||||
public static boolean nextBoolean()
|
||||
{
|
||||
return rnd.nextBoolean();
|
||||
return RANDOM.get().nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
* Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array.
|
||||
* @param bytes the byte array to fill with random bytes.
|
||||
*/
|
||||
public static void nextBytes(byte[] array)
|
||||
public static void nextBytes(byte[] bytes)
|
||||
{
|
||||
rnd.nextBytes(array);
|
||||
RANDOM.get().nextBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
* @param bound (int)
|
||||
* @return a random int value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
public static int get(int bound)
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
return (int) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
* @param origin (int)
|
||||
* @param bound (int)
|
||||
* @return a random int value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static float nextFloat()
|
||||
public static int get(int origin, int bound)
|
||||
{
|
||||
return rnd.nextFloat();
|
||||
return origin + (int) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return rnd.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
* @return a random int value.
|
||||
*/
|
||||
public static int nextInt()
|
||||
{
|
||||
return rnd.nextInt();
|
||||
return RANDOM.get().nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* @return int
|
||||
* @see com.l2jmobius.commons.util.Rnd#get(int n)
|
||||
* @param bound (long)
|
||||
* @return a random long value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static int nextInt(int n)
|
||||
public static long get(long bound)
|
||||
{
|
||||
return get(n);
|
||||
return (long) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
* @param origin (long)
|
||||
* @param bound (long)
|
||||
* @return a random long value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static long get(long origin, long bound)
|
||||
{
|
||||
return origin + (long) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random long value.
|
||||
*/
|
||||
public static long nextLong()
|
||||
{
|
||||
return rnd.nextLong();
|
||||
return RANDOM.get().nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bound (double)
|
||||
* @return a random double value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double get(double bound)
|
||||
{
|
||||
return RANDOM.get().nextDouble() * bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param origin (double)
|
||||
* @param bound (double)
|
||||
* @return a random double value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static double get(double origin, double bound)
|
||||
{
|
||||
return origin + (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random double value between zero (inclusive) and one (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
{
|
||||
return RANDOM.get().nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the next random, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return RANDOM.get().nextGaussian();
|
||||
}
|
||||
}
|
||||
|
@ -16,442 +16,129 @@
|
||||
*/
|
||||
package com.l2jmobius.commons.util;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class Rnd
|
||||
{
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
* Thread-specific random number generator.<br>
|
||||
* Each is seeded with the thread ID, so the sequence of random numbers are unique between threads.
|
||||
*/
|
||||
public static final class NonAtomicRandom extends Random
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<>()
|
||||
{
|
||||
private volatile long _seed;
|
||||
|
||||
public NonAtomicRandom()
|
||||
{
|
||||
this(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
|
||||
public NonAtomicRandom(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
protected Random initialValue()
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
return new Random(System.nanoTime() + Thread.currentThread().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
protected static final class RandomContainer
|
||||
{
|
||||
private final Random _random;
|
||||
|
||||
protected RandomContainer(Random random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public final Random directRandom()
|
||||
{
|
||||
return _random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public final double get()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public final int get(int n)
|
||||
{
|
||||
return (int) (_random.nextDouble() * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public final int get(int min, int max)
|
||||
{
|
||||
return min + (int) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public final long get(long min, long max)
|
||||
{
|
||||
return min + (long) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
*/
|
||||
public final boolean nextBoolean()
|
||||
{
|
||||
return _random.nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
*/
|
||||
public final void nextBytes(byte[] array)
|
||||
{
|
||||
_random.nextBytes(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
*/
|
||||
public final double nextDouble()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
*/
|
||||
public final float nextFloat()
|
||||
{
|
||||
return _random.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public final double nextGaussian()
|
||||
{
|
||||
return _random.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public final int nextInt()
|
||||
{
|
||||
return _random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public final long nextLong()
|
||||
{
|
||||
return _random.nextLong();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
public enum RandomType
|
||||
{
|
||||
/**
|
||||
* For best random quality.
|
||||
* @see java.security.SecureRandom
|
||||
*/
|
||||
SECURE,
|
||||
|
||||
/**
|
||||
* For average random quality.
|
||||
* @see java.util.Random
|
||||
*/
|
||||
UNSECURE_ATOMIC,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Each thread has it`s own random instance.<br>
|
||||
* Provides best parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.ThreadLocalRandom
|
||||
*/
|
||||
UNSECURE_THREAD_LOCAL,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Provides much faster parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.NonAtomicRandom
|
||||
*/
|
||||
UNSECURE_VOLATILE
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using thread local ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is the fastest, never generates the same seed for 2 threads.<br>
|
||||
* Each thread has it`s own random instance.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
*/
|
||||
public static final class ThreadLocalRandom extends Random
|
||||
{
|
||||
private static final class Seed
|
||||
{
|
||||
long _seed;
|
||||
|
||||
Seed(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
final int next(int bits)
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
}
|
||||
|
||||
final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<Seed> _seedLocal;
|
||||
|
||||
public ThreadLocalRandom()
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ThreadLocalRandom(long seed)
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(seed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
{
|
||||
return _seedLocal.get().next(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
if (_seedLocal != null)
|
||||
{
|
||||
_seedLocal.get().setSeed(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long ADDEND = 0xBL;
|
||||
|
||||
private static final long MASK = (1L << 48) - 1;
|
||||
|
||||
private static final long MULTIPLIER = 0x5DEECE66DL;
|
||||
|
||||
private static final RandomContainer rnd = newInstance(RandomType.UNSECURE_THREAD_LOCAL);
|
||||
|
||||
protected static volatile long SEED_UNIQUIFIER = 8682522807148012L;
|
||||
|
||||
public static Random directRandom()
|
||||
{
|
||||
return rnd.directRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public static double get()
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public static int get(int n)
|
||||
{
|
||||
return rnd.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public static int get(int min, int max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public static long get(long min, long max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
public static RandomContainer newInstance(RandomType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UNSECURE_ATOMIC:
|
||||
{
|
||||
return new RandomContainer(new Random());
|
||||
}
|
||||
case UNSECURE_VOLATILE:
|
||||
{
|
||||
return new RandomContainer(new NonAtomicRandom());
|
||||
}
|
||||
case UNSECURE_THREAD_LOCAL:
|
||||
{
|
||||
return new RandomContainer(new ThreadLocalRandom());
|
||||
}
|
||||
case SECURE:
|
||||
{
|
||||
return new RandomContainer(new SecureRandom());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
* @return a random boolean value.
|
||||
*/
|
||||
public static boolean nextBoolean()
|
||||
{
|
||||
return rnd.nextBoolean();
|
||||
return RANDOM.get().nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
* Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array.
|
||||
* @param bytes the byte array to fill with random bytes.
|
||||
*/
|
||||
public static void nextBytes(byte[] array)
|
||||
public static void nextBytes(byte[] bytes)
|
||||
{
|
||||
rnd.nextBytes(array);
|
||||
RANDOM.get().nextBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
* @param bound (int)
|
||||
* @return a random int value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
public static int get(int bound)
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
return (int) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
* @param origin (int)
|
||||
* @param bound (int)
|
||||
* @return a random int value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static float nextFloat()
|
||||
public static int get(int origin, int bound)
|
||||
{
|
||||
return rnd.nextFloat();
|
||||
return origin + (int) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return rnd.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
* @return a random int value.
|
||||
*/
|
||||
public static int nextInt()
|
||||
{
|
||||
return rnd.nextInt();
|
||||
return RANDOM.get().nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* @return int
|
||||
* @see com.l2jmobius.commons.util.Rnd#get(int n)
|
||||
* @param bound (long)
|
||||
* @return a random long value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static int nextInt(int n)
|
||||
public static long get(long bound)
|
||||
{
|
||||
return get(n);
|
||||
return (long) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
* @param origin (long)
|
||||
* @param bound (long)
|
||||
* @return a random long value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static long get(long origin, long bound)
|
||||
{
|
||||
return origin + (long) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random long value.
|
||||
*/
|
||||
public static long nextLong()
|
||||
{
|
||||
return rnd.nextLong();
|
||||
return RANDOM.get().nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bound (double)
|
||||
* @return a random double value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double get(double bound)
|
||||
{
|
||||
return RANDOM.get().nextDouble() * bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param origin (double)
|
||||
* @param bound (double)
|
||||
* @return a random double value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static double get(double origin, double bound)
|
||||
{
|
||||
return origin + (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random double value between zero (inclusive) and one (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
{
|
||||
return RANDOM.get().nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the next random, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return RANDOM.get().nextGaussian();
|
||||
}
|
||||
}
|
||||
|
@ -16,442 +16,129 @@
|
||||
*/
|
||||
package com.l2jmobius.commons.util;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class Rnd
|
||||
{
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
* Thread-specific random number generator.<br>
|
||||
* Each is seeded with the thread ID, so the sequence of random numbers are unique between threads.
|
||||
*/
|
||||
public static final class NonAtomicRandom extends Random
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<>()
|
||||
{
|
||||
private volatile long _seed;
|
||||
|
||||
public NonAtomicRandom()
|
||||
{
|
||||
this(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
|
||||
public NonAtomicRandom(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
protected Random initialValue()
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
return new Random(System.nanoTime() + Thread.currentThread().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
protected static final class RandomContainer
|
||||
{
|
||||
private final Random _random;
|
||||
|
||||
protected RandomContainer(Random random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public final Random directRandom()
|
||||
{
|
||||
return _random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public final double get()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public final int get(int n)
|
||||
{
|
||||
return (int) (_random.nextDouble() * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public final int get(int min, int max)
|
||||
{
|
||||
return min + (int) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public final long get(long min, long max)
|
||||
{
|
||||
return min + (long) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
*/
|
||||
public final boolean nextBoolean()
|
||||
{
|
||||
return _random.nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
*/
|
||||
public final void nextBytes(byte[] array)
|
||||
{
|
||||
_random.nextBytes(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
*/
|
||||
public final double nextDouble()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
*/
|
||||
public final float nextFloat()
|
||||
{
|
||||
return _random.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public final double nextGaussian()
|
||||
{
|
||||
return _random.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public final int nextInt()
|
||||
{
|
||||
return _random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public final long nextLong()
|
||||
{
|
||||
return _random.nextLong();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
public enum RandomType
|
||||
{
|
||||
/**
|
||||
* For best random quality.
|
||||
* @see java.security.SecureRandom
|
||||
*/
|
||||
SECURE,
|
||||
|
||||
/**
|
||||
* For average random quality.
|
||||
* @see java.util.Random
|
||||
*/
|
||||
UNSECURE_ATOMIC,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Each thread has it`s own random instance.<br>
|
||||
* Provides best parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.ThreadLocalRandom
|
||||
*/
|
||||
UNSECURE_THREAD_LOCAL,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Provides much faster parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.NonAtomicRandom
|
||||
*/
|
||||
UNSECURE_VOLATILE
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using thread local ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is the fastest, never generates the same seed for 2 threads.<br>
|
||||
* Each thread has it`s own random instance.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
*/
|
||||
public static final class ThreadLocalRandom extends Random
|
||||
{
|
||||
private static final class Seed
|
||||
{
|
||||
long _seed;
|
||||
|
||||
Seed(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
final int next(int bits)
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
}
|
||||
|
||||
final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<Seed> _seedLocal;
|
||||
|
||||
public ThreadLocalRandom()
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ThreadLocalRandom(long seed)
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(seed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
{
|
||||
return _seedLocal.get().next(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
if (_seedLocal != null)
|
||||
{
|
||||
_seedLocal.get().setSeed(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long ADDEND = 0xBL;
|
||||
|
||||
private static final long MASK = (1L << 48) - 1;
|
||||
|
||||
private static final long MULTIPLIER = 0x5DEECE66DL;
|
||||
|
||||
private static final RandomContainer rnd = newInstance(RandomType.UNSECURE_THREAD_LOCAL);
|
||||
|
||||
protected static volatile long SEED_UNIQUIFIER = 8682522807148012L;
|
||||
|
||||
public static Random directRandom()
|
||||
{
|
||||
return rnd.directRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public static double get()
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public static int get(int n)
|
||||
{
|
||||
return rnd.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public static int get(int min, int max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public static long get(long min, long max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
public static RandomContainer newInstance(RandomType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UNSECURE_ATOMIC:
|
||||
{
|
||||
return new RandomContainer(new Random());
|
||||
}
|
||||
case UNSECURE_VOLATILE:
|
||||
{
|
||||
return new RandomContainer(new NonAtomicRandom());
|
||||
}
|
||||
case UNSECURE_THREAD_LOCAL:
|
||||
{
|
||||
return new RandomContainer(new ThreadLocalRandom());
|
||||
}
|
||||
case SECURE:
|
||||
{
|
||||
return new RandomContainer(new SecureRandom());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
* @return a random boolean value.
|
||||
*/
|
||||
public static boolean nextBoolean()
|
||||
{
|
||||
return rnd.nextBoolean();
|
||||
return RANDOM.get().nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
* Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array.
|
||||
* @param bytes the byte array to fill with random bytes.
|
||||
*/
|
||||
public static void nextBytes(byte[] array)
|
||||
public static void nextBytes(byte[] bytes)
|
||||
{
|
||||
rnd.nextBytes(array);
|
||||
RANDOM.get().nextBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
* @param bound (int)
|
||||
* @return a random int value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
public static int get(int bound)
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
return (int) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
* @param origin (int)
|
||||
* @param bound (int)
|
||||
* @return a random int value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static float nextFloat()
|
||||
public static int get(int origin, int bound)
|
||||
{
|
||||
return rnd.nextFloat();
|
||||
return origin + (int) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return rnd.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
* @return a random int value.
|
||||
*/
|
||||
public static int nextInt()
|
||||
{
|
||||
return rnd.nextInt();
|
||||
return RANDOM.get().nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* @return int
|
||||
* @see com.l2jmobius.commons.util.Rnd#get(int n)
|
||||
* @param bound (long)
|
||||
* @return a random long value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static int nextInt(int n)
|
||||
public static long get(long bound)
|
||||
{
|
||||
return get(n);
|
||||
return (long) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
* @param origin (long)
|
||||
* @param bound (long)
|
||||
* @return a random long value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static long get(long origin, long bound)
|
||||
{
|
||||
return origin + (long) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random long value.
|
||||
*/
|
||||
public static long nextLong()
|
||||
{
|
||||
return rnd.nextLong();
|
||||
return RANDOM.get().nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bound (double)
|
||||
* @return a random double value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double get(double bound)
|
||||
{
|
||||
return RANDOM.get().nextDouble() * bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param origin (double)
|
||||
* @param bound (double)
|
||||
* @return a random double value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static double get(double origin, double bound)
|
||||
{
|
||||
return origin + (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random double value between zero (inclusive) and one (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
{
|
||||
return RANDOM.get().nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the next random, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return RANDOM.get().nextGaussian();
|
||||
}
|
||||
}
|
||||
|
@ -16,442 +16,129 @@
|
||||
*/
|
||||
package com.l2jmobius.commons.util;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class Rnd
|
||||
{
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
* Thread-specific random number generator.<br>
|
||||
* Each is seeded with the thread ID, so the sequence of random numbers are unique between threads.
|
||||
*/
|
||||
public static final class NonAtomicRandom extends Random
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<>()
|
||||
{
|
||||
private volatile long _seed;
|
||||
|
||||
public NonAtomicRandom()
|
||||
{
|
||||
this(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
|
||||
public NonAtomicRandom(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
protected Random initialValue()
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
return new Random(System.nanoTime() + Thread.currentThread().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
protected static final class RandomContainer
|
||||
{
|
||||
private final Random _random;
|
||||
|
||||
protected RandomContainer(Random random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public final Random directRandom()
|
||||
{
|
||||
return _random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public final double get()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public final int get(int n)
|
||||
{
|
||||
return (int) (_random.nextDouble() * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public final int get(int min, int max)
|
||||
{
|
||||
return min + (int) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public final long get(long min, long max)
|
||||
{
|
||||
return min + (long) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
*/
|
||||
public final boolean nextBoolean()
|
||||
{
|
||||
return _random.nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
*/
|
||||
public final void nextBytes(byte[] array)
|
||||
{
|
||||
_random.nextBytes(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
*/
|
||||
public final double nextDouble()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
*/
|
||||
public final float nextFloat()
|
||||
{
|
||||
return _random.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public final double nextGaussian()
|
||||
{
|
||||
return _random.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public final int nextInt()
|
||||
{
|
||||
return _random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public final long nextLong()
|
||||
{
|
||||
return _random.nextLong();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
public enum RandomType
|
||||
{
|
||||
/**
|
||||
* For best random quality.
|
||||
* @see java.security.SecureRandom
|
||||
*/
|
||||
SECURE,
|
||||
|
||||
/**
|
||||
* For average random quality.
|
||||
* @see java.util.Random
|
||||
*/
|
||||
UNSECURE_ATOMIC,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Each thread has it`s own random instance.<br>
|
||||
* Provides best parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.ThreadLocalRandom
|
||||
*/
|
||||
UNSECURE_THREAD_LOCAL,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Provides much faster parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.NonAtomicRandom
|
||||
*/
|
||||
UNSECURE_VOLATILE
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using thread local ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is the fastest, never generates the same seed for 2 threads.<br>
|
||||
* Each thread has it`s own random instance.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
*/
|
||||
public static final class ThreadLocalRandom extends Random
|
||||
{
|
||||
private static final class Seed
|
||||
{
|
||||
long _seed;
|
||||
|
||||
Seed(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
final int next(int bits)
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
}
|
||||
|
||||
final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<Seed> _seedLocal;
|
||||
|
||||
public ThreadLocalRandom()
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ThreadLocalRandom(long seed)
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(seed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
{
|
||||
return _seedLocal.get().next(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
if (_seedLocal != null)
|
||||
{
|
||||
_seedLocal.get().setSeed(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long ADDEND = 0xBL;
|
||||
|
||||
private static final long MASK = (1L << 48) - 1;
|
||||
|
||||
private static final long MULTIPLIER = 0x5DEECE66DL;
|
||||
|
||||
private static final RandomContainer rnd = newInstance(RandomType.UNSECURE_THREAD_LOCAL);
|
||||
|
||||
protected static volatile long SEED_UNIQUIFIER = 8682522807148012L;
|
||||
|
||||
public static Random directRandom()
|
||||
{
|
||||
return rnd.directRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public static double get()
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public static int get(int n)
|
||||
{
|
||||
return rnd.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public static int get(int min, int max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public static long get(long min, long max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
public static RandomContainer newInstance(RandomType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UNSECURE_ATOMIC:
|
||||
{
|
||||
return new RandomContainer(new Random());
|
||||
}
|
||||
case UNSECURE_VOLATILE:
|
||||
{
|
||||
return new RandomContainer(new NonAtomicRandom());
|
||||
}
|
||||
case UNSECURE_THREAD_LOCAL:
|
||||
{
|
||||
return new RandomContainer(new ThreadLocalRandom());
|
||||
}
|
||||
case SECURE:
|
||||
{
|
||||
return new RandomContainer(new SecureRandom());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
* @return a random boolean value.
|
||||
*/
|
||||
public static boolean nextBoolean()
|
||||
{
|
||||
return rnd.nextBoolean();
|
||||
return RANDOM.get().nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
* Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array.
|
||||
* @param bytes the byte array to fill with random bytes.
|
||||
*/
|
||||
public static void nextBytes(byte[] array)
|
||||
public static void nextBytes(byte[] bytes)
|
||||
{
|
||||
rnd.nextBytes(array);
|
||||
RANDOM.get().nextBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
* @param bound (int)
|
||||
* @return a random int value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
public static int get(int bound)
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
return (int) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
* @param origin (int)
|
||||
* @param bound (int)
|
||||
* @return a random int value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static float nextFloat()
|
||||
public static int get(int origin, int bound)
|
||||
{
|
||||
return rnd.nextFloat();
|
||||
return origin + (int) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return rnd.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
* @return a random int value.
|
||||
*/
|
||||
public static int nextInt()
|
||||
{
|
||||
return rnd.nextInt();
|
||||
return RANDOM.get().nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* @return int
|
||||
* @see com.l2jmobius.commons.util.Rnd#get(int n)
|
||||
* @param bound (long)
|
||||
* @return a random long value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static int nextInt(int n)
|
||||
public static long get(long bound)
|
||||
{
|
||||
return get(n);
|
||||
return (long) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
* @param origin (long)
|
||||
* @param bound (long)
|
||||
* @return a random long value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static long get(long origin, long bound)
|
||||
{
|
||||
return origin + (long) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random long value.
|
||||
*/
|
||||
public static long nextLong()
|
||||
{
|
||||
return rnd.nextLong();
|
||||
return RANDOM.get().nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bound (double)
|
||||
* @return a random double value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double get(double bound)
|
||||
{
|
||||
return RANDOM.get().nextDouble() * bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param origin (double)
|
||||
* @param bound (double)
|
||||
* @return a random double value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static double get(double origin, double bound)
|
||||
{
|
||||
return origin + (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random double value between zero (inclusive) and one (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
{
|
||||
return RANDOM.get().nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the next random, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return RANDOM.get().nextGaussian();
|
||||
}
|
||||
}
|
||||
|
@ -16,442 +16,129 @@
|
||||
*/
|
||||
package com.l2jmobius.commons.util;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class Rnd
|
||||
{
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
* Thread-specific random number generator.<br>
|
||||
* Each is seeded with the thread ID, so the sequence of random numbers are unique between threads.
|
||||
*/
|
||||
public static final class NonAtomicRandom extends Random
|
||||
private static ThreadLocal<Random> RANDOM = new ThreadLocal<>()
|
||||
{
|
||||
private volatile long _seed;
|
||||
|
||||
public NonAtomicRandom()
|
||||
{
|
||||
this(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
|
||||
public NonAtomicRandom(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
protected Random initialValue()
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
return new Random(System.nanoTime() + Thread.currentThread().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
protected static final class RandomContainer
|
||||
{
|
||||
private final Random _random;
|
||||
|
||||
protected RandomContainer(Random random)
|
||||
{
|
||||
_random = random;
|
||||
}
|
||||
|
||||
public final Random directRandom()
|
||||
{
|
||||
return _random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public final double get()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public final int get(int n)
|
||||
{
|
||||
return (int) (_random.nextDouble() * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public final int get(int min, int max)
|
||||
{
|
||||
return min + (int) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public final long get(long min, long max)
|
||||
{
|
||||
return min + (long) (_random.nextDouble() * ((max - min) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
*/
|
||||
public final boolean nextBoolean()
|
||||
{
|
||||
return _random.nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
*/
|
||||
public final void nextBytes(byte[] array)
|
||||
{
|
||||
_random.nextBytes(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
*/
|
||||
public final double nextDouble()
|
||||
{
|
||||
return _random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
*/
|
||||
public final float nextFloat()
|
||||
{
|
||||
return _random.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public final double nextGaussian()
|
||||
{
|
||||
return _random.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
*/
|
||||
public final int nextInt()
|
||||
{
|
||||
return _random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
*/
|
||||
public final long nextLong()
|
||||
{
|
||||
return _random.nextLong();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Forsaiken
|
||||
*/
|
||||
public enum RandomType
|
||||
{
|
||||
/**
|
||||
* For best random quality.
|
||||
* @see java.security.SecureRandom
|
||||
*/
|
||||
SECURE,
|
||||
|
||||
/**
|
||||
* For average random quality.
|
||||
* @see java.util.Random
|
||||
*/
|
||||
UNSECURE_ATOMIC,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Each thread has it`s own random instance.<br>
|
||||
* Provides best parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.ThreadLocalRandom
|
||||
*/
|
||||
UNSECURE_THREAD_LOCAL,
|
||||
|
||||
/**
|
||||
* Like {@link com.l2jmobius.commons.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
|
||||
* Provides much faster parallel access speed.
|
||||
* @see com.l2jmobius.commons.util.Rnd.NonAtomicRandom
|
||||
*/
|
||||
UNSECURE_VOLATILE
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends {@link java.util.Random} but do not compare and store atomically.<br>
|
||||
* Instead it`s using thread local ensure reading and storing the whole 64bit seed chunk.<br>
|
||||
* This implementation is the fastest, never generates the same seed for 2 threads.<br>
|
||||
* Each thread has it`s own random instance.
|
||||
* @author Forsaiken
|
||||
* @see java.util.Random
|
||||
*/
|
||||
public static final class ThreadLocalRandom extends Random
|
||||
{
|
||||
private static final class Seed
|
||||
{
|
||||
long _seed;
|
||||
|
||||
Seed(long seed)
|
||||
{
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
final int next(int bits)
|
||||
{
|
||||
return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
|
||||
}
|
||||
|
||||
final void setSeed(long seed)
|
||||
{
|
||||
_seed = (seed ^ MULTIPLIER) & MASK;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<Seed> _seedLocal;
|
||||
|
||||
public ThreadLocalRandom()
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(++SEED_UNIQUIFIER + System.nanoTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ThreadLocalRandom(long seed)
|
||||
{
|
||||
_seedLocal = new ThreadLocal<>()
|
||||
{
|
||||
@Override
|
||||
public final Seed initialValue()
|
||||
{
|
||||
return new Seed(seed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int next(int bits)
|
||||
{
|
||||
return _seedLocal.get().next(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSeed(long seed)
|
||||
{
|
||||
if (_seedLocal != null)
|
||||
{
|
||||
_seedLocal.get().setSeed(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long ADDEND = 0xBL;
|
||||
|
||||
private static final long MASK = (1L << 48) - 1;
|
||||
|
||||
private static final long MULTIPLIER = 0x5DEECE66DL;
|
||||
|
||||
private static final RandomContainer rnd = newInstance(RandomType.UNSECURE_THREAD_LOCAL);
|
||||
|
||||
protected static volatile long SEED_UNIQUIFIER = 8682522807148012L;
|
||||
|
||||
public static Random directRandom()
|
||||
{
|
||||
return rnd.directRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see com.l2jmobius.commons.util.Rnd#nextDouble()
|
||||
*/
|
||||
public static double get()
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from 0(inclusive) to n(exclusive)
|
||||
* @param n The superior limit (exclusive)
|
||||
* @return A random integer number from 0 to n-1
|
||||
*/
|
||||
public static int get(int n)
|
||||
{
|
||||
return rnd.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random integer number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random integer number from min to max
|
||||
*/
|
||||
public static int get(int min, int max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random long number from min(inclusive) to max(inclusive)
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @return A random long number from min to max
|
||||
*/
|
||||
public static long get(long min, long max)
|
||||
{
|
||||
return rnd.get(min, max);
|
||||
}
|
||||
|
||||
public static RandomContainer newInstance(RandomType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case UNSECURE_ATOMIC:
|
||||
{
|
||||
return new RandomContainer(new Random());
|
||||
}
|
||||
case UNSECURE_VOLATILE:
|
||||
{
|
||||
return new RandomContainer(new NonAtomicRandom());
|
||||
}
|
||||
case UNSECURE_THREAD_LOCAL:
|
||||
{
|
||||
return new RandomContainer(new ThreadLocalRandom());
|
||||
}
|
||||
case SECURE:
|
||||
{
|
||||
return new RandomContainer(new SecureRandom());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random boolean state (true or false)
|
||||
* @return A random boolean state (true or false)
|
||||
* @see java.util.Random#nextBoolean()
|
||||
* @return a random boolean value.
|
||||
*/
|
||||
public static boolean nextBoolean()
|
||||
{
|
||||
return rnd.nextBoolean();
|
||||
return RANDOM.get().nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given array with random byte numbers from Byte.MIN_VALUE(inclusive) to Byte.MAX_VALUE(inclusive)
|
||||
* @param array The array to be filled with random byte numbers
|
||||
* @see java.util.Random#nextBytes(byte[] bytes)
|
||||
* Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array.
|
||||
* @param bytes the byte array to fill with random bytes.
|
||||
*/
|
||||
public static void nextBytes(byte[] array)
|
||||
public static void nextBytes(byte[] bytes)
|
||||
{
|
||||
rnd.nextBytes(array);
|
||||
RANDOM.get().nextBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double number from 0 to 1
|
||||
* @return A random double number from 0 to 1
|
||||
* @see java.util.Random#nextDouble()
|
||||
* @param bound (int)
|
||||
* @return a random int value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
public static int get(int bound)
|
||||
{
|
||||
return rnd.nextDouble();
|
||||
return (int) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float number from 0 to 1
|
||||
* @return A random integer number from 0 to 1
|
||||
* @see java.util.Random#nextFloat()
|
||||
* @param origin (int)
|
||||
* @param bound (int)
|
||||
* @return a random int value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static float nextFloat()
|
||||
public static int get(int origin, int bound)
|
||||
{
|
||||
return rnd.nextFloat();
|
||||
return origin + (int) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random gaussian double number from 0 to 1
|
||||
* @return A random gaussian double number from 0 to 1
|
||||
* @see java.util.Random#nextGaussian()
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return rnd.nextGaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random integer number from Integer.MIN_VALUE(inclusive) to Integer.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Integer.MIN_VALUE to Integer.MAX_VALUE
|
||||
* @see java.util.Random#nextInt()
|
||||
* @return a random int value.
|
||||
*/
|
||||
public static int nextInt()
|
||||
{
|
||||
return rnd.nextInt();
|
||||
return RANDOM.get().nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* @return int
|
||||
* @see com.l2jmobius.commons.util.Rnd#get(int n)
|
||||
* @param bound (long)
|
||||
* @return a random long value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static int nextInt(int n)
|
||||
public static long get(long bound)
|
||||
{
|
||||
return get(n);
|
||||
return (long) (RANDOM.get().nextDouble() * bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random long number from Long.MIN_VALUE(inclusive) to Long.MAX_VALUE(inclusive)
|
||||
* @return A random integer number from Long.MIN_VALUE to Long.MAX_VALUE
|
||||
* @see java.util.Random#nextLong()
|
||||
* @param origin (long)
|
||||
* @param bound (long)
|
||||
* @return a random long value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static long get(long origin, long bound)
|
||||
{
|
||||
return origin + (long) (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random long value.
|
||||
*/
|
||||
public static long nextLong()
|
||||
{
|
||||
return rnd.nextLong();
|
||||
return RANDOM.get().nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bound (double)
|
||||
* @return a random double value between zero (inclusive) and the specified bound (exclusive).
|
||||
*/
|
||||
public static double get(double bound)
|
||||
{
|
||||
return RANDOM.get().nextDouble() * bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param origin (double)
|
||||
* @param bound (double)
|
||||
* @return a random double value between the specified origin (inclusive) and the specified bound (inclusive).
|
||||
*/
|
||||
public static double get(double origin, double bound)
|
||||
{
|
||||
return origin + (((bound - origin) + 1) * RANDOM.get().nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random double value between zero (inclusive) and one (exclusive).
|
||||
*/
|
||||
public static double nextDouble()
|
||||
{
|
||||
return RANDOM.get().nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the next random, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.
|
||||
*/
|
||||
public static double nextGaussian()
|
||||
{
|
||||
return RANDOM.get().nextGaussian();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user