/** * */ package vroom.common.utilities.ssj; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import umontreal.iro.lecuyer.rng.MRG32k3a; import umontreal.iro.lecuyer.rng.RandomStream; import umontreal.iro.lecuyer.rng.RandomStreamManager; /** * The class <code>RuntimeBaseRandomStreamManager</code> is a replacement of {@link RandomStreamManager} that is based * on a mapping between streams and current {@link ThreadGroup}. The idea is to maintain in a central place all the * random streams of the JVM and ensure that each {@link ThreadGroup} has only access to its own * {@linkplain RandomStream random streams}. * <p> * Creation date: Oct 8, 2010 - 5:03:28 PM * * @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los Andes</a>-<a * href="http://copa.uniandes.edu.co">Copa</a> <a href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a * href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp">SLP</a> * @version 1.0 */ public class SingletonRandomStreamManager { private static final SingletonRandomStreamManager INSTANCE = new SingletonRandomStreamManager(); private final Map<ThreadGroup, Map<String, RandomStream>> mStreams; /** * @return the singleton instance */ public static SingletonRandomStreamManager getInstance() { return INSTANCE; } private SingletonRandomStreamManager() { mStreams = new HashMap<ThreadGroup, Map<String, RandomStream>>(); } /** * @return the streams defined for the current thread group */ private Map<String, RandomStream> getCurrentThreadGroupStreams() { ThreadGroup cur = Thread.currentThread().getThreadGroup(); Map<String, RandomStream> streams; if (mStreams.containsKey(cur)) { streams = mStreams.get(cur); } else { streams = new HashMap<String, RandomStream>(); mStreams.put(cur, streams); } return streams; } /** * Adds the given stream to the internal list of this random stream manager and returns the added stream. * <p> * Any previous stream associated with the same key will be discarded * </p> * * @param key * a unique key to identify this stream within this {@link ThreadGroup} * @param stream * the {@link RandomStream} to be added * @return the newly added stream. */ public RandomStream add(String key, RandomStream stream) { getCurrentThreadGroupStreams().put(key, stream); return stream; } /** * Adds a {@link MRG32k3a} random stream for the current {@link ThreadGroup} and the given <code>key</code>. * * @param key * a unique key to identify this stream within this {@link ThreadGroup} * @param name * a name for the {@link RandomStream} * @param seeds * seeds for the {@link MRG32k3a} random stream, if <code>null</code> the default value will be used (see * {@link MRG32k3a#setPackageSeed(long[])}) * @return the stream that was added */ public MRG32k3a addMRG32k3a(String key, String name, long[] seeds) { MRG32k3a stream = new MRG32k3a(name); if (seeds != null) { stream.setSeed(seeds); } add(key, stream); return stream; } /** * Removes all the streams from the internal list of this random stream manager. */ public void clear() { getCurrentThreadGroupStreams().clear(); } /** * Returns an unmodifiable list containing all the random streams in this random stream manager. * * @return */ public List<RandomStream> getStreams() { return new ArrayList<RandomStream>(getCurrentThreadGroupStreams().values()); } /** * Access a specific random stream * * @param key * a unique key that identify the desired stream * @return */ public RandomStream getStream(String key) { return getCurrentThreadGroupStreams().get(key); } /** * Removes the given stream from the internal list of this random stream manager. * * @param key * the key for which the random stream has to be removed * @return */ public boolean remove(String key) { return getCurrentThreadGroupStreams().remove(key) != null; } /** * Forwards to the resetNextSubstream methods of all streams in the list. */ public void resetNextSubstream() { for (RandomStream stream : getCurrentThreadGroupStreams().values()) { stream.resetNextSubstream(); } } /** * Forwards to the resetStartStream methods of all streams in the list. */ public void resetStartStream() { for (RandomStream stream : getCurrentThreadGroupStreams().values()) { stream.resetStartStream(); } } /** * Forwards to the resetStartSubstream methods of all streams in the list. */ public void resetStartSubstream() { for (RandomStream stream : getCurrentThreadGroupStreams().values()) { stream.resetStartSubstream(); } } }