]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / scl / GraphRelation.java
diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java
new file mode 100644 (file)
index 0000000..807d44a
--- /dev/null
@@ -0,0 +1,136 @@
+package org.simantics.modeling.scl;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
+import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;\r
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
+import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;\r
+import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;\r
+import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+\r
+public class GraphRelation implements SCLRelation {\r
+\r
+    Resource relation;\r
+    double relationSelectivity;\r
+    Resource inverseRelation;\r
+    double inverseRelationSelectivity;\r
+    \r
+    public GraphRelation(Resource relation, double relationSelectivity,\r
+            Resource inverseRelation, double inverseRelationSelectivity) {\r
+        this.relation = relation;\r
+        this.relationSelectivity = relationSelectivity;\r
+        this.inverseRelation = inverseRelation;\r
+        this.inverseRelationSelectivity = inverseRelationSelectivity;\r
+    }\r
+\r
+    @Override\r
+    public TVar[] getTypeVariables() {\r
+        return TVar.EMPTY_ARRAY;\r
+    }\r
+    \r
+    private static final Type[] PARAMETER_TYPES = new Type[] { Types.RESOURCE, Types.RESOURCE };\r
+    \r
+    @Override\r
+    public Type[] getParameterTypes() {\r
+        return PARAMETER_TYPES;\r
+    }\r
+\r
+    @Override\r
+    public double getSelectivity(int boundVariables) {\r
+        switch(boundVariables) {\r
+        case FF: return Double.POSITIVE_INFINITY;\r
+        case BF: return relationSelectivity;\r
+        case FB: return inverseRelation == null ? Double.POSITIVE_INFINITY : inverseRelationSelectivity;\r
+        case BB: return 0.1;\r
+        default: throw new IllegalArgumentException();\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    public int getRequiredVariablesMask() {\r
+        return inverseRelation == null ? BF : FF;\r
+    }\r
+    \r
+    private static final Name GET_OBJECTS = Name.create("Simantics/DB", "#");\r
+    private static final Name HAS_STATEMENT = Name.create("Simantics/DB", "existsStatement3");\r
+    \r
+    @Override\r
+    public void generate(long location, QueryCompilationContext context,\r
+            Type[] typeParameters, Variable[] parameters, int boundVariables) {\r
+        switch(boundVariables) {\r
+        case BF: \r
+            context.iterateList(parameters[1], new EApply(\r
+                    Locations.NO_LOCATION,\r
+                    Types.READ_GRAPH,\r
+                    context.getTypingContext().getConstant(GET_OBJECTS),\r
+                    new EVariable(parameters[0]),\r
+                    new EExternalConstant(relation, Types.RESOURCE)\r
+                    ));\r
+            break;\r
+        case FB:\r
+            if(inverseRelation == null)\r
+                throw new IllegalArgumentException();\r
+            context.iterateList(parameters[0], new EApply(\r
+                    Locations.NO_LOCATION,\r
+                    Types.READ_GRAPH,\r
+                    context.getTypingContext().getConstant(GET_OBJECTS),\r
+                    new EVariable(parameters[1]),\r
+                    new EExternalConstant(inverseRelation, Types.RESOURCE)\r
+                    ));\r
+            break;\r
+        case BB:\r
+            context.condition(\r
+                    inverseRelation == null || relationSelectivity <= inverseRelationSelectivity\r
+                    ? new EApply(\r
+                            Locations.NO_LOCATION,\r
+                            Types.READ_GRAPH,\r
+                            context.getTypingContext().getConstant(HAS_STATEMENT),\r
+                            new Expression[] {\r
+                                new EVariable(parameters[0]),\r
+                                new EExternalConstant(relation, Types.RESOURCE),\r
+                                new EVariable(parameters[1])\r
+                            }\r
+                            )\r
+                    : new EApply(\r
+                            Locations.NO_LOCATION,\r
+                            Types.READ_GRAPH,\r
+                            context.getTypingContext().getConstant(HAS_STATEMENT),\r
+                            new Expression[] {\r
+                                new EVariable(parameters[1]),\r
+                                new EExternalConstant(inverseRelation, Types.RESOURCE),\r
+                                new EVariable(parameters[0])\r
+                            }\r
+                            ));\r
+            break;\r
+        default: throw new IllegalArgumentException();\r
+        }\r
+    }\r
+\r
+    private static final Name CLAIM = Name.create("Simantics/DB", "claim");\r
+    \r
+    @Override\r
+    public Expression generateEnforce(long location, EnforcingContext context,\r
+            Type[] typeParameters, Variable[] parameters) {\r
+        return new EApply(\r
+                Locations.NO_LOCATION,\r
+                Types.WRITE_GRAPH,\r
+                context.getTypingContext().getConstant(CLAIM),\r
+                new EVariable(parameters[0]),\r
+                new EExternalConstant(relation, Types.RESOURCE),\r
+                new EVariable(parameters[1])\r
+                );\r
+    }\r
+\r
+    @Override\r
+    public int getPhase() {\r
+        return 0;\r
+    }\r
+\r
+}\r