Author: bpoussin Date: 2014-07-10 18:35:38 +0200 (Thu, 10 Jul 2014) New Revision: 4033 Url: http://forge.codelutin.com/projects/isis-fish/repository/revisions/4033 Log: - change version to 4.3.1.0 - add information on each step (min, max, mean, ...) - rewrite IsisCache method for performance - sumOverDim use semantics 1,2,3,4,... for new dimensions Modified: trunk/pom.xml trunk/src/main/java/fr/ifremer/isisfish/IsisConfig.java trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultDatabaseStorage.java trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultStorageAbstract.java trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationContext.java trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationExportResultWrapper.java trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationListener.java trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationPreScriptListener.java trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationResultXML.java trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/InProcessSimulatorLauncher.java trunk/src/main/java/fr/ifremer/isisfish/util/IsisCache.java Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2014-07-10 12:25:39 UTC (rev 4032) +++ trunk/pom.xml 2014-07-10 16:35:38 UTC (rev 4033) @@ -11,7 +11,7 @@ <groupId>fr.ifremer</groupId> <artifactId>isis-fish</artifactId> - <version>4.3.0.2-SNAPSHOT</version> + <version>4.3.1.0-SNAPSHOT</version> <!-- POM Relationships : Inheritance : Dependencies --> <dependencies> Modified: trunk/src/main/java/fr/ifremer/isisfish/IsisConfig.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/IsisConfig.java 2014-07-10 12:25:39 UTC (rev 4032) +++ trunk/src/main/java/fr/ifremer/isisfish/IsisConfig.java 2014-07-10 16:35:38 UTC (rev 4033) @@ -122,7 +122,7 @@ * migration de donnees demande automatiquement un changement de version * d'application. */ - protected final static Version version = new Version(4, 3, 0, 2); + protected final static Version version = new Version(4, 3, 1, 0); protected final static Version majorVersion = new Version(version.getNumber(0)); protected final static Version databaseVersion = new Version( Modified: trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultDatabaseStorage.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultDatabaseStorage.java 2014-07-10 12:25:39 UTC (rev 4032) +++ trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultDatabaseStorage.java 2014-07-10 16:35:38 UTC (rev 4033) @@ -843,6 +843,10 @@ public void beforeSimulation(SimulationContext context) { } + @Override + public void stepChange(SimulationContext context, TimeStep step) { + } + // public void addActivatedRule(ResultStorage self, Date date, RegleParam rule){ // List rules = (List)activatedRules.get(date); // if(rules == null){ Modified: trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultStorageAbstract.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultStorageAbstract.java 2014-07-10 12:25:39 UTC (rev 4032) +++ trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultStorageAbstract.java 2014-07-10 16:35:38 UTC (rev 4033) @@ -698,6 +698,10 @@ public void beforeSimulation(SimulationContext context) { } + @Override + public void stepChange(SimulationContext context, TimeStep step) { + } + // public void addActivatedRule(ResultStorage self, Date date, RegleParam rule){ // List rules = (List)activatedRules.get(date); // if(rules == null){ Modified: trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationContext.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationContext.java 2014-07-10 12:25:39 UTC (rev 4032) +++ trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationContext.java 2014-07-10 16:35:38 UTC (rev 4033) @@ -42,6 +42,8 @@ import fr.ifremer.isisfish.simulator.sensitivity.SensitivityUtils; import fr.ifremer.isisfish.types.TimeStep; import fr.ifremer.isisfish.util.IsisCache; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; //import fr.ifremer.isisfish.util.Trace; import org.nuiton.config.ApplicationConfig; import org.nuiton.config.OverwriteApplicationConfig; @@ -82,6 +84,13 @@ protected RuleMonitor ruleMonitor = null; protected ResultManager resultManager = null; protected Set<SimulationListener> simulationListeners = new LinkedHashSet<SimulationListener>(); + protected PropertyChangeListener stepListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + SimulationContext.this.fireStepChange(new TimeStep((Integer)evt.getNewValue())); + } + }; + protected ClassLoader classLoader = null; protected File scriptDirectory; /** l'objet trace qui conserve les donnees statistiques des appels de methodes */ @@ -227,6 +236,12 @@ } } + public void fireStepChange(TimeStep step) { + for (SimulationListener l : simulationListeners) { + l.stepChange(this, step); + } + } + public void fireAfterSimulation() { for (SimulationListener l : simulationListeners) { l.afterSimulation(this); @@ -306,7 +321,15 @@ * @param simulationControl The simulationControl to set. */ public void setSimulationControl(SimulationControl simulationControl) { - this.simulationControl = simulationControl; + if (this.simulationControl != simulationControl) { + if (this.simulationControl != null) { + this.simulationControl.removePropertyChangeListener("step", stepListener); + } + this.simulationControl = simulationControl; + if (simulationControl != null) { + simulationControl.addPropertyChangeListener("step", stepListener); + } + } } /** Modified: trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationExportResultWrapper.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationExportResultWrapper.java 2014-07-10 12:25:39 UTC (rev 4032) +++ trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationExportResultWrapper.java 2014-07-10 16:35:38 UTC (rev 4033) @@ -32,7 +32,6 @@ import java.util.List; import java.util.Set; -import org.apache.commons.collections4.ListUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -42,6 +41,7 @@ import fr.ifremer.isisfish.export.Export; import fr.ifremer.isisfish.export.ExportHelper; import fr.ifremer.isisfish.export.SensitivityExport; +import fr.ifremer.isisfish.types.TimeStep; /** * Export simulation listener. @@ -125,4 +125,8 @@ @Override public void beforeSimulation(SimulationContext context) { } + + @Override + public void stepChange(SimulationContext context, TimeStep step) { + } } Modified: trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationListener.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationListener.java 2014-07-10 12:25:39 UTC (rev 4032) +++ trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationListener.java 2014-07-10 16:35:38 UTC (rev 4033) @@ -25,6 +25,8 @@ package fr.ifremer.isisfish.simulator; +import fr.ifremer.isisfish.types.TimeStep; + /** * You can create new SimulationListener and add it for simulation. To do that * add tag/value in advanced parameter simulation launcher like @@ -44,6 +46,14 @@ public void beforeSimulation(SimulationContext context); /** + * Receive event when simulation change step + * + * @param context + * @param step + */ + public void stepChange(SimulationContext context, TimeStep step); + + /** * called after simulation * * @param context Modified: trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationPreScriptListener.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationPreScriptListener.java 2014-07-10 12:25:39 UTC (rev 4032) +++ trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationPreScriptListener.java 2014-07-10 16:35:38 UTC (rev 4033) @@ -27,13 +27,11 @@ import static org.nuiton.i18n.I18n.t; -import java.util.HashMap; -import java.util.Map; - import org.apache.commons.lang3.StringUtils; import org.nuiton.topia.TopiaContext; import fr.ifremer.isisfish.datastore.SimulationStorage; +import fr.ifremer.isisfish.types.TimeStep; import fr.ifremer.isisfish.util.EvaluatorHelper; /** @@ -93,4 +91,8 @@ t("Can't evaluate simulation prescript"), eee); } } + + @Override + public void stepChange(SimulationContext context, TimeStep step) { + } } Modified: trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationResultXML.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationResultXML.java 2014-07-10 12:25:39 UTC (rev 4032) +++ trunk/src/main/java/fr/ifremer/isisfish/simulator/SimulationResultXML.java 2014-07-10 16:35:38 UTC (rev 4033) @@ -164,6 +164,10 @@ } + @Override + public void stepChange(SimulationContext context, TimeStep step) { + } + } Modified: trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/InProcessSimulatorLauncher.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/InProcessSimulatorLauncher.java 2014-07-10 12:25:39 UTC (rev 4032) +++ trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/InProcessSimulatorLauncher.java 2014-07-10 16:35:38 UTC (rev 4033) @@ -71,6 +71,8 @@ import fr.ifremer.isisfish.types.TimeStep; import fr.ifremer.isisfish.util.CompileHelper; import org.nuiton.math.matrix.MatrixFactory; +import org.nuiton.profiling.Statistic; +import org.nuiton.profiling.Unit; /** * Fait une simulation dans la meme jvm. @@ -87,7 +89,45 @@ private static Log log = LogFactory .getLog(InProcessSimulatorLauncher.class); + protected static class StepTimeStat implements SimulationListener { + + protected long lastTime = 0; + protected Statistic stat = new Statistic("Step time"){ + @Override + public String formatValue(long value) { + String result = String.valueOf(Unit.Time.nano.convertTo(Unit.Time.s, value)); + return result; + } + }; + + public Statistic getStat() { + return stat; + } + + @Override + public void beforeSimulation(SimulationContext context) { + } + + @Override + public void stepChange(SimulationContext context, TimeStep step) { + if (lastTime == 0) { + lastTime = System.nanoTime(); + } else { + long newTime = System.nanoTime(); + long delta = newTime - lastTime; + lastTime = newTime; + stat.add(delta); + } + } + + @Override + public void afterSimulation(SimulationContext context) { + } + + } + protected SimulationStorage simulation; + protected StepTimeStat stepTimeStat = new StepTimeStat(); /** * {@inheritDoc} @@ -434,6 +474,9 @@ + matrixBackend + " and " + matrixSparseBackend + " threshold: " + threshold); simulatorObject.simulate(context); + simulation.getInformation().addInformation( + stepTimeStat.getStat().exportText(null).toString()); + // // Ajout des nouveaux objets créés durant la simulation // @@ -545,6 +588,9 @@ // - ResultStorage context.addSimulationListener(simulation.getResultStorage()); + // ajout du listener de statistique sur le temps de chaque pas de temps + context.addSimulationListener(stepTimeStat); + // - TODO: mexico xml result // - TODO: vle result String simListener = context.getSimulationStorage().getParameter() Modified: trunk/src/main/java/fr/ifremer/isisfish/util/IsisCache.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/util/IsisCache.java 2014-07-10 12:25:39 UTC (rev 4032) +++ trunk/src/main/java/fr/ifremer/isisfish/util/IsisCache.java 2014-07-10 16:35:38 UTC (rev 4033) @@ -31,7 +31,6 @@ import org.aspectj.lang.ProceedingJoinPoint; import org.nuiton.topia.persistence.TopiaEntity; -import fr.ifremer.isisfish.simulator.SimulationContext; import fr.ifremer.isisfish.types.TimeStep; import java.util.HashMap; import java.util.Map; @@ -60,7 +59,7 @@ // la longueur du package pour minimiser la longueur des topiaId static final private int entityPackageLenght = "fr.ifremer.isisfish.entities.".length(); - // la valeur NULL a utilise a la place de null pour les timeStep + // la valeur NULL a utilise a la place de null pour les timeStep, et les retours de method static final private Object NULL = new Object(); protected long totalCall = 0; @@ -108,44 +107,55 @@ public Object get(Method method, Object[] args, Object defaultValue) throws Throwable { totalCall++; - Object result = null; + Object result; - String methodString = methodStringCache.get(method); - if (methodString == null) { - Class declaringClass = method.getDeclaringClass(); - methodString = (method.getAnnotation(Nocache.class) != null - || declaringClass.getAnnotation(Nocache.class) != null)? - "@" : ""; - methodString += declaringClass.getSimpleName() + "."+ method.getName(); - methodString = methodString.intern(); - methodStringCache.put(method, methodString); - } - - // if method have annotation 'noCache' name start with @ - if (methodString.charAt(0) == '@') { + if (Void.TYPE == method.getReturnType()) { + // for void return type, never put it in cache, we can call directly real method result = realCall(defaultValue); } else { - // compute key and keep TimeStep objet - // le pas de temps trouve dans les arguments - sbKey.setLength(0); - TimeStep step = computeKey(sbKey, methodString, args); - // on recupere le intern de la String car normalement en cache on - // retrouve souvent les memes chaines comme cle (sinon le cache - // servirait a rien :D) - String key = sbKey.toString().intern(); - result = get(step, key); - if (result == null) { + String methodString = methodStringCache.get(method); + if (methodString == null) { + Class declaringClass = method.getDeclaringClass(); + methodString = (method.getAnnotation(Nocache.class) != null + || declaringClass.getAnnotation(Nocache.class) != null)? + "@" : ""; + methodString += declaringClass.getSimpleName() + "."+ method.getName(); + methodString = methodString.intern(); + methodStringCache.put(method, methodString); + } - // computation increment (/ by 0) - // FIXME need to be called, but fail with empty stack - //getTrace().traceAfterComputation(method); + // if method have annotation 'noCache' name start with @ + if (methodString.charAt(0) == '@') { result = realCall(defaultValue); - if (result != null) { // util pour les methodes retournant void, ne fonctionne pas si on met AND !execute(void *(..)) dans l'aspect. En fait fonction seulement si utilisé avec les traces :( - put(step, key, result); + } else { + // compute key and keep TimeStep objet + // le pas de temps trouve dans les arguments + sbKey.setLength(0); + TimeStep step = computeKey(sbKey, methodString, args); + + // on recupere le intern de la String car normalement en cache on + // retrouve souvent les memes chaines comme cle (sinon le cache + // servirait a rien :D) + String key = sbKey.toString().intern(); + result = get(step, key); + if (result == null) { + + // computation increment (/ by 0) + // FIXME need to be called, but fail with empty stack + //getTrace().traceAfterComputation(method); + result = realCall(defaultValue); + // si return null on stock NULL pour faire la distinction + // entre present dans le cache ou absent (get(...) return null) +// if (returnType != != null) { // util pour les methodes retournant void, ne fonctionne pas si on met AND !execute(void *(..)) dans l'aspect. En fait fonction seulement si utilisé avec les traces :( + put(step, key, result==null?NULL:result); +// } + } else { + if (result == NULL) { + result = null; + } + cacheUsed++; } - } else { - cacheUsed++; } } return result;