1 package org.opentrafficsim.core.perception; 2 3 import java.util.Collections; 4 import java.util.Map; 5 import java.util.Set; 6 import java.util.WeakHashMap; 7 8 import org.djunits.value.vdouble.scalar.Duration; 9 import org.djunits.value.vdouble.scalar.Time; 10 11 import nl.tudelft.simulation.dsol.experiment.Replication; 12 import nl.tudelft.simulation.dsol.simtime.SimTimeDoubleUnit; 13 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface; 14 15 /** 16 * History manager with automatic garbage collection by the java garbage collector using weak references to the 17 * {@code Historical}s. 18 * <p> 19 * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br> 20 * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>. 21 * <p> 22 * @version $Revision$, $LastChangedDate$, by $Author$, initial version 18 jan. 2018 <br> 23 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a> 24 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a> 25 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a> 26 */ 27 public abstract class HistoryManager 28 { 29 30 // HACK //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 31 // TODO remove this hack and obtain manager from somewhere else, OTSReplication? 32 /** Centrally stored manager. */ 33 private static Map<Replication<Time, Duration, SimTimeDoubleUnit>, HistoryManagerDEVS> managers = new WeakHashMap<>(); 34 35 /** 36 * Get central manager. 37 * @param simulator DEVSSimulatorInterface.TimeDoubleUnit; simulator 38 * @return HistoryManagerDEVS; central manager 39 */ 40 public static HistoryManagerDEVS get(final DEVSSimulatorInterface.TimeDoubleUnit simulator) 41 { 42 HistoryManagerDEVS manager = managers.get(simulator.getReplication()); 43 if (manager == null) 44 { 45 manager = new HistoryManagerDEVS(simulator, Duration.createSI(0.0), Duration.createSI(10.0)); 46 managers.put(simulator.getReplication(), manager); 47 } 48 return manager; 49 } 50 51 /** 52 * Set central manager. 53 * @param manager HistoryManagerDEVS; manager 54 * @param simulator DEVSSimulatorInterface.TimeDoubleUnit; simulator 55 */ 56 public static void set(final HistoryManagerDEVS manager, final DEVSSimulatorInterface.TimeDoubleUnit simulator) 57 { 58 managers.put(simulator.getReplication(), manager); 59 } 60 61 /** 62 * Clear central manager. If this is not done in batch simulations, this forms a memory leak. 63 * @param simulator DEVSSimulatorInterface.TimeDoubleUnit; simulator 64 */ 65 public static void clear(final DEVSSimulatorInterface.TimeDoubleUnit simulator) 66 { 67 managers.remove(simulator.getReplication()); 68 } 69 // END OF HACK ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 70 71 /** Set of all {@code Historical}s. */ 72 // There's no WeakSet, but this is effectively the same. Iterating over this is safe, only alive objects are returned. 73 private final Set<HistoricalElement> historicals = Collections.newSetFromMap(new WeakHashMap<HistoricalElement, Boolean>()); 74 75 /** 76 * Registers a historical. 77 * @param historical Historical; historical to register. 78 */ 79 public void registerHistorical(final HistoricalElement historical) 80 { 81 if (historical != null) 82 { 83 this.historicals.add(historical); 84 } 85 } 86 87 /** 88 * Returns the historicals. 89 * @return the historicals 90 */ 91 protected final Set<HistoricalElement> getHistoricals() 92 { 93 return this.historicals; 94 } 95 96 /** 97 * Returns the current simulation time. This is used by historicals to time-stamp state changes. 98 * @return Time; current simulation time. 99 */ 100 abstract Time now(); 101 102 /** 103 * Historical view for the history manager. 104 * <p> 105 * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. 106 * <br> 107 * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>. 108 * <p> 109 * @version $Revision$, $LastChangedDate$, by $Author$, initial version 1 feb. 2018 <br> 110 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a> 111 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a> 112 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a> 113 */ 114 public interface HistoricalElement 115 { 116 /** 117 * Removes events that are no longer needed to guarantee the history time. This is invoked by the history manager. 118 * @param history Duration; history time to keep 119 */ 120 void cleanUpHistory(Duration history); 121 } 122 123 /** 124 * Method that clears the entire memory at simulation end. 125 */ 126 protected final void endOfSimulation() 127 { 128 for (HistoricalElement historical : this.historicals) 129 { 130 historical.cleanUpHistory(Duration.ZERO); 131 } 132 this.historicals.clear(); 133 } 134 135 }