NativeSeedType.java
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.commons.rng.simple.internal;
- import org.apache.commons.rng.core.util.NumberFactory;
- /**
- * The native seed type. Contains values for all native seed types and methods
- * to convert supported seed types to the native seed type.
- *
- * <p>Valid native seed types are:</p>
- * <ul>
- * <li>{@code Integer}</li>
- * <li>{@code Long}</li>
- * <li>{@code int[]}</li>
- * <li>{@code long[]}</li>
- * </ul>
- *
- * <p>Valid types for seed conversion are:</p>
- * <ul>
- * <li>{@code Integer} (or {@code int})</li>
- * <li>{@code Long} (or {@code long})</li>
- * <li>{@code int[]}</li>
- * <li>{@code long[]}</li>
- * <li>{@code byte[]}</li>
- * </ul>
- *
- * @since 1.3
- */
- public enum NativeSeedType {
- /** The seed type is {@code Integer}. */
- INT(Integer.class, 4) {
- @Override
- public Integer createSeed(int size, int from, int to) {
- return SeedFactory.createInt();
- }
- @Override
- protected Integer convert(Integer seed, int size) {
- return seed;
- }
- @Override
- protected Integer convert(Long seed, int size) {
- return Conversions.long2Int(seed);
- }
- @Override
- protected Integer convert(int[] seed, int size) {
- return Conversions.intArray2Int(seed);
- }
- @Override
- protected Integer convert(long[] seed, int size) {
- return Conversions.longArray2Int(seed);
- }
- @Override
- protected Integer convert(byte[] seed, int size) {
- return Conversions.byteArray2Int(seed);
- }
- },
- /** The seed type is {@code Long}. */
- LONG(Long.class, 8) {
- @Override
- public Long createSeed(int size, int from, int to) {
- return SeedFactory.createLong();
- }
- @Override
- protected Long convert(Integer seed, int size) {
- return Conversions.int2Long(seed);
- }
- @Override
- protected Long convert(Long seed, int size) {
- return seed;
- }
- @Override
- protected Long convert(int[] seed, int size) {
- return Conversions.intArray2Long(seed);
- }
- @Override
- protected Long convert(long[] seed, int size) {
- return Conversions.longArray2Long(seed);
- }
- @Override
- protected Long convert(byte[] seed, int size) {
- return Conversions.byteArray2Long(seed);
- }
- },
- /** The seed type is {@code int[]}. */
- INT_ARRAY(int[].class, 4) {
- @Override
- public int[] createSeed(int size, int from, int to) {
- // Limit the number of calls to the synchronized method. The generator
- // will support self-seeding.
- return SeedFactory.createIntArray(Math.min(size, RANDOM_SEED_ARRAY_SIZE),
- from, to);
- }
- @Override
- protected int[] convert(Integer seed, int size) {
- return Conversions.int2IntArray(seed, size);
- }
- @Override
- protected int[] convert(Long seed, int size) {
- return Conversions.long2IntArray(seed, size);
- }
- @Override
- protected int[] convert(int[] seed, int size) {
- return seed;
- }
- @Override
- protected int[] convert(long[] seed, int size) {
- // Avoid zero filling seeds that are too short
- return Conversions.longArray2IntArray(seed,
- Math.min(size, Conversions.intSizeFromLongSize(seed.length)));
- }
- @Override
- protected int[] convert(byte[] seed, int size) {
- // Avoid zero filling seeds that are too short
- return Conversions.byteArray2IntArray(seed,
- Math.min(size, Conversions.intSizeFromByteSize(seed.length)));
- }
- },
- /** The seed type is {@code long[]}. */
- LONG_ARRAY(long[].class, 8) {
- @Override
- public long[] createSeed(int size, int from, int to) {
- // Limit the number of calls to the synchronized method. The generator
- // will support self-seeding.
- return SeedFactory.createLongArray(Math.min(size, RANDOM_SEED_ARRAY_SIZE),
- from, to);
- }
- @Override
- protected long[] convert(Integer seed, int size) {
- return Conversions.int2LongArray(seed, size);
- }
- @Override
- protected long[] convert(Long seed, int size) {
- return Conversions.long2LongArray(seed, size);
- }
- @Override
- protected long[] convert(int[] seed, int size) {
- // Avoid zero filling seeds that are too short
- return Conversions.intArray2LongArray(seed,
- Math.min(size, Conversions.longSizeFromIntSize(seed.length)));
- }
- @Override
- protected long[] convert(long[] seed, int size) {
- return seed;
- }
- @Override
- protected long[] convert(byte[] seed, int size) {
- // Avoid zero filling seeds that are too short
- return Conversions.byteArray2LongArray(seed,
- Math.min(size, Conversions.longSizeFromByteSize(seed.length)));
- }
- };
- /** Error message for unrecognized seed types. */
- private static final String UNRECOGNISED_SEED = "Unrecognized seed type: ";
- /** Maximum length of the seed array (for creating array seeds). */
- private static final int RANDOM_SEED_ARRAY_SIZE = 128;
- /** Define the class type of the native seed. */
- private final Class<?> type;
- /**
- * Define the number of bytes required to represent the native seed. If the type is
- * an array then this represents the size of a single value of the type.
- */
- private final int bytes;
- /**
- * Instantiates a new native seed type.
- *
- * @param type Define the class type of the native seed.
- * @param bytes Define the number of bytes required to represent the native seed.
- */
- NativeSeedType(Class<?> type, int bytes) {
- this.type = type;
- this.bytes = bytes;
- }
- /**
- * Gets the class type of the native seed.
- *
- * @return the type
- */
- public Class<?> getType() {
- return type;
- }
- /**
- * Gets the number of bytes required to represent the native seed type. If the type is
- * an array then this represents the size of a single value of the type.
- *
- * @return the number of bytes
- */
- public int getBytes() {
- return bytes;
- }
- /**
- * Creates the seed. The output seed type is determined by the native seed type. If the
- * output is an array the required size of the array can be specified.
- *
- * @param size The size of the seed (array types only).
- * @return the seed
- */
- public Object createSeed(int size) {
- // Maintain behaviour since 1.3 to ensure position [0] of array seeds is non-zero.
- return createSeed(size, 0, Math.min(size, 1));
- }
- /**
- * Creates the seed. The output seed type is determined by the native seed type. If
- * the output is an array the required size of the array can be specified and a
- * sub-range that must not be all-zero.
- *
- * @param size The size of the seed (array types only).
- * @param from The start of the not all-zero sub-range (inclusive; array types only).
- * @param to The end of the not all-zero sub-range (exclusive; array types only).
- * @return the seed
- * @throws IndexOutOfBoundsException if the sub-range is out of bounds
- * @since 1.5
- */
- public abstract Object createSeed(int size, int from, int to);
- /**
- * Converts the input seed from any of the supported seed types to the native seed type.
- * If the output is an array the required size of the array can be specified.
- *
- * @param seed Input seed.
- * @param size The size of the output seed (array types only).
- * @return the native seed.
- * @throws UnsupportedOperationException if the {@code seed} type is invalid.
- */
- public Object convertSeed(Object seed,
- int size) {
- // Convert to native type.
- // Each method must be overridden by specific implementations.
- if (seed instanceof Integer) {
- return convert((Integer) seed, size);
- } else if (seed instanceof Long) {
- return convert((Long) seed, size);
- } else if (seed instanceof int[]) {
- return convert((int[]) seed, size);
- } else if (seed instanceof long[]) {
- return convert((long[]) seed, size);
- } else if (seed instanceof byte[]) {
- return convert((byte[]) seed, size);
- }
- throw new UnsupportedOperationException(unrecognizedSeedMessage(seed));
- }
- /**
- * Convert the input {@code Integer} seed to the native seed type.
- *
- * @param seed Input seed.
- * @param size The size of the output seed (array types only).
- * @return the native seed.
- */
- protected abstract Object convert(Integer seed, int size);
- /**
- * Convert the input {@code Long} seed to the native seed type.
- *
- * @param seed Input seed.
- * @param size The size of the output seed (array types only).
- * @return the native seed.
- */
- protected abstract Object convert(Long seed, int size);
- /**
- * Convert the input {@code int[]} seed to the native seed type.
- *
- * @param seed Input seed.
- * @param size The size of the output seed (array types only).
- * @return the native seed.
- */
- protected abstract Object convert(int[] seed, int size);
- /**
- * Convert the input {@code long[]} seed to the native seed type.
- *
- * @param seed Input seed.
- * @param size The size of the output seed (array types only).
- * @return the native seed.
- */
- protected abstract Object convert(long[] seed, int size);
- /**
- * Convert the input {@code byte[]} seed to the native seed type.
- *
- * @param seed Input seed.
- * @param size The size of the output seed (array types only).
- * @return the native seed.
- */
- protected abstract Object convert(byte[] seed, int size);
- /**
- * Converts the input seed from any of the supported seed types to bytes.
- *
- * @param seed Input seed.
- * @return the seed bytes.
- * @throws UnsupportedOperationException if the {@code seed} type is invalid.
- */
- public static byte[] convertSeedToBytes(Object seed) {
- if (seed instanceof Integer) {
- return NumberFactory.makeByteArray((Integer) seed);
- } else if (seed instanceof Long) {
- return NumberFactory.makeByteArray((Long) seed);
- } else if (seed instanceof int[]) {
- return NumberFactory.makeByteArray((int[]) seed);
- } else if (seed instanceof long[]) {
- return NumberFactory.makeByteArray((long[]) seed);
- } else if (seed instanceof byte[]) {
- return (byte[]) seed;
- }
- throw new UnsupportedOperationException(unrecognizedSeedMessage(seed));
- }
- /**
- * Create an unrecognized seed message. This will add the class type of the seed.
- *
- * @param seed the seed
- * @return the message
- */
- private static String unrecognizedSeedMessage(Object seed) {
- return UNRECOGNISED_SEED + ((seed == null) ? "null" : seed.getClass().getName());
- }
- }