123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- /*
- * Copyright (C) 2004-2015 L2J Server
- *
- * This file is part of L2J Server.
- *
- * L2J Server is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * L2J Server is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- package com.l2jserver.util;
- import java.security.SecureRandom;
- import java.util.Random;
- /**
- * @author Forsaiken
- */
- 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
- */
- public static final class NonAtomicRandom extends Random
- {
- private static final long serialVersionUID = 1L;
- private volatile long _seed;
-
- public NonAtomicRandom()
- {
- this(++SEED_UNIQUIFIER + System.nanoTime());
- }
-
- public NonAtomicRandom(final long seed)
- {
- setSeed(seed);
- }
-
- @Override
- public final int next(final int bits)
- {
- return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
- }
-
- @Override
- public final void setSeed(final long seed)
- {
- _seed = (seed ^ MULTIPLIER) & MASK;
- }
- }
-
- /**
- * @author Forsaiken
- */
- protected static final class RandomContainer
- {
- private final Random _random;
-
- protected RandomContainer(final 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.l2jserver.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(final 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(final int min, final 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(final long min, final 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(final 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 static enum RandomType
- {
- /**
- * For best random quality.
- * @see java.security.SecureRandom
- */
- SECURE,
-
- /**
- * For average random quality.
- * @see java.util.Random
- */
- UNSECURE_ATOMIC,
-
- /**
- * Like {@link com.l2jserver.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
- * Each thread has it`s own random instance.<br>
- * Provides best parallel access speed.
- * @see com.l2jserver.util.Rnd.ThreadLocalRandom
- */
- UNSECURE_THREAD_LOCAL,
-
- /**
- * Like {@link com.l2jserver.util.Rnd.RandomType#UNSECURE_ATOMIC}.<br>
- * Provides much faster parallel access speed.
- * @see com.l2jserver.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(final long seed)
- {
- setSeed(seed);
- }
-
- final int next(final int bits)
- {
- return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
- }
-
- final void setSeed(final long seed)
- {
- _seed = (seed ^ MULTIPLIER) & MASK;
- }
- }
-
- private static final long serialVersionUID = 1L;
- 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(final long seed)
- {
- _seedLocal = new ThreadLocal<Seed>()
- {
- @Override
- public final Seed initialValue()
- {
- return new Seed(seed);
- }
- };
- }
-
- @Override
- public final int next(final int bits)
- {
- return _seedLocal.get().next(bits);
- }
-
- @Override
- public final void setSeed(final 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();
- }
-
- /**
- * Get a random double number from 0 to 1
- * @return A random double number from 0 to 1
- * @see com.l2jserver.util.Rnd#nextDouble()
- */
- public static final 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 final int get(final 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 final int get(final int min, final 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 final long get(final long min, final long max)
- {
- return rnd.get(min, max);
- }
-
- public static final RandomContainer newInstance(final 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()
- */
- public static final boolean nextBoolean()
- {
- return rnd.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 static final void nextBytes(final byte[] array)
- {
- rnd.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 static final double nextDouble()
- {
- return rnd.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 static final float nextFloat()
- {
- 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();
- }
-
- /**
- * @param n
- * @return
- * @see com.l2jserver.util.Rnd#get(int n)
- */
- public static final int nextInt(final 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();
- }
- }
|