X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fchr%2Fplanning%2FQueryPlanningContext.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fchr%2Fplanning%2FQueryPlanningContext.java;h=c083b8fc9693a41b25ba3165bb2df6f5096c65ea;hb=a8758de5bc19e5adb3f618d3038743a164f09912;hp=0000000000000000000000000000000000000000;hpb=12d9af17384d960b75d58c3935d2b7b46d93e87b;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/QueryPlanningContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/QueryPlanningContext.java new file mode 100644 index 000000000..c083b8fc9 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/QueryPlanningContext.java @@ -0,0 +1,240 @@ +package org.simantics.scl.compiler.elaboration.chr.planning; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; +import org.simantics.scl.compiler.compilation.CompilationContext; +import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; +import org.simantics.scl.compiler.elaboration.chr.plan.AccessFactOp; +import org.simantics.scl.compiler.elaboration.chr.plan.ClaimOp; +import org.simantics.scl.compiler.elaboration.chr.plan.ExecuteOp; +import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp; +import org.simantics.scl.compiler.elaboration.chr.planning.items.CheckPrePlanItem; +import org.simantics.scl.compiler.elaboration.chr.planning.items.EqualsPrePlanItem; +import org.simantics.scl.compiler.elaboration.chr.planning.items.GenericPrePlanItem; +import org.simantics.scl.compiler.elaboration.chr.planning.items.MemberPrePlanItem; +import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint; +import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation; +import org.simantics.scl.compiler.elaboration.expressions.EApplyType; +import org.simantics.scl.compiler.elaboration.expressions.EConstant; +import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant; +import org.simantics.scl.compiler.elaboration.expressions.ELiteral; +import org.simantics.scl.compiler.elaboration.expressions.EVariable; +import org.simantics.scl.compiler.elaboration.expressions.Expression; +import org.simantics.scl.compiler.elaboration.expressions.Variable; + +import gnu.trove.impl.Constants; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.procedure.TIntProcedure; +import gnu.trove.set.hash.TIntHashSet; + +public class QueryPlanningContext { + CompilationContext compilationContext; + public PlanPriorityQueue priorityQueue = new PlanPriorityQueue(); + ArrayList variables; + TObjectIntHashMap variableMap; + ArrayList> itemsContainingVariable; + ArrayList planOps = new ArrayList(); + + public QueryPlanningContext(CompilationContext compilationContext, Variable[] variables) { + this.compilationContext = compilationContext; + this.variables = new ArrayList(variables.length*2); + this.variableMap = new TObjectIntHashMap(variables.length, Constants.DEFAULT_LOAD_FACTOR, -1); + itemsContainingVariable = new ArrayList>(variables.length*2); + for(Variable variable : variables) + addVariable(variable); + } + + private void addVariable(Variable variable) { + int id = variables.size(); + variables.add(variable); + variableMap.put(variable, id); + itemsContainingVariable.add(new ArrayList(2)); + } + + public void add(CHRLiteral literal, int secondaryPriority) { + if(literal.relation instanceof SpecialCHRRelation) { + switch((SpecialCHRRelation)literal.relation) { + case CHECK: + addCheck(literal.location, literal.parameters[0], secondaryPriority); + return; + case EQUALS: + addGenericEquals(literal.location, literal.parameters[0], literal.parameters[1], secondaryPriority); + return; + case MEMBER: + addMember(literal.location, literal.parameters[0], literal.parameters[1], secondaryPriority); + return; + case EXECUTE: + throw new InternalCompilerError(literal.location, "EXECUTE constraint is not allowed in query compilation."); + } + } + + addGenericConstraint(literal, secondaryPriority); + } + + private TIntHashSet getVars(Expression expression, int initialCapacity) { + TIntHashSet variableSet = new TIntHashSet(initialCapacity); + expression.collectVars(variableMap, variableSet); + return variableSet; + } + + private TIntHashSet[] getVars(Expression[] expressions, int initialCapacity) { + TIntHashSet[] variableSets = new TIntHashSet[expressions.length]; + for(int i=0;i getPlanOps() { + return planOps; + } + + private final TIntProcedure BIND_PROCEDURE = new TIntProcedure() { + @Override + public boolean execute(int variableId) { + ArrayList l = itemsContainingVariable.get(variableId); + for(PrePlanItem item : l) + item.variableSolved(QueryPlanningContext.this, variableId); + l.clear(); + return true; + } + }; + + public void bind(TIntHashSet variableSet) { + variableSet.forEach(BIND_PROCEDURE); + } + + public void addPlanOp(PlanOp planOp) { + planOps.add(planOp); + } + + public CompilationContext getCompilationContext() { + return compilationContext; + } + + public void activate(CHRLiteral literal, Expression inputFact, int secondaryPriority) { + Variable[] variables = new Variable[literal.parameters.length]; + for(int i=0;i