Author: echatellier Date: 2014-03-19 10:51:00 +0100 (Wed, 19 Mar 2014) New Revision: 3893 Url: http://forge.codelutin.com/projects/isis-fish/repository/revisions/3893 Log: Merge trunk@3892 into branch 4.0.1@3890 Added: branches/4.0.1/src/main/java/fr/ifremer/isisfish/datastore/ResultStorageInMemory.java branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCache.java branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackend.java branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackendOnGuava.java branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackendOnReferenceMap.java Removed: branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/Cache.java Modified: branches/4.0.1/ branches/4.0.1/pom.xml branches/4.0.1/src/main/java/fr/ifremer/isisfish/IsisConfig.java branches/4.0.1/src/main/java/fr/ifremer/isisfish/IsisFish.java branches/4.0.1/src/main/java/fr/ifremer/isisfish/aspect/CacheAspect.java branches/4.0.1/src/main/java/fr/ifremer/isisfish/datastore/SimulationStorage.java branches/4.0.1/src/main/java/fr/ifremer/isisfish/equation/PopulationGrowth.java branches/4.0.1/src/main/java/fr/ifremer/isisfish/simulator/SimulationContext.java branches/4.0.1/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationService.java branches/4.0.1/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationServiceTableModel.java branches/4.0.1/src/main/java/fr/ifremer/isisfish/ui/input/PopulationZonesEditorUI.jaxx branches/4.0.1/src/main/java/fr/ifremer/isisfish/ui/input/PopulationZonesUI.jaxx branches/4.0.1/src/main/resources/i18n/isis-fish_en_GB.properties branches/4.0.1/src/main/resources/i18n/isis-fish_fr_FR.properties branches/4.0.1/src/main/resources/sensitivity.properties branches/4.0.1/src/main/resources/templates/ssh/qsub-script.ftl Property changes on: branches/4.0.1 ___________________________________________________________________ Modified: svn:mergeinfo - /branches/4.0.0-svnkit:3665-3698 /branches/4.1:3601-3670 /trunk:3616-3799 + /branches/4.0.0-svnkit:3665-3698 /branches/4.1:3601-3670 /trunk:3616-3892 Modified: branches/4.0.1/pom.xml =================================================================== --- branches/4.0.1/pom.xml 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/pom.xml 2014-03-19 09:51:00 UTC (rev 3893) @@ -6,7 +6,7 @@ <parent> <groupId>org.nuiton</groupId> <artifactId>mavenpom4redmine</artifactId> - <version>4.7</version> + <version>5.0.1</version> </parent> <groupId>fr.ifremer</groupId> @@ -345,6 +345,12 @@ <scope>compile</scope> </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>16.0.1</version> + </dependency> + <!-- Tests --> <dependency> <groupId>junit</groupId> @@ -359,7 +365,7 @@ <description>Simulateur de pecherie complexe.</description> <inceptionYear>1999</inceptionYear> - <url>http://maven-site.forge.codelutin.com/isis-fish</url> + <url>http://doc.codelutin.com/isis-fish</url> <organization> <name>CodeLutin</name> @@ -405,7 +411,7 @@ <ciManagement> <system>hudson</system> - <url>http://jenkins.forge.codelutin.com/jenkins/job/isis-fish</url> + <url>http://ci.codelutin.com/jenkins/job/isis-fish-ci</url> </ciManagement> <developers> @@ -441,26 +447,28 @@ <timezone>+2</timezone> </developer> <developer> - <id>sletellier</id> - <name>Sylvain Letellier</name> - <email>letellier@codelutin.com</email> + <id>jcouteau</id> + <name>Jean Couteau</name> + <email>couteau@codelutin.com</email> <organization>CodeLutin</organization> <roles> <role>Développeur</role> </roles> <timezone>+2</timezone> </developer> - <developer> - <id>jcouteau</id> - <name>Jean Couteau</name> - <email>couteau@codelutin.com</email> + </developers> + + <contributors> + <contributor> + <name>Sylvain Letellier</name> + <email>letellier@codelutin.com</email> <organization>CodeLutin</organization> <roles> <role>Développeur</role> </roles> <timezone>+2</timezone> - </developer> - </developers> + </contributor> + </contributors> <!-- ************************************************************* --> <!-- *** Build Settings ****************************************** --> @@ -470,7 +478,7 @@ <properties> <!-- Super pom properties --> <projectId>isis-fish</projectId> - <platform>forge.codelutin.com</platform> + <platform>codelutin.com</platform> <siteLocales>fr,en</siteLocales> <maven.jar.main.class>fr.ifremer.isisfish.IsisFish</maven.jar.main.class> <license.licenseName>gpl_v3</license.licenseName> @@ -501,7 +509,7 @@ <distributionManagement> <site> - <id>${platform}</id> + <id>doc.${platform}</id> <url>${our.site.repository}/isis-fish</url> </site> </distributionManagement> @@ -667,9 +675,9 @@ <!-- *** Build Environment ************************************** --> <!-- ************************************************************* --> <scm> - <connection>scm:svn:http://svn.forge.codelutin.com/svn/isis-fish/branches/4.0.1</connection> - <developerConnection>scm:svn:http://svn.forge.codelutin.com/svn/isis-fish/branches/4.0.1</developerConnection> - <url>http://svn.forge.codelutin.com/svn/isis-fish/branches/4.0.1</url> + <connection>scm:svn:http://svn.codelutin.com/isis-fish/branches/4.0.1</connection> + <developerConnection>scm:svn:http://svn.codelutin.com/isis-fish/branches/4.0.1</developerConnection> + <url>http://svn.codelutin.com/isis-fish/branches/4.0.1</url> </scm> <repositories> @@ -708,6 +716,7 @@ <descriptor>src/main/assembly/bin.xml</descriptor> </descriptors> <attach>false</attach> + <recompressZippedFiles>true</recompressZippedFiles> </configuration> <executions> <execution> Modified: branches/4.0.1/src/main/java/fr/ifremer/isisfish/IsisConfig.java =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/IsisConfig.java 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/IsisConfig.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -59,6 +59,8 @@ import fr.ifremer.isisfish.simulator.launcher.SSHSimulatorLauncher; import fr.ifremer.isisfish.simulator.launcher.SimulationService; import fr.ifremer.isisfish.simulator.launcher.SubProcessSimulationLauncher; +import fr.ifremer.isisfish.util.IsisCacheBackend; +import fr.ifremer.isisfish.util.IsisCacheBackendOnGuava; import fr.ifremer.isisfish.vcs.VCS; /** @@ -929,7 +931,7 @@ /** * L'implementation de la class gérant les implémentations de vecteur de * matrice pour les fichiers mappés. - * + * * @return * @since 4.2.1.1 */ @@ -938,6 +940,18 @@ return result; } + /** + * Retourne la factory a utilise pour le cache + * + * @return factory a utilise pour le backend de cache + * @since 4.2.1.2 + */ + public IsisCacheBackend.Factory getCacheBackendFactoryClass() { + IsisCacheBackend.Factory result = getOptionAsObject( + IsisCacheBackend.Factory.class, Option.CACHE_BACKEND_FACTORY_CLASS.key); + return result; + } + ////////////////////////////////////////////////// // Toutes les options disponibles ////////////////////////////////////////////////// @@ -1044,7 +1058,8 @@ USER_NAME("user.name", n_("isisfish.config.main.userName.description"), System.getProperty("user.name")), SMTP_SERVER("smtpServer", n_("isisfish.config.main.smtpServer.description"), "smtp"), USER_MAIL("userMail", n_("isisfish.config.main.userMail.description"), USER_NAME.key + "@" + VCS_HOST_NAME.key), - MAPPED_RESULT_MATRIX_VECTOR_CLASS("mapped.result.matrix.vector.class", n_("isisfish.config.mapped.result.matrix.vector.class.description"), DoubleBigVector.class.getName()); + MAPPED_RESULT_MATRIX_VECTOR_CLASS("mapped.result.matrix.vector.class", n_("isisfish.config.mapped.result.matrix.vector.class.description"), DoubleBigVector.class.getName()), + CACHE_BACKEND_FACTORY_CLASS("cache.backend.factory.class", n_("isisfish.config.cache.backend.factory.class.description"), IsisCacheBackendOnGuava.IsisCacheBackendOnGuavaFactory.class.getName()); public String key; public String description; Modified: branches/4.0.1/src/main/java/fr/ifremer/isisfish/IsisFish.java =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/IsisFish.java 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/IsisFish.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -44,6 +44,7 @@ import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTextArea; +import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; @@ -73,10 +74,12 @@ import fr.ifremer.isisfish.datastore.SimulationPlanStorage; import fr.ifremer.isisfish.datastore.SimulationStorage; import fr.ifremer.isisfish.datastore.SimulatorStorage; +import fr.ifremer.isisfish.simulator.launcher.SimulationMonitor; import fr.ifremer.isisfish.simulator.launcher.SimulationService; import fr.ifremer.isisfish.ui.WelcomeTabUI; import fr.ifremer.isisfish.ui.WelcomeUI; import fr.ifremer.isisfish.ui.util.ErrorHelper; +import fr.ifremer.isisfish.util.IsisCache; import fr.ifremer.isisfish.util.IsisMatrixSemanticMapper; import fr.ifremer.isisfish.vcs.VCS; import fr.ifremer.isisfish.vcs.VCSActionEvent; @@ -243,6 +246,9 @@ I18n.init(new ClassPathI18nInitializer(), config.getLocale()); } + // init cache backend + IsisCache.defaultFactory = config.getCacheBackendFactoryClass(); + // after init shutdown hook Runtime.getRuntime().addShutdownHook(new IsisQuitHook()); } @@ -631,97 +637,112 @@ public static void launchUI() { if (config.isLaunchUI()) { - // catch wall application exception - Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - public void uncaughtException(Thread t, Throwable cause) { - if (cause instanceof LinkageError) { - if (log.isFatalEnabled()) { - log.fatal("Linkage error detected", cause); - } + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { - // a real java.lang.Error sometimes happen when - // using non recompiled script due to dependency changes - // this is the better solution found : - // remove isis build directory - //FileUtils.deleteQuietly(IsisFish.config.getCompileDirectory()); + // catch wall application exception + Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + public void uncaughtException(Thread t, Throwable cause) { + if (cause instanceof LinkageError) { + if (log.isFatalEnabled()) { + log.fatal("Linkage error detected", cause); + } + + // a real java.lang.Error sometimes happen when + // using non recompiled script due to dependency changes + // this is the better solution found : + // remove isis build directory + try { + FileUtils.deleteDirectory(IsisFish.config.getCompileDirectory()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } - ErrorHelper.showErrorDialog(null, _("isisfish.error.linkageerror.message"), cause); - } - else { - if (log.isErrorEnabled()) { - log.error("Global application exception", cause); + ErrorHelper.showErrorDialog(null, _("isisfish.error.linkageerror.message"), cause); + } + else { + if (log.isErrorEnabled()) { + log.error("Global application exception", cause); + } + + // les NumberFormatException sont courantes lors de la saisie + // ca va etre relou de toutes les afficher + Throwable lastCause = cause; + while (lastCause.getCause() != null) { + lastCause = lastCause.getCause(); + } + if (!(lastCause instanceof NumberFormatException)) { + ErrorHelper.showErrorDialog(null, cause.getMessage(), cause); + } + } } - - // les NumberFormatException sont courantes lors de la saisie - // ca va etre relou de toutes les afficher - Throwable lastCause = cause; - while (lastCause.getCause() != null) { - lastCause = lastCause.getCause(); + }); + + // init simulater manager + SimulationService.getService(); + + // init IsisTray + IsisTray.getInstance(); + + // OpenMap sysout + MapBean.suppressCopyright = true; + + // configure swing session + // can't be in config ? getUserConfigDirectory() not static + File isisConfigDirectory = new File(config.getUserConfigDirectory(), "isis-fish"); + isisConfigDirectory.mkdirs(); + File sessionFile = new File(isisConfigDirectory, "session.xml"); + final SwingSession session = new SwingSession(sessionFile, true); + + // lauch first UI (welcomeUI) + WelcomeUI welcome = new WelcomeUI(); + welcome.setTitle(_("isisfish.welcome.title", IsisConfig.getVersion())); + // Set to exit on close + welcome.setDefaultCloseOperation(WelcomeUI.DO_NOTHING_ON_CLOSE); + welcome.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + WelcomeUI ui = (WelcomeUI)e.getSource(); + ui.getHandler().close(ui); } - if (!(lastCause instanceof NumberFormatException)) { - ErrorHelper.showErrorDialog(null, cause.getMessage(), cause); + + @Override + public void windowClosed(WindowEvent e) { + session.save(); + quit(); } + }); + + try { + InputStream imageStream = WelcomeUI.class.getResourceAsStream("/images/simulation.gif"); + Image image = ImageIO.read(imageStream); + welcome.setIconImage(image); } + catch (IOException ex) { + if (log.isErrorEnabled()) { + log.error("Can't set frame icon", ex); + } + } + + // show main isis window + welcome.setLocationRelativeTo(null); + session.add(welcome); + + // small fix to set selected tab index always to first + WelcomeTabUI tabUI = (WelcomeTabUI)welcome.getWelcomePanelUI().getComponent(1); + tabUI.getSimulUI().getBodyTabbedPane().setSelectedIndex(0); + tabUI.getSensitivityUI().getBodyTabbedPane().setSelectedIndex(0); + + // display frame + welcome.setVisible(true); + + // + SimulationService service = SimulationService.getService(); + SimulationMonitor.getInstance().reloadConfig(service); } }); - - // init simulater manager - SimulationService.getService(); - - // init IsisTray - IsisTray.getInstance(); - - // OpenMap sysout - MapBean.suppressCopyright = true; - - // configure swing session - // can't be in config ? getUserConfigDirectory() not static - File isisConfigDirectory = new File(config.getUserConfigDirectory(), "isis-fish"); - isisConfigDirectory.mkdirs(); - File sessionFile = new File(isisConfigDirectory, "session.xml"); - final SwingSession session = new SwingSession(sessionFile, true); - - // lauch first UI (welcomeUI) - WelcomeUI welcome = new WelcomeUI(); - welcome.setTitle(_("isisfish.welcome.title", IsisConfig.getVersion())); - // Set to exit on close - welcome.setDefaultCloseOperation(WelcomeUI.DO_NOTHING_ON_CLOSE); - welcome.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - WelcomeUI ui = (WelcomeUI)e.getSource(); - ui.getHandler().close(ui); - } - - @Override - public void windowClosed(WindowEvent e) { - session.save(); - quit(); - } - }); - - try { - InputStream imageStream = WelcomeUI.class.getResourceAsStream("/images/simulation.gif"); - Image image = ImageIO.read(imageStream); - welcome.setIconImage(image); - } - catch (IOException ex) { - if (log.isErrorEnabled()) { - log.error("Can't set frame icon", ex); - } - } - - // show main isis window - welcome.setLocationRelativeTo(null); - session.add(welcome); - - // small fix to set selected tab index always to first - WelcomeTabUI tabUI = (WelcomeTabUI)welcome.getWelcomePanelUI().getComponent(1); - tabUI.getSimulUI().getBodyTabbedPane().setSelectedIndex(0); - tabUI.getSensitivityUI().getBodyTabbedPane().setSelectedIndex(0); - - // display frame - welcome.setVisible(true); } else { if (log.isInfoEnabled()) { Modified: branches/4.0.1/src/main/java/fr/ifremer/isisfish/aspect/CacheAspect.java =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/aspect/CacheAspect.java 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/aspect/CacheAspect.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -36,7 +36,7 @@ import org.aspectj.lang.reflect.MethodSignature; import fr.ifremer.isisfish.simulator.SimulationContext; -import fr.ifremer.isisfish.util.Cache; +import fr.ifremer.isisfish.util.IsisCache; /** * CacheAspect aspect. @@ -66,9 +66,9 @@ * * @return trace object from context */ - protected Cache getCache() { + protected IsisCache getCache() { SimulationContext context = SimulationContext.get(); - Cache result = context.getCache(); + IsisCache result = context.getCache(); return result; } Copied: branches/4.0.1/src/main/java/fr/ifremer/isisfish/datastore/ResultStorageInMemory.java (from rev 3892, trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultStorageInMemory.java) =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/datastore/ResultStorageInMemory.java (rev 0) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/datastore/ResultStorageInMemory.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -0,0 +1,497 @@ +/* + * #%L + * IsisFish + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2002 - 2011 Ifremer, Code Lutin, Cédric Pineau, Benjamin Poussin, Chatellier Eric + * %% + * This program 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. + * + * This program 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/gpl-3.0.html>. + * #L% + */ + +package fr.ifremer.isisfish.datastore; + +import static org.nuiton.i18n.I18n._; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.math.matrix.MatrixFactory; +import org.nuiton.math.matrix.MatrixIterator; +import org.nuiton.math.matrix.MatrixND; +import org.nuiton.topia.TopiaContext; +import org.nuiton.util.ArrayUtil; +import org.nuiton.util.HashList; + +import fr.ifremer.isisfish.IsisFishException; +import fr.ifremer.isisfish.entities.Population; +import fr.ifremer.isisfish.export.Export; +import fr.ifremer.isisfish.export.SensitivityExport; +import fr.ifremer.isisfish.rule.Rule; +import fr.ifremer.isisfish.simulator.SimulationContext; +import fr.ifremer.isisfish.simulator.SimulationException; +import fr.ifremer.isisfish.simulator.SimulationPlan; +import fr.ifremer.isisfish.simulator.SimulationResultGetter; +import fr.ifremer.isisfish.types.TimeStep; +import fr.ifremer.isisfish.types.Month; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.Map; + +/** + * Cette classe permet de conserver des résultats de simulation. Elle permet + * ensuite de les récupérer. Les résultats sont stockés en mémoire. + * + * Created: 29 sept. 2004 + * + * @author Benjamin Poussin <poussin@codelutin.com> + * @version $Revision$ + * + * Mise a jour: $Date$ + * par : $Author$ + */ +public class ResultStorageInMemory implements SimulationResultGetter, ResultStorage { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(ResultStorageInMemory.class); + + final static public String MAX_TIME_STEP = "ResultStorageInMemory.maxTimeStep"; + protected int maxTimeStep = 12; // default to 1 year + protected SimulationStorage simulation = null; + + LinkedHashMap<TimeStep, Map<String, MatrixND>> data = new LinkedHashMap<TimeStep, Map<String, MatrixND>>() { + private static final long serialVersionUID = 1L; + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > maxTimeStep; + } + }; + + LinkedHashMap<TimeStep, List<Rule>> rules = new LinkedHashMap<TimeStep, List<Rule>>() { + private static final long serialVersionUID = 1L; + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > maxTimeStep; + } + }; + + + /** result enabled */ + transient protected Set<String> enabledResult = null; + + /** + * Les ResultStorage ne doivent pas etre instancier directement, mais + * recuperer a partir d'un + * {@link fr.ifremer.isisfish.datastore.SimulationStorage#getResultStorage()} + * + * @param simulation storage to get result + */ + public ResultStorageInMemory(SimulationStorage simulation) { + this.simulation = simulation; + maxTimeStep = Integer.parseInt(simulation.getParameter().getTagValue().get(MAX_TIME_STEP)); + } + + @Override + public void delete() { + data.clear(); + } + + @Override + public void close() { + // do nothing, closed by simulation storage closing + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#isEnabled(java.lang.String) + */ + @Override + public boolean isEnabled(String name) { + name = name.trim(); + if (enabledResult == null) { + enabledResult = new HashSet<String>(); + + Collection<String> resultEnabled = simulation.getParameter() + .getResultEnabled(); + enabledResult.addAll(resultEnabled); + + // test on export + List<String> exportNames = simulation.getParameter().getExportNames(); + if (exportNames != null) { + for (String exportName : exportNames) { + ExportStorage storage = ExportStorage.getExport(exportName); + try { + Export export = storage.getNewExportInstance(); + for (String resultName : export.getNecessaryResult()) { + enabledResult.add(resultName); + } + } catch (IsisFishException eee) { + if (log.isWarnEnabled()) { + log.warn(_("isisfish.error.instanciate.export", + exportName), eee); + } + } + } + } + + // test on sensitivity export + List<SensitivityExport> sensitivityExports = simulation + .getParameter().getSensitivityExport(); + if (sensitivityExports != null) { + for (SensitivityExport sensitivityExport : sensitivityExports) { + for (String resultName : sensitivityExport.getNecessaryResult()) { + enabledResult.add(resultName); + } + } + } + + // test on rules + List<Rule> rules = simulation.getParameter().getRules(); + if (rules != null) { + for (Rule rule : rules) { + for (String resultName : rule.getNecessaryResult()) { + enabledResult.add(resultName); + } + } + } + + // test on plans + List<SimulationPlan> plans = simulation.getParameter().getSimulationPlans(); + if (plans != null) { + for (SimulationPlan plan : plans) { + for (String resultName : plan.getNecessaryResult()) { + enabledResult.add(resultName); + } + } + } + log.info("Enabled result: " + enabledResult); + } + boolean result = enabledResult.contains(name); + return result; + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(fr.ifremer.isisfish.types.TimeStep, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(TimeStep step, MatrixND mat) throws IsisFishException { + addResult(false, step, mat.getName(), mat); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(fr.ifremer.isisfish.types.TimeStep, fr.ifremer.isisfish.entities.Population, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(TimeStep step, Population pop, MatrixND mat) throws IsisFishException { + addResult(false, step, mat.getName(), pop, mat); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(boolean, fr.ifremer.isisfish.types.TimeStep, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(boolean force, TimeStep step, MatrixND mat) throws IsisFishException { + addResult(force, step, mat.getName(), mat); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(boolean, fr.ifremer.isisfish.types.TimeStep, fr.ifremer.isisfish.entities.Population, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(boolean force, TimeStep step, Population pop, MatrixND mat) throws IsisFishException { + addResult(force, step, mat.getName(), pop, mat); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(fr.ifremer.isisfish.types.TimeStep, java.lang.String, fr.ifremer.isisfish.entities.Population, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(TimeStep step, String name, Population pop, MatrixND mat) throws IsisFishException { + addResult(false, step, name, pop, mat); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(fr.ifremer.isisfish.types.TimeStep, java.lang.String, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(TimeStep step, String name, MatrixND mat) throws IsisFishException { + addResult(false, step, name, mat); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(boolean, fr.ifremer.isisfish.types.TimeStep, java.lang.String, fr.ifremer.isisfish.entities.Population, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(boolean force, TimeStep step, String name, Population pop, MatrixND mat) throws IsisFishException { + if (force || isEnabled(name)) { + doAddResult(step, name + " " + pop, mat); + } + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(boolean, fr.ifremer.isisfish.types.TimeStep, java.lang.String, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(boolean force, TimeStep step, String name, MatrixND mat) throws IsisFishException { + if (force || isEnabled(name)) { + doAddResult(step, name, mat); + } + } + + protected void doAddResult(TimeStep step, String name, MatrixND mat) throws IsisFishException { + // si la matrice n'a pas de semantique on refuse + for (int i = 0; i < mat.getDimCount(); i++) { + // la semantique n'est pas bonne des qu'il y a un null dedans + if (mat.getSemantic(i).contains(null)) { + throw new SimulationException( + "Erreur le résultat que vous souhaitez enregistrer n'a pas d'information convenable pour la dimension: " + + i + " " + mat.getDimensionName(i)); + } + } + + // on fait une copie pour avoir reellement des resultats independant + // FIXME echatellier 20120829 : faire une copie optimiser + // suivant l'implementation du vector plutot qu'un parcourt + // via un iterateur de semantiques (plus couteux) + MatrixND newMat = mat.copy(); + Map<String, MatrixND> mats = data.get(step); + if (mats == null) { + mats = new HashMap<String, MatrixND>(); + data.put(step, mats); + } + + mats.put(name, newMat); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addActiveRule(fr.ifremer.isisfish.types.TimeStep, fr.ifremer.isisfish.rule.Rule) + */ + @Override + public void addActiveRule(TimeStep step, Rule rule) throws IsisFishException { + List<Rule> list = rules.get(step); + if (list == null) { + list = new LinkedList<Rule>(); + rules.put(step, list); + } + + list.add(rule); + +// result.setActiveRuleStep(step); +// result.setName(RuleStorage.getName(rule)); +// result.setParam(RuleStorage.getParamAsString(rule)); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getResultName() + */ + @Override + public List<String> getResultName() { + + Set<String> result = new HashSet<String>(); + + for (Map<String, MatrixND> mats : data.values()) { + result.addAll(mats.keySet()); + } + + return new ArrayList<String>(result); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(fr.ifremer.isisfish.types.TimeStep, fr.ifremer.isisfish.entities.Population, java.lang.String) + */ + @Override + public MatrixND getMatrix(TimeStep step, Population pop, String name) { + String newName = name + " " + pop; + return getMatrix(step, newName); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(fr.ifremer.isisfish.types.TimeStep, java.lang.String) + */ + @Override + public MatrixND getMatrix(TimeStep step, String name) { + MatrixND result = null; + Map<String, MatrixND> mats = data.get(step); + if (mats != null) { + result = mats.get(name); + } + return result; + } + + @Override + public MatrixND getMatrix(TimeStep step, String name, TopiaContext tx) { + return getMatrix(step, name); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(fr.ifremer.isisfish.entities.Population, java.lang.String) + */ + @Override + public MatrixND getMatrix(Population pop, String name) { + String newName = name + " " + pop; + return getMatrix(newName); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(fr.ifremer.isisfish.entities.Population, java.lang.String, org.nuiton.topia.TopiaContext) + */ + @Override + public MatrixND getMatrix(Population pop, String name, TopiaContext tx) { + String newName = name + " " + pop; + return getMatrix(newName, tx); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(java.lang.String) + */ + @Override + public MatrixND getMatrix(String name) { + MatrixND result = null; + + List<TimeStep> steps = new ArrayList<TimeStep>(); + Map<TimeStep, MatrixND> mats = new LinkedHashMap<TimeStep, MatrixND>(); + MatrixND matExample = null; + for (Map.Entry<TimeStep, Map<String, MatrixND>> e : data.entrySet()) { + TimeStep ts = e.getKey(); + MatrixND mat = e.getValue().get(name); + if (mat != null) { + steps.add(ts); + mats.put(ts, mat); + matExample = mat; + } + } + + if (mats.size() > 0) { + // recuperation des noms des dimensions + String[] dimNames = new String[1 + matExample.getDimCount()]; + dimNames[0] = _("isisfish.common.date"); + for (int i = 1; i < dimNames.length; i++) { + dimNames[i] = matExample.getDimensionName(i - 1); + } + + // creation de la semantique pour la matrice resultat. +1 pour les dates + List[] sem = new List[1 + matExample.getDimCount()]; + sem[0] = steps; + + for (int i = 1; i < sem.length; i++) { + sem[i] = new HashList(); + } + + for (MatrixND mattmp : mats.values()) { + if (log.isTraceEnabled()) { + log.trace("Ajout de la semantics: " + + Arrays.asList(mattmp.getSemantics())); + } + + for (int s = 0; s < mattmp.getDimCount(); s++) { + sem[s + 1].addAll(mattmp.getSemantic(s)); + } + } + + if (log.isTraceEnabled()) { + log.trace("La semantique final est: " + Arrays.asList(sem)); + } + + // creation de la matrice resultat + result = MatrixFactory.getInstance().create(name, sem, dimNames); + + // recuperation du resultat pour chaque date de la simulation, de Date(0) à lastDate + for (Map.Entry<TimeStep, MatrixND> e : mats.entrySet()) { + TimeStep d = e.getKey(); + MatrixND mat = e.getValue(); + // on recupere dans la matrice resultat l'endroit on il faut + // mettre la matrice + MatrixND submat = result.getSubMatrix(0, d, 1); + // on met les valeur de mat dans la sous matrice extraite + for (MatrixIterator mi = mat.iterator(); mi.next();) { + submat.setValue( + ArrayUtil.concat(new Object[] { d }, + mi.getSemanticsCoordinates()), mi.getValue()); + } + } + } + + return result; + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(java.lang.String, org.nuiton.topia.TopiaContext) + */ + @Override + public MatrixND getMatrix(String name, TopiaContext tx) { + return getMatrix(name); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getLastStep() + */ + @Override + public TimeStep getLastStep() { + int monthNumber = simulation.getParameter().getNumberOfYear() + * Month.NUMBER_OF_MONTH; + TimeStep result = new TimeStep(monthNumber - 1); // -1 because date begin at 0 + return result; + } + + /* + * @see fr.ifremer.isisfish.simulator.SimulationResultListener#addResult(fr.ifremer.isisfish.simulator.SimulationContext, fr.ifremer.isisfish.types.TimeStep, java.lang.String, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(SimulationContext context, TimeStep step, String name, + MatrixND mat) throws IsisFishException { + doAddResult(step, name, mat); + } + + /* + * @see fr.ifremer.isisfish.simulator.SimulationResultGetter#getMatrix(fr.ifremer.isisfish.simulator.SimulationContext, fr.ifremer.isisfish.types.TimeStep, java.lang.String) + */ + @Override + public MatrixND getMatrix(SimulationContext context, TimeStep step, String name) { + MatrixND result = getMatrix(step, name); + return result; + } + + /* + * @see fr.ifremer.isisfish.simulator.SimulationResultGetter#getMatrix(fr.ifremer.isisfish.simulator.SimulationContext, java.lang.String) + */ + @Override + public MatrixND getMatrix(SimulationContext context, String name) { + MatrixND result = getMatrix(name); + return result; + } + + /* + * @see fr.ifremer.isisfish.simulator.SimulationListener#afterSimulation(fr.ifremer.isisfish.simulator.SimulationContext) + */ + @Override + public void afterSimulation(SimulationContext context) { + } + + /* + * @see fr.ifremer.isisfish.simulator.SimulationListener#beforeSimulation(fr.ifremer.isisfish.simulator.SimulationContext) + */ + @Override + public void beforeSimulation(SimulationContext context) { + } + +} Modified: branches/4.0.1/src/main/java/fr/ifremer/isisfish/datastore/SimulationStorage.java =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/datastore/SimulationStorage.java 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/datastore/SimulationStorage.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -476,10 +476,17 @@ if (simuVersion.before(version4200)) { resultStorage = new ResultDatabaseStorage(this); } else { - try { - resultStorage = new ResultMappedStorage(this); - } catch (IOException ex) { - throw new StorageException("Can't get storage", ex); + // if user ask for ResultStorageInMemory, used it + String maxTimeStep = param.getTagValue().get(ResultStorageInMemory.MAX_TIME_STEP); + if (maxTimeStep != null) { + // use in memory with max time step + resultStorage = new ResultStorageInMemory(this); + } else { + try { + resultStorage = new ResultMappedStorage(this); + } catch (IOException ex) { + throw new StorageException("Can't get storage", ex); + } } } } Modified: branches/4.0.1/src/main/java/fr/ifremer/isisfish/equation/PopulationGrowth.java =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/equation/PopulationGrowth.java 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/equation/PopulationGrowth.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -43,7 +43,7 @@ public interface PopulationGrowth { /** - * Compute groth equation. + * Compute growth equation. * * @param context simulation context * @param age l'age du groupe en mois Modified: branches/4.0.1/src/main/java/fr/ifremer/isisfish/simulator/SimulationContext.java =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/simulator/SimulationContext.java 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/simulator/SimulationContext.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -40,7 +40,7 @@ import fr.ifremer.isisfish.datastore.SimulationStorage; import fr.ifremer.isisfish.simulator.sensitivity.SensitivityUtils; import fr.ifremer.isisfish.types.TimeStep; -import fr.ifremer.isisfish.util.Cache; +import fr.ifremer.isisfish.util.IsisCache; import fr.ifremer.isisfish.util.Trace; /** @@ -78,7 +78,7 @@ /** l'objet trace qui conserve les donnees statistiques des appels de methodes */ protected Trace trace; /** cache used by aspect for this simulation */ - protected Cache cache; + protected IsisCache cache; /** TopiaContext must be used by rule action to modify data */ protected TopiaContext db = null; @@ -208,10 +208,11 @@ return trace; } - public Cache getCache() { + public IsisCache getCache() { if (cache == null) { - cache = new Cache(); - }return cache; + cache = new IsisCache(); + } + return cache; } /** Modified: branches/4.0.1/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationService.java =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationService.java 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationService.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -201,9 +201,10 @@ // fait un appel au moniteur // pour reprendre le monitoring des simulation en cours // TODO check this, don't restart monitoring on non ui launch - if (IsisFish.config.isLaunchUI()) { - SimulationMonitor.getInstance().reloadConfig(this); - } + // moved to main() + //if (IsisFish.config.isLaunchUI()) { + // SimulationMonitor.getInstance().reloadConfig(this); + //} } /** Modified: branches/4.0.1/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationServiceTableModel.java =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationServiceTableModel.java 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationServiceTableModel.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -103,7 +103,7 @@ } controlListener = new ControlListener(this); simulationService.addSimulationServiceListener(jobListener); - jobListener.setData(); + //jobListener.setData(); } public void addJob(SimulationJob job) { @@ -330,12 +330,12 @@ } public void setData() { - model.setJobs(new ArrayList<SimulationJob>(simulationService - .getJobs())); - for (SimulationJob job : model.getJobs()) { + ArrayList<SimulationJob> jobs = new ArrayList<SimulationJob>(simulationService.getJobs()); + for (SimulationJob job : jobs) { job.getItem().getControl().addPropertyChangeListener( controlListener); } + model.setJobs(jobs); } public void simulationStart(SimulationService simService, Modified: branches/4.0.1/src/main/java/fr/ifremer/isisfish/ui/input/PopulationZonesEditorUI.jaxx =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/ui/input/PopulationZonesEditorUI.jaxx 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/ui/input/PopulationZonesEditorUI.jaxx 2014-03-19 09:51:00 UTC (rev 3893) @@ -192,7 +192,9 @@ <cell columns='3' fill='both' weightx='1.0' weighty='0.5'> <org.nuiton.math.matrix.gui.MatrixPanelEditor id='fieldPopulationMappingZoneReproZoneRecru' constructorParams='false' enabled='{isActive()}' - onMatrixChanged="populationMappingZoneReproZoneRecruMatrixChanged(event)" /> + onMatrixChanged="populationMappingZoneReproZoneRecruMatrixChanged(event)" + decorator='boxed' + _sensitivityBean='{fr.ifremer.isisfish.entities.Population.class}' _sensitivityMethod='"MappingZoneReproZoneRecru"' /> </cell> </row> </Table> Modified: branches/4.0.1/src/main/java/fr/ifremer/isisfish/ui/input/PopulationZonesUI.jaxx =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/ui/input/PopulationZonesUI.jaxx 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/ui/input/PopulationZonesUI.jaxx 2014-03-19 09:51:00 UTC (rev 3893) @@ -43,6 +43,12 @@ getSaveVerifier().addCurrentPanel(popZones); }*/ + +@Override +public void setLayer(boolean active) { + super.setLayer(active); + popZones.setLayer(active); +} ]]> </script> <JPanel id='body'> @@ -50,8 +56,7 @@ <row> <cell columns="2" fill='both' weightx='1.0' weighty='1'> <PopulationZonesEditorUI id='popZones' constructorParams='this' - bean='{getBean()}' active='{isActive()}' decorator='boxed' - _sensitivityBean='{Population.class}' _sensitivityMethod='"MappingZoneReproZoneRecru"'/> + bean='{getBean()}' active='{isActive()}'/> </cell> </row> <row> Deleted: branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/Cache.java =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/Cache.java 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/Cache.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -1,288 +0,0 @@ -/* - * #%L - * IsisFish - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2006 - 2013 Ifremer, Code Lutin, Cédric Pineau, Benjamin Poussin, Chatellier Eric - * %% - * This program 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. - * - * This program 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/gpl-3.0.html>. - * #L% - */ - -package fr.ifremer.isisfish.util; - -import java.lang.reflect.Method; -import java.util.Map; - -import org.apache.commons.collections4.map.AbstractReferenceMap.ReferenceStrength; -import org.apache.commons.collections4.map.ReferenceMap; -import org.aspectj.lang.ProceedingJoinPoint; -import org.nuiton.topia.persistence.TopiaEntity; - -import fr.ifremer.isisfish.simulator.SimulationContext; -import fr.ifremer.isisfish.types.TimeStep; - -/** - * Cache utilise pour mettre les resultats de methode durant la simulation - * pour minimiser les appels - * - * Created: 25 août 06 22:42:47 - * - * @author poussin - * @version $Revision$ - * - * Last update: $Date$ - * by : $Author$ - */ -public class Cache { - - // 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 - static final private Object NULL = new Object(); - -// static private List<CacheAspect> instances = new ArrayList<CacheAspect>(); - - protected long totalCall = 0; - protected long cacheUsed = 0; - - /** - * map<TimeStep, Map<Key, Value>> - * TimeStep peut etre null via l'objet NULL - * Key est la cle calcule par computeKey - * Value est la valeur du cache - * - * TimeStep est en WEAK pour que des que l'on passe au pas de temps suivant - * ils soit efface de la memoire si plus personne n'a de reference sur - * ce pas de temps. L'autre moyen est de force l'effacement via clear(TimeStep) - * - * Value est en SOFT reference pour que les valeurs soit effacee du cache - * lorsqu'il n'y a plus de place memoire - */ - protected Map cache = new ReferenceMap(ReferenceStrength.WEAK, ReferenceStrength.HARD); -// protected Map cache = new AdaptaptativeCache(1000, 95); - - public Cache() { - } - - /** - * Return trace object from context. - * - * @return trace object from context - */ - protected Trace getTrace() { - SimulationContext context = SimulationContext.get(); - Trace result = context.getTrace(); - return result; - } - - /** - * Recupere pour un pas de temps donnes une valeur calcule pour une cle - * @param step le pas de temps pour lequel on souhaite ajouter (ou null) - * @param key la cle de storage - * @param defaultValue la valeur par defaut a retourner si elle n'est pas en cache - * si defaultValue est une JoinPoint alors un proceed est appele dessus et le - * resultat de l'appel est utiliser comme valeur par defaut - * @return la valeur dans le cache ou defaultValue - */ - public Object get(Method method, Object[] args, Object defaultValue) throws Throwable { - totalCall++; - - Object result = null; - if (method.getAnnotation(Nocache.class) != null || - method.getDeclaringClass().getAnnotation(Nocache.class) != null) { - result = realCall(defaultValue); - } else { - // compute key and keep TimeStep objet - StringBuilder sbKey = new StringBuilder(); - // le pas de temps trouve dans les arguments - TimeStep step = computeKey(sbKey, method, 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) - Object 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); - 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 { - cacheUsed++; - } - } - return result; - } - - protected TimeStep computeKey(StringBuilder sbKey, Method method, Object[] args) { - TimeStep result = null; - sbKey.append(method.getDeclaringClass().getSimpleName()); - sbKey.append("."); - sbKey.append(method.getName()); - for (Object o : args) { - sbKey.append(";"); - if (o == null) { - sbKey.append("null"); - } else if (o instanceof Number || o instanceof String) { - sbKey.append(o.toString()); - } else if (o instanceof TimeStep) { - result = (TimeStep)o; - sbKey.append(((TimeStep)o).getStep()); - } else if (o instanceof TopiaEntity) { - sbKey.append( ((TopiaEntity)o).getTopiaId().substring(entityPackageLenght)); - } else { - // on minimise en prenant que le nom de la classe (pas le package) - sbKey.append(o.getClass().getSimpleName()); - sbKey.append('@'); - // et en lui ajoutant son adresse memoire en Hexa - sbKey.append(Integer.toHexString(System.identityHashCode(o))); - } - } - return result; - } - - protected Map getCacheTimeStep(TimeStep step) { - Object key = step; - if (step == null) { - key = NULL; - } - Map result = (Map)cache.get(key); - if (result == null) { - result = new ReferenceMap(ReferenceStrength.HARD, ReferenceStrength.SOFT); - cache.put(key, result); - } - return result; - } - - protected Object get(TimeStep step, Object key) { - Object result = null; - Map cacheTimeStep = getCacheTimeStep(step); - if (cacheTimeStep != null) { - result = cacheTimeStep.get(key); - } - return result; - } - - protected void put(TimeStep step, Object key, Object value) { - getCacheTimeStep(step).put(key, value); - } - - /** - * On fait l'appel reel dans une autre methode pour pouvoir le savoir - * dans les traces - * - * @param jp - * @return ? - * @throws Throwable - */ - protected Object realCall(Object defaultValue) throws Throwable { - Object result = defaultValue; - if (defaultValue instanceof ProceedingJoinPoint) { - result = ((ProceedingJoinPoint)defaultValue).proceed(); - } - return result; - } - - /** - * remove all values in cache - */ - public void clear() { - cache.clear(); - } - - /** - * remove all values in cache for the specied TimeStep - */ - public void clear(TimeStep step) { - Object key = step; - if (key == null) { - key = NULL; - } - cache.remove(key); - } - - /** - * @return Returns the cacheUsed. - */ - public long getCacheUsed() { - long result = cacheUsed; - return result; - } - - /** - * @return Returns the totalCall. - */ - public long getTotalCall() { - long result = totalCall; - return result; - } - - /** - * Affiche les statistiques - * - */ - public String printStatistiqueAndClear() { - StringBuilder result = new StringBuilder(); - result.append("--- Cache Statistiques ---\n"); - result.append("Total call: ").append(totalCall).append("\n"); - result.append("Cache used: ").append(cacheUsed).append("\n"); - long percent = 0; - if (totalCall != 0) { - percent = 100*cacheUsed/totalCall; - } - result.append("Cache usage: ").append(percent).append("%\n"); - result.append("--------------------\n"); - cache.clear(); - - System.out.println(result.toString()); - return result.toString(); - } - - // EN COURS D'ECRITURE MAIS JAMAIS FINI :( - // l'idee est de prendre la place memoire qu'il y a, mais s'il n'y en - // a plus on commence par enlever les objets les plus vieux -// class AdaptaptativeCache extends LinkedHashMap<String, Object> { -// protected int maxMemory = 95; -// /** -// * -// * @param capacity initial capacity -// * @param maxMemory maximum memory used (0-100) -// */ -// public AdaptaptativeCache(int capacity, int maxMemory) { -// super(capacity, 0.75f, true); -// this.maxMemory = maxMemory; -// } -// -// /* (non-Javadoc) -// * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) -// */ -// @Override -// protected boolean removeEldestEntry(Entry<String, Object> eldest) { -// double free = 100.0 * Runtime.getRuntime().freeMemory() / Runtime.getRuntime().maxMemory() ; -// boolean result = 100 - free > maxMemory; -// return result; -// } -// } -} - - Copied: branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCache.java (from rev 3892, trunk/src/main/java/fr/ifremer/isisfish/util/IsisCache.java) =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCache.java (rev 0) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCache.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -0,0 +1,268 @@ +/* + * #%L + * IsisFish + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2006 - 2010 Ifremer, Code Lutin, Cédric Pineau, Benjamin Poussin + * %% + * This program 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. + * + * This program 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/gpl-3.0.html>. + * #L% + */ +package fr.ifremer.isisfish.util; + +import java.lang.reflect.Method; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.aspectj.lang.ProceedingJoinPoint; +import org.nuiton.topia.persistence.TopiaEntity; + +import fr.ifremer.isisfish.simulator.SimulationContext; +import fr.ifremer.isisfish.types.TimeStep; + +/** + * IsisCacheOnReferenceMap utilise pour mettre les resultats de methode durant + * la simulation pour minimiser les appels + * <p> + * Created: 25 août 06 22:42:47 + * <p> + * @author poussin + * @version $Revision$ + <p> + Last update: $Date$ by : + $Author$ + */ +public class IsisCache { + + /** + * to use log facility, just put in your code: log.info(\"...\"); + */ + static private Log log = LogFactory.getLog(IsisCache.class); + + static public IsisCacheBackend.Factory defaultFactory + = IsisCacheBackendOnGuava.factory; + + // 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 + static final private Object NULL = new Object(); + + protected long totalCall = 0; + protected long cacheUsed = 0; + + protected IsisCacheBackend cacheBackend; + + public IsisCache() { + this(defaultFactory.createNew()); + } + + public IsisCache(IsisCacheBackend cacheBackend) { + this.cacheBackend = cacheBackend; + } + + /** + * Return trace object from context. + * <p> + * @return trace object from context + */ + protected Trace getTrace() { + SimulationContext context = SimulationContext.get(); + Trace result = context.getTrace(); + return result; + } + + /** + * Recupere pour un pas de temps donnes une valeur calcule pour une cle + * <p> + * @param step le pas de temps pour lequel on souhaite ajouter (ou + * null) + * @param key la cle de storage + * @param defaultValue la valeur par defaut a retourner si elle n'est pas en + * cache si defaultValue est une JoinPoint alors un + * proceed est appele dessus et le resultat de l'appel + * est utiliser comme valeur par defaut + * @return la valeur dans le cache ou defaultValue + */ + public Object get(Method method, Object[] args, Object defaultValue) throws Throwable { + totalCall++; + + Object result = null; + if (method.getAnnotation(Nocache.class) != null + || method.getDeclaringClass().getAnnotation(Nocache.class) != null) { + result = realCall(defaultValue); + } else { + // compute key and keep TimeStep objet + StringBuilder sbKey = new StringBuilder(); + // le pas de temps trouve dans les arguments + TimeStep step = computeKey(sbKey, method, 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); + 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 { + cacheUsed++; + } + } + return result; + } + + protected TimeStep computeKey(StringBuilder sbKey, Method method, Object[] args) { + TimeStep result = null; + sbKey.append(method.getDeclaringClass().getSimpleName()); + sbKey.append("."); + sbKey.append(method.getName()); + for (Object o : args) { + sbKey.append(";"); + if (o == null) { + sbKey.append("null"); + } else if (o instanceof Number || o instanceof String) { + sbKey.append(o.toString()); + } else if (o instanceof TimeStep) { + result = (TimeStep) o; + sbKey.append(((TimeStep) o).getStep()); + } else if (o instanceof TopiaEntity) { + sbKey.append(((TopiaEntity) o).getTopiaId().substring(entityPackageLenght)); + } else { + // on minimise en prenant que le nom de la classe (pas le package) + sbKey.append(o.getClass().getSimpleName()); + sbKey.append('@'); + // et en lui ajoutant son adresse memoire en Hexa + sbKey.append(Integer.toHexString(System.identityHashCode(o))); + } + } + return result; + } + + protected Object get(TimeStep step, String key) { + Object result = cacheBackend.get(step, key); + return result; + } + + protected void put(TimeStep step, String key, Object value) { + cacheBackend.put(step, key, value); + } + + /** + * On fait l'appel reel dans une autre methode pour pouvoir le savoir dans + * les traces + * <p> + * @param jp + * @return ? + * @throws Throwable + */ + protected Object realCall(Object defaultValue) throws Throwable { + Object result = defaultValue; + if (defaultValue instanceof ProceedingJoinPoint) { + result = ((ProceedingJoinPoint)defaultValue).proceed(); + } + return result; + } + + /** + * remove all values in cache + */ + public void clear() { + cacheBackend.clear(); + } + + /** + * remove all values in cache for the specied TimeStep + */ + public void clear(TimeStep step) { + Object key = step; + if (key == null) { + key = NULL; + } + cacheBackend.removeStep(key); + } + + /** + * @return Returns the cacheUsed. + */ + public long getCacheUsed() { + long result = cacheUsed; + return result; + } + + /** + * @return Returns the totalCall. + */ + public long getTotalCall() { + long result = totalCall; + return result; + } + + /** + * Affiche les statistiques + * <p> + */ + public String printStatistiqueAndClear() { + cacheBackend.clear(); + + StringBuilder result = new StringBuilder(); + result.append("--- Cache Statistiques ---\n"); + result.append("Total call: ").append(totalCall).append("\n"); + result.append("Cache used: ").append(cacheUsed).append("\n"); + long percent = 0; + if (totalCall != 0) { + percent = 100 * cacheUsed / totalCall; + } + result.append("Cache usage: ").append(percent).append("%\n"); + result.append(cacheBackend.getStat()); + result.append("--------------------\n"); + + System.out.println(result.toString()); + return result.toString(); + } + + // EN COURS D'ECRITURE MAIS JAMAIS FINI :( + // l'idee est de prendre la place memoire qu'il y a, mais s'il n'y en + // a plus on commence par enlever les objets les plus vieux +// class AdaptaptativeCache extends LinkedHashMap<String, Object> { +// protected int maxMemory = 95; +// /** +// * +// * @param capacity initial capacity +// * @param maxMemory maximum memory used (0-100) +// */ +// public AdaptaptativeCache(int capacity, int maxMemory) { +// super(capacity, 0.75f, true); +// this.maxMemory = maxMemory; +// } +// +// /* (non-Javadoc) +// * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) +// */ +// @Override +// protected boolean removeEldestEntry(Entry<String, Object> eldest) { +// double free = 100.0 * Runtime.getRuntime().freeMemory() / Runtime.getRuntime().maxMemory() ; +// boolean result = 100 - free > maxMemory; +// return result; +// } +// } +} Copied: branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackend.java (from rev 3892, trunk/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackend.java) =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackend.java (rev 0) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackend.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -0,0 +1,58 @@ +/* + * #%L + * IsisFish + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2013 Ifremer, Code Lutin, Benjamin Poussin + * %% + * This program 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. + * + * This program 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/gpl-3.0.html>. + * #L% + */ + +package fr.ifremer.isisfish.util; + +import fr.ifremer.isisfish.types.TimeStep; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public interface IsisCacheBackend { + + Object get(TimeStep step, String key) ; + + void put(TimeStep step, String key, Object value); + + void clear() ; + + void removeStep(Object key); + + /** + * get specific backend cache statistic + * @return backend specific string cache stat representation + */ + String getStat(); + + static public interface Factory { + IsisCacheBackend createNew(); + } + +} Copied: branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackendOnGuava.java (from rev 3892, trunk/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackendOnGuava.java) =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackendOnGuava.java (rev 0) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackendOnGuava.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -0,0 +1,310 @@ +/* + * #%L + * IsisFish + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2013 Ifremer, Code Lutin, Benjamin Poussin + * %% + * This program 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. + * + * This program 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/gpl-3.0.html>. + * #L% + */ +package fr.ifremer.isisfish.util; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.Weigher; +import fr.ifremer.isisfish.types.TimeStep; +import java.util.Collection; +import org.apache.commons.lang3.ClassUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.math.matrix.MatrixND; +import org.nuiton.util.StringUtil; + +/** + * Cache qui reserve de la place pour l'equivalent de N pas de temps dans le cache. + * + * Une premiere instanciation du cache est faite. Puis apres le premier pas + * de temps on regarde la taille des objets ayant ete ajoutes au cache pour + * recalculer la nouvelle taille pour permettre de stocker N pas de temps. + * + * @author poussin + * @version $Revision$ + + Last update: $Date$ + by : $Author$ + */ +public class IsisCacheBackendOnGuava implements IsisCacheBackend { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(IsisCacheBackendOnGuava.class); + + final static public int POINTER_SIZE = 8; + final static public int DOUBLE_SIZE = 8; + final static public int CHAR_SIZE = 2; + + /** number of time steps to cache by interpolating from the first step*/ + // perhaps allow the configuration + static public int CACHE_STEP = 3; + + static public class IsisCacheBackendOnGuavaFactory implements IsisCacheBackend.Factory { + @Override + public IsisCacheBackend createNew() { + return new IsisCacheBackendOnGuava(); + } + } + + static public Factory factory = new IsisCacheBackendOnGuavaFactory(); + + static public class IsisWeigher implements Weigher<String, Object> { + + protected IsisCacheBackendOnGuava backend; + public IsisWeigher(IsisCacheBackendOnGuava backend) { + this.backend = backend; + } + + @Override + public int weigh(String key, Object value) { + int result = key.length() * CHAR_SIZE; + if (value instanceof MatrixND) { + // MatrixND + // on prend le nombre de case de la matrice pour sa taille + // on ne tient pas compte des dimensions qui sont des objets + // utilises ailleurs + int[] dim = ((MatrixND)value).getDim(); + int size = 1; + for (int i=0; i<dim.length; i++) { + size *= dim[i]; + } + result += size * DOUBLE_SIZE; // size is wrong, because depend on matrix type (float or double) + } else if (value instanceof Collection) { + // List<Zone|Pop|Str|Metier|Cell> + // on prend la taille de la collection, car la donnees + // elle meme qu'elle soit dans le backend ou non est + // certainement utilisee ailleur, donc seul la taille + // des pointeurs dans la collection est prise ici + result += ((Collection)value).size() * POINTER_SIZE; + } else if (value instanceof Number) { + // int| double + // seulement une valeur, on ajoute 1 + result += 1 * DOUBLE_SIZE; + } else { + // a priori, il n'y a pas d'autre type de donnee + if (value != null) { + log.info("Cache can't compute value size of " + ClassUtils.getPackageCanonicalName(value, "null")); + } + } + + backend.addStat(result); + + result = Math.max(1024, result); // min to 1ko + return result; + } + } + + protected Cache<String, Object> cache; + protected IsisWeigher isisWeigher; + protected long maxMemory; + protected long maxCache; + protected long sizeCache; + + /** the last step use to put value in cache */ + protected TimeStep lastStep = null; + /** if true size of cache has been recomputed */ + protected boolean adjusted = false; + + /** le total en octet mis en cache au precedent pas de temps*/ + protected long totalLastStepCached = 0; + + // STATISTIQUE PAR ENTREE DANS LE CACHE + /** le total en d'element mis en cache */ + protected long numberCached = 0; + /** le total en octet mis en cache */ + protected long totalCached = 0; + /** la plus petite donnee mis en cache */ + protected long smallestCached = Long.MAX_VALUE; + /** la plus grosse donnee mis en cache */ + protected long biggestCached = 0; + + // for variance + double delta = 0; + double mean = 0; + double M2 = 0; + + // STATISTIQUE PAR PAS DE TEMPS + /** le total en d'element mis en cache */ + protected long numberStepCached = 0; + /** le total en octet mis en cache */ + protected long totalStepCached = 0; + /** la plus petite donnee mis en cache */ + protected long smallestStepCached = Long.MAX_VALUE; + /** la plus grosse donnee mis en cache */ + protected long biggestStepCached = 0; + + // for variance + double stepDelta = 0; + double stepMean = 0; + double stepM2 = 0; + + + + public IsisCacheBackendOnGuava() { + isisWeigher = new IsisWeigher(this); + + maxMemory = Runtime.getRuntime().maxMemory(); + maxCache = maxMemory - 500*1024*1024; // isis need about 500M + maxCache = Math.max(maxCache, 200*1024*1024); // to do simulation we need 200M cache + + // create first cache, this cache is juste for one step + adjustedCache(maxCache); + } + + public void addStat(long value) { + numberCached++; + totalCached = totalCached + value; + + // compute variance + delta = value - mean; + mean = mean + delta/numberCached; + M2 = M2 + delta * (value - mean); + + biggestCached = Math.max(biggestCached, value); + smallestCached = Math.min(smallestCached, value); + } + + public void addStepStat(long value) { + numberStepCached++; + totalStepCached = totalStepCached + value; + + // compute variance + stepDelta = value - stepMean; + stepMean = stepMean + stepDelta/numberStepCached; + stepM2 = stepM2 + stepDelta * (value - stepMean); + + biggestStepCached = Math.max(biggestStepCached, value); + smallestStepCached = Math.min(smallestStepCached, value); + } + + @Override + public void clear() { + cache.invalidateAll(); + // clear is assimilate to step change (last step end) + // useful to finalize variance computation for last step + changeStep(); + } + + @Override + public void removeStep(Object o) { + } + + /** + * resizes the cache if amount is not greater than autorized maxCache + * @param amount new size of cache in byte + */ + public void adjustedCache(long amount){ + if (amount == 0) { + log.info("Cache size not ajusted because 0 is not acceptable amount"); + } else { + // on estime le nombre d'entree necessaire pour ce volume de donnees + long bytePerStep = totalCached / Math.max(1, numberStepCached); + long entriesPerStep = numberCached / Math.max(1, numberStepCached); + + long initialCapacity = amount * entriesPerStep / Math.max(1, bytePerStep); + long stepEquivalent = initialCapacity / Math.max(1, entriesPerStep); + + // use amount as new size for cache + // if this new size is less than maxCache, use it + // to keep more memory for JVM + sizeCache = Math.min(this.maxCache, amount); + + CacheBuilder builder = CacheBuilder.newBuilder(); + builder.maximumWeight(sizeCache); + builder.weigher(isisWeigher); + if (initialCapacity > 0) { + builder.initialCapacity((int)initialCapacity); + } + cache = builder.build(); + + log.info(String.format("Cache size ajusted to %s (equivalent to %s step need)", + StringUtil.convertMemory(sizeCache), stepEquivalent)); + } + } + + /** + * Previent le cache, qu'on change de TimeStep et qu'il peut faire + * du travail s'il en a besoin. + * + * - calcul de statistique + * - ajustement de la taille du cache + */ + public void changeStep() { + // on est passe au pas de temps suivant + long stepAmount = totalCached - totalLastStepCached; + totalLastStepCached = totalCached; + addStepStat(stepAmount); + + // after first step, use information to resize cache + if (!adjusted) { + adjustedCache(stepAmount * CACHE_STEP); // keep place for 3 step + adjusted = true; + } + } + + @Override + public Object get(TimeStep step, String key) { + Object result = cache.getIfPresent(key); + return result; + } + + @Override + public void put(TimeStep step, String key, Object value) { + cache.put(key, value); + if (step != null) { + if (lastStep == null) { + lastStep = step; + } else if (lastStep.getStep() != step.getStep()) { + // if step differ, this indicate new Step + changeStep(); + lastStep = step; + } + } + } + + @Override + public String getStat() { + long mean = totalCached / Math.max(1, numberCached); + long stepMean = totalStepCached / Math.max(1, numberStepCached); + + double variance = M2/Math.max(1, numberCached - 1); + double stepVariance = stepM2/Math.max(1, numberStepCached - 1); + + double standardDeviation = Math.sqrt(variance); + double stepStandardDeviation = Math.sqrt(stepVariance); + + return String.format("%s - \n" + + "\tmaxMemory: %s, cacheMemory: %s, totalCached: %s, numberStep: %s, numberEntries: %s\n" + + "\tStep min: %s, max: %s, mean: %s, standard deviation: %s\n" + + "\tEntry min: %s, max: %s, mean: %s, standard deviation: %s\n", + getClass().getSimpleName(), + StringUtil.convertMemory(maxMemory), StringUtil.convertMemory(sizeCache), StringUtil.convertMemory(totalCached), numberStepCached, numberCached, + StringUtil.convertMemory(smallestStepCached), StringUtil.convertMemory(biggestStepCached), StringUtil.convertMemory(stepMean), StringUtil.convertMemory((long)stepStandardDeviation), + StringUtil.convertMemory(smallestCached), StringUtil.convertMemory(biggestCached), StringUtil.convertMemory(mean), StringUtil.convertMemory((long)standardDeviation) + ); + } + + +} Copied: branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackendOnReferenceMap.java (from rev 3892, trunk/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackendOnReferenceMap.java) =================================================================== --- branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackendOnReferenceMap.java (rev 0) +++ branches/4.0.1/src/main/java/fr/ifremer/isisfish/util/IsisCacheBackendOnReferenceMap.java 2014-03-19 09:51:00 UTC (rev 3893) @@ -0,0 +1,145 @@ +/* + * #%L + * IsisFish + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2006 - 2010 Ifremer, Code Lutin, Cédric Pineau, Benjamin Poussin + * %% + * This program 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. + * + * This program 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/gpl-3.0.html>. + * #L% + */ + +package fr.ifremer.isisfish.util; + +import fr.ifremer.isisfish.simulator.SimulationContext; +import fr.ifremer.isisfish.types.TimeStep; +import java.util.Map; +import org.apache.commons.collections.map.ReferenceMap; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * IsisCacheBackendOnReferenceMap utilise pour mettre les resultats de methode durant la simulation + pour minimiser les appels + + Created: 25 août 06 22:42:47 + * + * @author poussin + * @version $Revision$ + + Last update: $Date$ + by : $Author$ + */ +public class IsisCacheBackendOnReferenceMap implements IsisCacheBackend { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(IsisCacheBackendOnReferenceMap.class); + + static public class IsisCacheBackendOnReferenceMapFactory implements IsisCacheBackend.Factory { + @Override + public IsisCacheBackend createNew() { + return new IsisCacheBackendOnReferenceMap(); + } + } + + static public Factory factory = new IsisCacheBackendOnReferenceMapFactory(); + + // 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 + static final private Object NULL = new Object(); + + /** + * map<TimeStep, Map<Key, Value>> + * TimeStep peut etre null via l'objet NULL + * Key est la cle calcule par computeKey + * Value est la valeur du cache + * + * TimeStep est en WEAK pour que des que l'on passe au pas de temps suivant + * ils soit efface de la memoire si plus personne n'a de reference sur + * ce pas de temps. L'autre moyen est de force l'effacement via clear(TimeStep) + * + * Value est en SOFT reference pour que les valeurs soit effacee du cache + * lorsqu'il n'y a plus de place memoire + */ + protected Map cache = new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.HARD); + + public IsisCacheBackendOnReferenceMap() { + } + + /** + * Return trace object from context. + * + * @return trace object from context + */ + protected Trace getTrace() { + SimulationContext context = SimulationContext.get(); + Trace result = context.getTrace(); + return result; + } + + protected Map getCacheTimeStep(TimeStep step) { + Object key = step; + if (step == null) { + key = NULL; + } + Map result = (Map)cache.get(key); + if (result == null) { + result = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT); + cache.put(key, result); + } + return result; + } + + @Override + public Object get(TimeStep step, String key) { + Object result = null; + Map cacheTimeStep = getCacheTimeStep(step); + if (cacheTimeStep != null) { + result = cacheTimeStep.get(key); + } + return result; + } + + @Override + public void put(TimeStep step, String key, Object value) { + getCacheTimeStep(step).put(key, value); + } + + /** + * remove all values in cache + */ + @Override + public void clear() { + cache.clear(); + } + + /** + * remove all values in cache for the specied TimeStep + */ + @Override + public void removeStep(Object o) { + cache.remove(o); + } + + @Override + public String getStat() { + return String.format("%s - no specific stat\n", getClass().getSimpleName()); + } +} + + Modified: branches/4.0.1/src/main/resources/i18n/isis-fish_en_GB.properties =================================================================== --- branches/4.0.1/src/main/resources/i18n/isis-fish_en_GB.properties 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/resources/i18n/isis-fish_en_GB.properties 2014-03-19 09:51:00 UTC (rev 3893) @@ -164,6 +164,7 @@ isisfish.common.warn=warn isisfish.common.year=year isisfish.common.zone=Zone +isisfish.config.cache.backend.factory.class.description=Cache backend class to use for simulation isisfish.config.category.communityvcs=Community VCS isisfish.config.category.communityvcs.description=Community VCS repository isisfish.config.category.main=Main Modified: branches/4.0.1/src/main/resources/i18n/isis-fish_fr_FR.properties =================================================================== --- branches/4.0.1/src/main/resources/i18n/isis-fish_fr_FR.properties 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/resources/i18n/isis-fish_fr_FR.properties 2014-03-19 09:51:00 UTC (rev 3893) @@ -164,6 +164,7 @@ isisfish.common.warn=Warning isisfish.common.year=année isisfish.common.zone=Zone +isisfish.config.cache.backend.factory.class.description=Implantation du cache à utiliser pour les simulations isisfish.config.category.communityvcs=VCS Communauté isisfish.config.category.communityvcs.description=Dépôt contenant les scripts de la communautés isisfish.config.category.main=Globale @@ -981,12 +982,12 @@ isisfish.strategy.inactivity=Equation d'inactivité isisfish.strategy.inactivityEquationUsed=Utiliser une équation d'inactivité isisfish.strategy.name=Nom -isisfish.strategy.proportionMetier=Proportion metier -isisfish.strategy.proportionMetierLabel=Proportion metier \: +isisfish.strategy.proportionMetier=Proportion métier +isisfish.strategy.proportionMetierLabel=Proportion métier \: isisfish.strategy.proportionSetOfVessels=Proportion de la flottille isisfish.strategy.title=Caractéristiques isisfish.strategyMonthInfo.metier=Métier -isisfish.strategyMonthInfo.minInactivityDays=Jour minimums d'inactivité +isisfish.strategyMonthInfo.minInactivityDays=Jours minimums d'inactivité isisfish.strategyMonthInfo.numberOfTrips=Nombre de trajets isisfish.strategyMonthInfo.proportion=Proportion isisfish.strategyMonthInfo.title=Saisie des mois Modified: branches/4.0.1/src/main/resources/sensitivity.properties =================================================================== --- branches/4.0.1/src/main/resources/sensitivity.properties 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/resources/sensitivity.properties 2014-03-19 09:51:00 UTC (rev 3893) @@ -42,6 +42,7 @@ Population.groupMin Population.growth Population.growthReverse +Population.mappingZoneReproZoneRecru Population.maturityOgiveEquation Population.meanWeight Population.monthGapBetweenReproRecrutement @@ -54,6 +55,7 @@ PopulationSeasonInfo.migrationEquation PopulationSeasonInfo.emigrationEquation PopulationSeasonInfo.immigrationEquation +PopulationSeasonInfo.reproductionDistribution Selectivity.equation SetOfVessels.fixedCosts SetOfVessels.numberOfVessels Modified: branches/4.0.1/src/main/resources/templates/ssh/qsub-script.ftl =================================================================== --- branches/4.0.1/src/main/resources/templates/ssh/qsub-script.ftl 2014-03-19 09:16:24 UTC (rev 3892) +++ branches/4.0.1/src/main/resources/templates/ssh/qsub-script.ftl 2014-03-19 09:51:00 UTC (rev 3893) @@ -5,7 +5,7 @@ $Id$ $HeadURL$ %% - Copyright (C) 2009 - 2012 Ifremer, CodeLutin, Chatellier Eric + Copyright (C) 2009 - 2014 Ifremer, CodeLutin, Chatellier Eric %% This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -29,7 +29,7 @@ setenv R_HOME /appli/R/2.15.0-gnu-4.3/lib64/R setenv LD_LIBRARY_PATH ${r"${R_HOME}"}/lib -<#assign commonCommand="${javapath} -Djava.library.path=jri64 -DR.type=jni -Xmx${javamemory} -jar isis-fish*.jar" /> +<#assign commonCommand="${javapath} -Djava.library.path=jri64 -DR.type=jni -Xmx${javamemory} -XX:+UseSerialGC -jar isis-fish*.jar" /> <#assign commonOptions="--option launch.ui false --option perform.vcsupdate false --option perform.migration false --option perform.cron false" /> <#if qsubmutiplejob> <#-- localsimulationid is short simulation id version -->