]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
(refs #5441) Global model cache for speeding up deployed model initialization
authorvillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 27 Oct 2014 07:18:56 +0000 (07:18 +0000)
committervillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 27 Oct 2014 07:18:56 +0000 (07:18 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@30490 ac1ea38d-2e2b-0410-8846-a27921b304fc

fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Assignment.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/CodeCache.java [new file with mode: 0644]
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Environment.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Model.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ParameterDeclaration.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Parser.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Solver.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/VariableDeclaration.java

index 67752379c360df09395883314cd46caa9e80ebdb..2a49d408bdf4f875ec1440536bc00ce9aaea828d 100644 (file)
@@ -18,7 +18,7 @@ public class Assignment {
        public Variable target;\r
        public IExpression[] subscripts;\r
     public IExpression expression;\r
-    public boolean assigned = false;\r
+    //public boolean assigned = false;\r
     public boolean isConstant = false;\r
     \r
     public Assignment(IFrame model, Variable target, IExpression[] subscripts, IExpression expression) {\r
@@ -44,13 +44,13 @@ public class Assignment {
        }\r
     }\r
     \r
-    public void assign(IEnvironment env) {\r
+    public void assign(Environment env) {\r
        try {\r
                        Object value = expression.evaluate(env);\r
                        if(value != null) {\r
                                validate(target, value);\r
                                target.assign(env, subscripts, value);\r
-                               assigned = true;\r
+                               env.setAssigned(this);\r
                        }\r
        } catch (ExecutionException e) {\r
                if(model instanceof Model) {\r
diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/CodeCache.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/CodeCache.java
new file mode 100644 (file)
index 0000000..f43cb99
--- /dev/null
@@ -0,0 +1,60 @@
+package fi.semantum.sysdyn.solver;\r
+\r
+import java.io.StringReader;\r
+import java.util.HashMap;\r
+import java.util.LinkedList;\r
+import java.util.Map;\r
+\r
+import fi.semantum.sysdyn.solver.Model.Globals;\r
+import fi.semantum.sysdyn.solver.parser.ModelParser;\r
+import fi.semantum.sysdyn.solver.parser.ParseException;\r
+import fi.semantum.sysdyn.solver.parser.SimpleNode;\r
+\r
+public class CodeCache {\r
+\r
+       final static int CACHE_SIZE = 5;\r
+       \r
+       private static CodeCache INSTANCE;\r
+       \r
+       final Map<String,Model> models = new HashMap<String,Model>();\r
+       final LinkedList<String> codes = new LinkedList<String>();\r
+       \r
+       public static CodeCache getInstance() {\r
+               if(INSTANCE == null) INSTANCE = new CodeCache();\r
+               return INSTANCE;\r
+       }\r
+       \r
+       private CodeCache() {\r
+       }\r
+       \r
+       public Model getModel(String code) throws ParseException {\r
+               \r
+               Model model = models.get(code);\r
+               if(model == null) {\r
+\r
+                       StringReader reader = new StringReader(code);\r
+                       ModelParser modelParser = new ModelParser(reader);\r
+                       SimpleNode n = (SimpleNode)modelParser.stored_definition();\r
+\r
+                   Parser parser = new Parser();\r
+                   model = new Model(new Globals(), "", false);\r
+                       parser.walk(n, 0, model);\r
+                       \r
+                       model.prepare();\r
+                       model.prepareFunctions();\r
+                       model.sortAssignments();\r
+                       \r
+                       models.put(code, model);\r
+                       if(codes.size() == 5) {\r
+                               String last = codes.removeLast();\r
+                               models.remove(last);\r
+                               codes.addFirst(code);\r
+                       }\r
+                       \r
+               }\r
+               \r
+               return model;\r
+               \r
+       }\r
+       \r
+}\r
index 135410d7283d6e4f1abd23901ffdc2232c0e5ab2..247a93d1ec1de650078a55ef25c9ad58992f9f12 100644 (file)
@@ -734,4 +734,14 @@ final public class Environment implements IEnvironment, ISystem {
                put(index, value);\r
        }\r
        \r
+       public void setAssigned(Object ass) {\r
+               assigned.add(ass);\r
+       }\r
+       \r
+       public boolean isAssigned(Object o) {\r
+               return assigned.contains(o);\r
+       }\r
+       \r
+       private Set<Object> assigned = new HashSet<Object>();\r
+       \r
 }\r
index ab861d89034a5da8b5726e88d7f5a42ba512508c..ff2527ff19c28cd7304f1b0bfc3514028c4f6c85 100644 (file)
@@ -12,11 +12,19 @@ package fi.semantum.sysdyn.solver;
 \r
 import java.util.ArrayList;\r
 import java.util.Arrays;\r
+import java.util.Collections;\r
+import java.util.Comparator;\r
 import java.util.HashMap;\r
+import java.util.HashSet;\r
 import java.util.List;\r
 import java.util.Map;\r
+import java.util.Set;\r
 import java.util.TreeMap;\r
 \r
+import org.simantics.utils.datastructures.MapList;\r
+\r
+import fi.semantum.sysdyn.solver.IExpression.ExpressionVisitor;\r
+\r
 class Model implements IFrame {\r
        \r
        static class Globals {\r
@@ -41,9 +49,11 @@ class Model implements IFrame {
        public final Globals globals;\r
        \r
        public int line = -1;\r
-       public String name;\r
        public boolean isEnumClass;\r
        \r
+       private String name;\r
+       private int size;\r
+       \r
        public Model(Globals globals, String name, boolean isEnumClass) {\r
                this.globals = globals;\r
                this.name = name;\r
@@ -333,24 +343,28 @@ class Model implements IFrame {
                \r
                if(!done) throw new IllegalStateException();\r
                \r
-               int nextIndex = 0;\r
+               size = 0;\r
                for(Map.Entry<String, VariableBase> entry : names.entrySet()) {\r
                        VariableBase base = entry.getValue();\r
-                       base.index = nextIndex;\r
+                       base.index = size;\r
                        if(PRINT)\r
                                System.err.println("Variable: " + entry.getKey() + " " + base.index + " " + Arrays.toString(base.dimensions));\r
                        int dim = base.dimension();\r
                        if(dim == -1) dim = 1;\r
-                       nextIndex += dim;\r
+                       size += dim;\r
                }\r
                \r
                if(PRINT)\r
                        System.err.println("==================");\r
                \r
-               return nextIndex;\r
+               return size;\r
                \r
        }\r
        \r
+       public int getSize() {\r
+               return size;\r
+       }\r
+       \r
        public void prettyPrint() {\r
 \r
                System.err.println("initials");\r
@@ -441,4 +455,63 @@ class Model implements IFrame {
                \r
        }\r
        \r
+       public void prepareFunctions() {\r
+               \r
+               for(Fn fn : functions.values()) {\r
+                       if(fn instanceof Function)\r
+                               ((Function)fn).prepare();\r
+               }\r
+\r
+       }\r
+       \r
+       public void sortAssignments() {\r
+\r
+               final MapList<String,Assignment> asses = new MapList<String,Assignment>();\r
+               for(Assignment ass : assignments) asses.add(ass.target.base.name, ass);\r
+               \r
+               final List<VariableBase> found = new ArrayList<VariableBase>();\r
+               final Set<String> visited = new HashSet<String>();\r
+\r
+               ExpressionVisitor sortVisitor = new ExpressionVisitor() {\r
+                       @Override\r
+                       public void visit(IExpression expression) {\r
+                               if(expression instanceof Variable) {\r
+                                       Variable var = (Variable)expression;\r
+                                       if(visited.add(var.base.name)) {\r
+                                               for(Assignment ass : asses.getValues(var.base.name)) {\r
+                                                       ass.expression.accept(this);\r
+                                                       if(ass.subscripts != null)\r
+                                                               for(IExpression e : ass.subscripts) e.accept(this);\r
+                                               }\r
+                                               found.add(var.base);\r
+                                       }\r
+                               }\r
+                       }\r
+               };\r
+               \r
+               // Sort assignments\r
+               for(Assignment ass : assignments) {\r
+                       ass.target.accept(sortVisitor);\r
+               }\r
+\r
+               Collections.sort(assignments, new Comparator<Assignment>() {\r
+\r
+                       @Override\r
+                       public int compare(Assignment o1, Assignment o2) {\r
+                               int i1 = found.indexOf(o1.target.base); \r
+                               int i2 = found.indexOf(o2.target.base);\r
+                               if(i1 < i2) return -1;\r
+                               else if (i1 > i2) return 1;\r
+                               return 0;\r
+                       }\r
+\r
+                       \r
+               });\r
+               \r
+               assignmentArray = assignments.toArray(new Assignment[assignments.size()]);\r
+               derivativeArray = derivatives.toArray(new Assignment[derivatives.size()]);\r
+               parameterArray = parameters.toArray(new ParameterDeclaration[parameters.size()]);\r
+               \r
+       }\r
+       \r
 }
\ No newline at end of file
index 72cbab5e08ade7e3be89addaf70c2c97deba1e04..45ec0f0b5a22b8447c6b1e50fafbb914b5a26903 100644 (file)
@@ -17,7 +17,7 @@ public class ParameterDeclaration implements IExpression {
 \r
        public Variable variable;\r
        public IExpression modification;\r
-       public boolean assigned = false;\r
+//     public boolean assigned = false;\r
 \r
        public ParameterDeclaration(Variable variable, IExpression modification) {\r
                this.variable = variable;\r
index 32695d7417049f5454c02d48c93c459925b87dd5..3fe43ba4ec2baee554c745d0709de73f1b9dcc35 100644 (file)
@@ -365,7 +365,6 @@ public class Parser {
                                SimpleNode child = (SimpleNode)n.jjtGetChild(0);\r
                                String packagePath = getPackagePath(child);\r
                                String functionName = packagePath + child.op;\r
-                               System.err.println("function " + functionName + " at line " + child.line);\r
                                ArrayList<IStatement> stms2 = new ArrayList<IStatement>();\r
                                Function function = new Function(functionName, new StatementList(stms2), child.line);\r
                                ArrayList<Object> composition = (ArrayList<Object>)walk(child, indent+2, function);\r
index 80484a5608303380faa4de56761e03b812d1fe79..d33e12cc4671d2b762d8fd4af4333706940e2ee6 100644 (file)
  *******************************************************************************/\r
 package fi.semantum.sysdyn.solver;\r
 \r
-import java.io.StringReader;\r
 import java.util.ArrayList;\r
-import java.util.Collections;\r
-import java.util.Comparator;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
 \r
-import org.simantics.utils.datastructures.MapList;\r
-\r
-import fi.semantum.sysdyn.solver.IExpression.ExpressionVisitor;\r
-import fi.semantum.sysdyn.solver.Model.Globals;\r
-import fi.semantum.sysdyn.solver.parser.ModelParser;\r
 import fi.semantum.sysdyn.solver.parser.SimpleNode;\r
 \r
 public class Solver {\r
@@ -62,52 +51,6 @@ public class Solver {
                ready = false;\r
        }\r
        \r
-       private void sortAssignments() {\r
-\r
-               final MapList<String,Assignment> asses = new MapList<String,Assignment>();\r
-               for(Assignment ass : model.assignments) asses.add(ass.target.base.name, ass);\r
-               \r
-               final List<VariableBase> found = new ArrayList<VariableBase>();\r
-               final Set<String> visited = new HashSet<String>();\r
-\r
-               ExpressionVisitor sortVisitor = new ExpressionVisitor() {\r
-                       @Override\r
-                       public void visit(IExpression expression) {\r
-                               if(expression instanceof Variable) {\r
-                                       Variable var = (Variable)expression;\r
-                                       if(visited.add(var.base.name)) {\r
-                                               for(Assignment ass : asses.getValues(var.base.name)) {\r
-                                                       ass.expression.accept(this);\r
-                                                       if(ass.subscripts != null)\r
-                                                               for(IExpression e : ass.subscripts) e.accept(this);\r
-                                               }\r
-                                               found.add(var.base);\r
-                                       }\r
-                               }\r
-                       }\r
-               };\r
-               \r
-               // Sort assignments\r
-               for(Assignment ass : model.assignments) {\r
-                       ass.target.accept(sortVisitor);\r
-               }\r
-\r
-               Collections.sort(model.assignments, new Comparator<Assignment>() {\r
-\r
-                       @Override\r
-                       public int compare(Assignment o1, Assignment o2) {\r
-                               int i1 = found.indexOf(o1.target.base); \r
-                               int i2 = found.indexOf(o2.target.base);\r
-                               if(i1 < i2) return -1;\r
-                               else if (i1 > i2) return 1;\r
-                               return 0;\r
-                       }\r
-\r
-                       \r
-               });\r
-               \r
-       }\r
-\r
        private SimpleNode n;\r
        private String codeCache = null;\r
        \r
@@ -133,37 +76,32 @@ public class Solver {
                \r
                long startNanos = System.nanoTime();\r
                \r
-               if(!input.equals(codeCache)) {\r
+               model = CodeCache.getInstance().getModel(input);\r
                \r
-                       StringReader reader = new StringReader(input);\r
-                       ModelParser modelParser = new ModelParser(reader);\r
-                       n = (SimpleNode)modelParser.stored_definition();\r
+//             if(!input.equals(codeCache)) {\r
+//             \r
+//                     StringReader reader = new StringReader(input);\r
+//                     ModelParser modelParser = new ModelParser(reader);\r
+//                     n = (SimpleNode)modelParser.stored_definition();\r
+//\r
+//                 Parser parser = new Parser();\r
+//                 model = new Model(new Globals(), "", false);\r
+//                     parser.walk(n, 0, model);\r
+//                     \r
+//                     model.prepare();\r
+//                     model.prepareFunctions();\r
+//                     model.sortAssignments();\r
+//\r
+//                     codeCache = input;\r
+//\r
+//             }\r
                \r
-               }\r
-\r
-           Parser parser = new Parser();\r
-           model = new Model(new Globals(), "", false);\r
-               parser.walk(n, 0, model);\r
-               codeCache = input;\r
-\r
-               env = new Environment(model, defaultStep, start);\r
+               int size = model.getSize();\r
                \r
-               int size = model.prepare();\r
+               env = new Environment(model, defaultStep, start);\r
                env.setSize(size);\r
-               \r
-               for(Fn fn : model.functions.values()) {\r
-                       if(fn instanceof Function)\r
-                               ((Function)fn).prepare();\r
-               }\r
-               \r
                env.valueTable = new Object[size+STACK_SIZE];\r
                \r
-               sortAssignments();\r
-               \r
-               model.assignmentArray = model.assignments.toArray(new Assignment[model.assignments.size()]);\r
-               model.derivativeArray = model.derivatives.toArray(new Assignment[model.derivatives.size()]);\r
-               model.parameterArray = model.parameters.toArray(new ParameterDeclaration[model.parameters.size()]);\r
-               \r
                newValues = new Object[Math.max(model.assignments.size(),model.derivatives.size())];\r
                \r
                int condition = 1;\r
@@ -171,6 +109,10 @@ public class Solver {
                \r
                StringBuilder errors = null;\r
                \r
+               ArrayList<Assignment> assignments = new ArrayList<Assignment>();\r
+               assignments.addAll(model.assignments);\r
+               assignments.addAll(model.initials);\r
+\r
                while(condition > 0 && loops++ < MAX_LOOPS) {\r
 \r
                        if(loops == MAX_LOOPS) errors = new StringBuilder();\r
@@ -183,11 +125,11 @@ public class Solver {
 \r
                        for(ParameterDeclaration pd : model.parameters) {\r
                                try {\r
-                                       if(!pd.assigned) {\r
+                                       if(!env.isAssigned(pd)) {\r
                                                Object value = pd.modification.evaluate(env);\r
                                                validate(pd.variable, value);\r
                                                pd.variable.assign(env, null, value);\r
-                                               pd.assigned = true;\r
+                                               env.setAssigned(pd);\r
                                        }\r
                                } catch (Exception e) {\r
                                        String error = "  -" + pd.variable.toString() + ": " + e.getMessage();\r
@@ -203,13 +145,9 @@ public class Solver {
                                }\r
                        }\r
                        \r
-                       ArrayList<Assignment> assignments = new ArrayList<Assignment>();\r
-                       assignments.addAll(model.assignments);\r
-                       assignments.addAll(model.initials);\r
-\r
                        for(VariableDeclaration vd : model.variables) {\r
                                try {\r
-                                       if(!vd.assigned) {\r
+                                       if(!env.isAssigned(vd)) {\r
                                                for(Argument arg : vd.modification.args) {\r
                                                        if(arg.name.endsWith("start")) {\r
                                                                Object value = arg.modification.evaluate(env);\r
@@ -233,7 +171,7 @@ public class Solver {
                                                                // efficient way\r
                                                                for (Assignment a : assignments) {\r
                                                                        if (vd.variable.base.equals(a.target.base)) {\r
-                                                                               a.assigned = true;\r
+                                                                               env.setAssigned(a);\r
                                                                        }\r
                                                                }\r
                                                        }\r
@@ -255,7 +193,7 @@ public class Solver {
                        \r
                        for(Assignment ass : assignments) {\r
                                try {\r
-                                       if(!ass.assigned)\r
+                                       if(!env.isAssigned(ass))\r
                                                ass.assign(env);\r
                                } catch (Exception e) {\r
                                        String error = "  -" + ass.target.toString() + ": " + e.getMessage();\r
index 83958d394b8102aa4ad8fb0cf397ca1e239f5d86..eb92bfa5f2ea0df53017e5288ac0f29dcc3708af 100644 (file)
@@ -19,7 +19,7 @@ public class VariableDeclaration implements IExpression {
        public String direction;\r
        public String type;\r
        public ArgumentList modification;\r
-       public boolean assigned = false;\r
+//     public boolean assigned = false;\r
 \r
        public VariableDeclaration(Variable variable, String direction, String type, ArgumentList modification) {\r
                this.variable = variable;\r