]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
(refs #5495) Performance optimizations for Project Game
authorvillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 24 Nov 2014 10:47:16 +0000 (10:47 +0000)
committervillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 24 Nov 2014 10:47:16 +0000 (10:47 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@30594 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/IndexVariable.java
org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableValueSubscription.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/GameResult.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/OldSysdynExperiment.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SimulateDurationJob.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperimentInternal.java
org.simantics.sysdyn/src/org/simantics/sysdyn/utils/DocumentationUtils.java

index 4211a80a91e361e71ea2c484753746d945cba24c..6b4a6d7f209c57cf0566636cefffcc4445a3805a 100644 (file)
@@ -25,6 +25,7 @@ import org.simantics.project.IProject;
 import org.simantics.simulation.experiment.IExperiment;\r
 import org.simantics.simulation.ontology.SimulationResource;\r
 import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.manager.OldSysdynExperiment;\r
 import org.simantics.sysdyn.manager.SysdynExperiment;\r
 import org.simantics.sysdyn.manager.SysdynModel;\r
 import org.simantics.sysdyn.manager.SysdynModelManager;\r
@@ -47,7 +48,37 @@ public abstract class IndexVariable<T> extends AbstractPropertyVariable {
                this.indexes = indexes;\r
        }\r
        \r
-       \r
+       @Override\r
+       public int hashCode() {\r
+               final int prime = 31;\r
+               int result = 1;\r
+               result = prime * result + ((indexes == null) ? 0 : indexes.hashCode());\r
+               result = prime * result + ((parent == null) ? 0 : parent.hashCode());\r
+               return result;\r
+       }\r
+\r
+       @Override\r
+       public boolean equals(Object obj) {\r
+               if (this == obj)\r
+                       return true;\r
+               if (obj == null)\r
+                       return false;\r
+               if (getClass() != obj.getClass())\r
+                       return false;\r
+               IndexVariable other = (IndexVariable) obj;\r
+               if (indexes == null) {\r
+                       if (other.indexes != null)\r
+                               return false;\r
+               } else if (!indexes.equals(other.indexes))\r
+                       return false;\r
+               if (parent == null) {\r
+                       if (other.parent != null)\r
+                               return false;\r
+               } else if (!parent.equals(other.parent))\r
+                       return false;\r
+               return true;\r
+       }\r
+\r
        protected VariableSubscriptionManager getSubscriptionManager() {\r
                return this.experiment;\r
        }\r
@@ -92,10 +123,9 @@ public abstract class IndexVariable<T> extends AbstractPropertyVariable {
      * @author Teemu Lempinen\r
      *\r
      */\r
-    class PropertyRequest extends ParametrizedPrimitiveRead<Variable, T> {\r
-\r
+    static class PropertyRequest<T> extends ParametrizedPrimitiveRead<IndexVariable, T> {\r
 \r
-        public PropertyRequest(Variable indexVariable) {\r
+        public PropertyRequest(IndexVariable indexVariable) {\r
             super(indexVariable);\r
         }\r
 \r
@@ -103,24 +133,21 @@ public abstract class IndexVariable<T> extends AbstractPropertyVariable {
 \r
         @Override\r
         public void register(ReadGraph graph, Listener<T> procedure) {\r
-            subscription = registerSubscription(this, procedure);\r
+               if(subscription != null)\r
+                       System.err.println("err!");\r
+            subscription = parameter.registerSubscription(this, procedure);\r
         }\r
         @Override\r
         public void unregistered() {\r
             if(subscription != null) {\r
-                unregisterSubscription(subscription);\r
+                parameter.unregisterSubscription(subscription);\r
                 subscription = null;\r
             }\r
         }\r
-\r
-        @SuppressWarnings("unchecked")\r
-               @Override\r
-        public boolean equals(Object object) {\r
-            if(object instanceof IndexVariable.PropertyRequest && super.equals(object)) {\r
-                return this.parameter.equals(((PropertyRequest)object).parameter);\r
-            } else {\r
-                return super.equals(object);\r
-            }\r
+        \r
+        @Override\r
+        public String toString() {\r
+               return "PropertyRequest[" + parameter.rvi + "]";\r
         }\r
 \r
     }\r
@@ -308,5 +335,12 @@ public abstract class IndexVariable<T> extends AbstractPropertyVariable {
        public Variable getParent(ReadGraph graph) throws DatabaseException {\r
                return parent;\r
        }\r
+       \r
+       public int getPublishCounter(ReadGraph graph) throws DatabaseException {\r
+               if(experiment instanceof OldSysdynExperiment) {\r
+                       return ((OldSysdynExperiment)experiment).getPublishCounter(graph);\r
+               }\r
+               return 0;\r
+       }\r
 \r
 }\r
index 716fd5887f1ae657925d95c2e61c4ca050a3f118..a283e94c1d3bab2b8e35c6aee0ea124351976acb 100644 (file)
@@ -23,15 +23,19 @@ import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.Listener;\r
 import org.simantics.db.request.ExternalRead;\r
 import org.simantics.db.service.QueryControl;\r
+import org.simantics.utils.ObjectUtils;\r
 import org.simantics.utils.datastructures.Callback;\r
 \r
 public class VariableValueSubscription<T> {\r
     \r
        public static final long SUBSCRIPTION_COLLECTION_INTERVAL = 2000L;\r
+       \r
+       private static final Object dummy = new Object();\r
 \r
        protected ExternalRead<?>  request;\r
        protected IndexVariable<T>         variable;\r
        protected Listener<T> listener;\r
+       protected Object lastFired = dummy;\r
 \r
        /**\r
         * To protect against invoking listener.exception multiple times which is\r
@@ -52,15 +56,19 @@ public class VariableValueSubscription<T> {
     public void update() {\r
         try {\r
             T value = variable.getValue();\r
-            fireValue(value);\r
+            if(!ObjectUtils.objectEquals(value, lastFired)) {\r
+                fireValue(value);\r
+                lastFired = value;\r
+            }\r
         } catch (Throwable e) {\r
             fireException(e);\r
         }\r
     }\r
 \r
        void fireValue(T value) {\r
-               if (listener != null)\r
+               if (listener != null) {\r
                        listener.execute(value);\r
+               }\r
        }\r
 \r
        void fireException(Throwable t) {\r
index 8997ca0742ec3f98535599b0c9357dd7eea7d7f1..1beb980cd45c08acb25f11e5477b35785b7d7a8b 100644 (file)
@@ -1,7 +1,6 @@
 package org.simantics.sysdyn.manager;\r
 \r
 import gnu.trove.list.array.TDoubleArrayList;\r
-import gnu.trove.map.hash.THashMap;\r
 \r
 import org.simantics.modelica.data.DataSet;\r
 import org.simantics.modelica.data.SimulationResult;\r
@@ -13,16 +12,18 @@ import org.simantics.modelica.data.SimulationResult;
  */\r
 public class GameResult extends SimulationResult {\r
        \r
-       public GameResult(SysdynGameExperimentBase sysdynGameExperiment, THashMap<String, TDoubleArrayList> results, String[] subscription) {\r
+       public GameResult(SysdynGameExperimentBase sysdynGameExperiment, TDoubleArrayList[] results, String[] subscription) {\r
+               \r
+               int timeIndex = sysdynGameExperiment.subscriptionIndexes.get("time");\r
                \r
                // Get times\r
-               TDoubleArrayList timeList = results.get("time");\r
+               TDoubleArrayList timeList = results[timeIndex];\r
                double[] times = timeList.toArray();\r
                \r
                String name;\r
                for(int k = 0; k < subscription.length; k++) {\r
                        name = subscription[k];\r
-                       TDoubleArrayList valueList = results.get(name);\r
+                       TDoubleArrayList valueList = results[k];\r
                        if(valueList.size() ==  timeList.size()) {\r
                                this.variables.add(new DataSet(name, times, valueList.toArray()));\r
                        } else {\r
index 8ebfb23f8aa26aeedda8d8808e496c710e428307..f6e2d507ec7b6d35a08bd29811a7aceb8e92c274 100644 (file)
@@ -34,11 +34,14 @@ import org.simantics.db.Resource;
 import org.simantics.db.Session;\r
 import org.simantics.db.VirtualGraph;\r
 import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.ParametrizedPrimitiveRead;\r
 import org.simantics.db.common.request.ReadRequest;\r
 import org.simantics.db.common.request.WriteRequest;\r
 import org.simantics.db.common.utils.Logger;\r
 import org.simantics.db.common.utils.NameUtils;\r
 import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.RuntimeDatabaseException;\r
+import org.simantics.db.procedure.Listener;\r
 import org.simantics.db.request.Read;\r
 import org.simantics.db.service.VirtualGraphSupport;\r
 import org.simantics.layer0.Layer0;\r
@@ -100,6 +103,42 @@ public class OldSysdynExperiment extends SysdynExperiment {
     public static OldSysdynExperiment getInstance() {\r
         return INSTANCE;\r
     }\r
+    \r
+    public class PublishExternalRead extends ParametrizedPrimitiveRead<OldSysdynExperiment,Integer> {\r
+\r
+       private int value = 0;\r
+       private Listener<Integer> listener = null;\r
+       \r
+               public PublishExternalRead(OldSysdynExperiment parameter) {\r
+                       super(parameter);\r
+               }\r
+\r
+               @Override\r
+               public void register(ReadGraph graph, Listener<Integer> procedure) {\r
+                       procedure.execute(value);\r
+                       if(procedure.isDisposed()) return;\r
+                       if(listener != null) throw new RuntimeDatabaseException("Internal error");\r
+                       listener = procedure;\r
+               }\r
+               \r
+               @Override\r
+               public void unregistered() {\r
+                       listener = null;\r
+               }\r
+               \r
+               public void fire() {\r
+                       value++;\r
+                       if(listener != null)\r
+                               listener.execute(value);\r
+               }\r
+       \r
+    }\r
+    \r
+    private PublishExternalRead publishRead = new PublishExternalRead(this);\r
+    \r
+    public int getPublishCounter(ReadGraph graph) throws DatabaseException {\r
+       return graph.syncRequest(publishRead);\r
+    }\r
 \r
     public SysdynResult getCurrentResult() {\r
         if(this.result == null)\r
@@ -870,7 +909,7 @@ public class OldSysdynExperiment extends SysdynExperiment {
      */\r
     @Override\r
     public void updateSubscriptions() {\r
-       if(!publishResults) return;\r
+       if(publishResults) publishRead.fire();\r
         for(VariableValueSubscription subscription : getListenerSnapshot())\r
             subscription.update();\r
         skippedVariableUpdate = false;\r
index f411138fcb30b38c56e9d8a2c4c168322377d3cd..76238491f7e8383c9f3cc6fba7e16eee6991bc25 100644 (file)
@@ -6,6 +6,7 @@ import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;\r
 import org.simantics.simulation.experiment.ExperimentState;\r
 import org.simantics.sysdyn.solver.ISolver;\r
+import org.simantics.utils.logging.TimeLogger;\r
 \r
 class SimulateDurationJob extends Job {\r
 \r
@@ -13,12 +14,14 @@ class SimulateDurationJob extends Job {
        private double duration;\r
        private final SysdynGameExperimentBase base;\r
        private final ISolver solver;\r
+       final private boolean asJob;\r
        \r
-       public SimulateDurationJob(SysdynGameExperimentBase base, String name, double duration) {\r
+       public SimulateDurationJob(SysdynGameExperimentBase base, String name, double duration, boolean asJob) {\r
                super(name);\r
                this.base = base;\r
                this.solver = base.getSolver();\r
                this.duration = duration;\r
+               this.asJob = asJob;\r
        }\r
 \r
        @Override\r
@@ -31,9 +34,12 @@ class SimulateDurationJob extends Job {
                if(base == null || base.getState() != ExperimentState.STOPPED)\r
                        return Status.OK_STATUS;\r
 \r
+               TimeLogger.resetTime();\r
+               \r
                long start = System.nanoTime();\r
                \r
-               base.changeState(ExperimentState.RUNNING);\r
+               if(asJob) base.changeState(ExperimentState.RUNNING);\r
+                       \r
                int nSteps = (int)(duration / base.stepLength); \r
                int work = 1 + nSteps * 3 + 2; // initialization + number of steps * number of phases per step + set result + call result listeners \r
 \r
@@ -87,7 +93,7 @@ class SimulateDurationJob extends Job {
 \r
                        base.resultsChanged(true);\r
                        monitor.worked(1);\r
-                       base.changeState(ExperimentState.STOPPED);\r
+                       if(asJob) base.changeState(ExperimentState.STOPPED);\r
 \r
                } catch (Exception e) {\r
                        e.printStackTrace();\r
@@ -97,6 +103,8 @@ class SimulateDurationJob extends Job {
                long end = System.nanoTime();\r
 //             System.err.println("simulate duration took " + 1e-6*(end-start) + "ms.");\r
 \r
+               TimeLogger.log("SimulateDuration");\r
+\r
                return Status.OK_STATUS;\r
                \r
        }\r
index 6d8d4a927b865daae22257b8491891ca3c880388..53aec601544946a7ca15b42d9dcb5c7e64799577 100644 (file)
@@ -77,7 +77,7 @@ public class SysdynGameExperiment extends SysdynGameExperimentBase {
                if(control == null)\r
                        control = new FMUControlJNI();\r
                \r
-               results = new THashMap<String, TDoubleArrayList>();\r
+               results = new TDoubleArrayList[results.length];\r
                \r
        }\r
        \r
@@ -333,6 +333,8 @@ public class SysdynGameExperiment extends SysdynGameExperimentBase {
             for(int i = 0; i < subscription.length; i++) {\r
                 subscriptionIndexes.put(subscription[i], i);\r
             }\r
+            \r
+            results = new TDoubleArrayList[subscription.length];\r
 \r
             // Initialize container for current simulation results\r
             currentValues = new double[subscription.length];\r
index a0338fdc2d960b7cfa01ee2defec3f0b0a8e518f..23b17f6350e8fabb2a1be7d708e56697fae90400 100644 (file)
@@ -57,7 +57,7 @@ public class SysdynGameExperimentInternal extends SysdynGameExperimentBase {
                \r
                super.init(g);\r
                \r
-               results = new THashMap<String, TDoubleArrayList>();\r
+               results = null;\r
 \r
                solver = new InternalSolver(this, sysdynModel, true, new ISolverMonitor() {\r
                        \r
@@ -106,6 +106,8 @@ public class SysdynGameExperimentInternal extends SysdynGameExperimentBase {
             // Initialize container for current simulation results\r
             currentValues = new double[subscription.length];\r
             \r
+            results = new TDoubleArrayList[currentValues.length];\r
+            \r
             // subscribe all variables\r
             //solver.subscribe(subscription); \r
 \r
index b2c4b7164a0582dcd6c3d030bf4b7652684f1080..c82366cbc6e6b1675a0e0dd3c5ac6e9a0534dfb8 100644 (file)
@@ -22,6 +22,7 @@ import org.simantics.db.common.request.UniqueRead;
 import org.simantics.db.common.request.WriteRequest;\r
 import org.simantics.db.common.utils.ListUtils;\r
 import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.exception.MissingVariableException;\r
 import org.simantics.db.layer0.util.EvaluatingListener;\r
 import org.simantics.db.layer0.util.EvaluatingListener.Criterion;\r
 import org.simantics.db.layer0.util.EvaluatingListener.Evaluation;\r
@@ -631,8 +632,7 @@ public class DocumentationUtils {
                try {\r
                    Pair<String, String> nameAndIndices = splitToNameAndIndices(parameter2);\r
                    org.simantics.db.layer0.variable.Variable v = parameter.browsePossible(graph, "/" + nameAndIndices.first + "#value#" + nameAndIndices.second);\r
-                   //if(v == null) throw new MissingVariableException("No variable for SysDyn reference path: " + parameter2);\r
-                   if(v == null) return null;\r
+                   if(v == null) throw new MissingVariableException("No variable for SysDyn reference path: " + parameter2 + " from variable " + parameter.getURI(graph) );\r
                    return v;\r
                } catch (Throwable e) {\r
                        throw new DatabaseException(e);\r
@@ -651,10 +651,13 @@ public class DocumentationUtils {
         \r
     }\r
     \r
-    \r
     public static org.simantics.db.layer0.variable.Variable lastValueIndexed(ReadGraph graph, org.simantics.db.layer0.variable.Variable run, String path) throws DatabaseException {\r
-       if(run == null) return null;\r
+       \r
+       if(run == null) \r
+               throw new DatabaseException("Input variable (run) is null");\r
+       \r
        return graph.syncRequest(new LastValueIndexed(run, path));\r
+                       \r
     }    \r
     \r
     public static org.simantics.db.layer0.variable.Variable equation(ReadGraph graph, org.simantics.db.layer0.variable.Variable input, String path) throws DatabaseException {\r