Search in sources :

Example 61 with RuleTerminalNode

use of org.drools.core.reteoo.RuleTerminalNode in project drools by kiegroup.

the class PhreakBranchNode method doLeftUpdates.

public void doLeftUpdates(ConditionalBranchNode branchNode, ConditionalBranchMemory cbm, LeftTupleSink sink, InternalAgenda agenda, TupleSets<LeftTuple> srcLeftTuples, TupleSets<LeftTuple> trgLeftTuples, TupleSets<LeftTuple> stagedLeftTuples, RuleExecutor executor) {
    ConditionalBranchEvaluator branchEvaluator = branchNode.getBranchEvaluator();
    RuleAgendaItem ruleAgendaItem = executor.getRuleAgendaItem();
    int salienceInt = 0;
    Salience salience = ruleAgendaItem.getRule().getSalience();
    if (!salience.isDynamic()) {
        salienceInt = ruleAgendaItem.getRule().getSalience().getValue();
        salience = null;
    }
    for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
        LeftTuple next = leftTuple.getStagedNext();
        BranchTuples branchTuples = getBranchTuples(sink, leftTuple);
        RuleTerminalNode oldRtn = null;
        if (branchTuples.rtnLeftTuple != null) {
            oldRtn = branchTuples.rtnLeftTuple.getTupleSink();
        }
        ConditionalExecution conditionalExecution = branchEvaluator.evaluate(leftTuple, agenda.getWorkingMemory(), cbm.context);
        RuleTerminalNode newRtn = null;
        boolean breaking = false;
        if (conditionalExecution != null) {
            newRtn = (RuleTerminalNode) conditionalExecution.getSink().getFirstLeftTupleSink();
            breaking = conditionalExecution.isBreaking();
        }
        // Handle conditional branches
        if (oldRtn != null) {
            if (newRtn == null) {
                // old exits, new does not, so delete
                if (branchTuples.rtnLeftTuple.getMemory() != null) {
                    executor.removeLeftTuple(branchTuples.rtnLeftTuple);
                }
                PhreakRuleTerminalNode.doLeftDelete(agenda, executor, branchTuples.rtnLeftTuple);
            } else if (newRtn == oldRtn) {
                // old and new on same branch, so update
                PhreakRuleTerminalNode.doLeftTupleUpdate(newRtn, executor, agenda, salienceInt, salience, branchTuples.rtnLeftTuple);
            } else {
                // old and new on different branches, delete one and insert the other
                if (branchTuples.rtnLeftTuple.getMemory() != null) {
                    executor.removeLeftTuple(branchTuples.rtnLeftTuple);
                }
                PhreakRuleTerminalNode.doLeftDelete(agenda, executor, branchTuples.rtnLeftTuple);
                branchTuples.rtnLeftTuple = newRtn.createLeftTuple(leftTuple, newRtn, leftTuple.getPropagationContext(), true);
                PhreakRuleTerminalNode.doLeftTupleInsert(newRtn, executor, agenda, executor.getRuleAgendaItem(), salienceInt, salience, branchTuples.rtnLeftTuple);
            }
        } else if (newRtn != null) {
            // old does not exist, new exists, so insert
            branchTuples.rtnLeftTuple = newRtn.createLeftTuple(leftTuple, newRtn, leftTuple.getPropagationContext(), true);
            PhreakRuleTerminalNode.doLeftTupleInsert(newRtn, executor, agenda, executor.getRuleAgendaItem(), salienceInt, salience, branchTuples.rtnLeftTuple);
        }
        // Handle main branch
        if (branchTuples.mainLeftTuple != null) {
            normalizeStagedTuples(stagedLeftTuples, branchTuples.mainLeftTuple);
            if (!breaking) {
                // child exist, new one does, so update
                trgLeftTuples.addUpdate(branchTuples.mainLeftTuple);
            } else {
                // child exist, new one does not, so delete
                trgLeftTuples.addDelete(branchTuples.mainLeftTuple);
            }
        } else if (!breaking) {
            // child didn't exist, new one does, so insert
            trgLeftTuples.addInsert(sink.createLeftTuple(leftTuple, sink, leftTuple.getPropagationContext(), true));
        }
        leftTuple.clearStaged();
        leftTuple = next;
    }
}
Also used : ConditionalBranchEvaluator(org.drools.core.reteoo.ConditionalBranchEvaluator) ConditionalExecution(org.drools.core.reteoo.ConditionalBranchEvaluator.ConditionalExecution) Salience(org.drools.core.spi.Salience) LeftTuple(org.drools.core.reteoo.LeftTuple) RuleTerminalNode(org.drools.core.reteoo.RuleTerminalNode)

Example 62 with RuleTerminalNode

use of org.drools.core.reteoo.RuleTerminalNode in project drools by kiegroup.

the class PhreakBranchNode method doLeftInserts.

public void doLeftInserts(ConditionalBranchNode branchNode, ConditionalBranchMemory cbm, LeftTupleSink sink, InternalAgenda agenda, TupleSets<LeftTuple> srcLeftTuples, TupleSets<LeftTuple> trgLeftTuples, RuleExecutor executor) {
    ConditionalBranchEvaluator branchEvaluator = branchNode.getBranchEvaluator();
    RuleAgendaItem ruleAgendaItem = executor.getRuleAgendaItem();
    int salienceInt = 0;
    Salience salience = ruleAgendaItem.getRule().getSalience();
    if (!salience.isDynamic()) {
        salienceInt = ruleAgendaItem.getRule().getSalience().getValue();
        salience = null;
    }
    for (LeftTuple leftTuple = srcLeftTuples.getInsertFirst(); leftTuple != null; ) {
        LeftTuple next = leftTuple.getStagedNext();
        boolean breaking = false;
        ConditionalExecution conditionalExecution = branchEvaluator.evaluate(leftTuple, agenda.getWorkingMemory(), cbm.context);
        boolean useLeftMemory = RuleNetworkEvaluator.useLeftMemory(branchNode, leftTuple);
        if (conditionalExecution != null) {
            RuleTerminalNode rtn = (RuleTerminalNode) conditionalExecution.getSink().getFirstLeftTupleSink();
            LeftTuple branchedLeftTuple = rtn.createLeftTuple(leftTuple, rtn, leftTuple.getPropagationContext(), useLeftMemory);
            PhreakRuleTerminalNode.doLeftTupleInsert(rtn, executor, agenda, executor.getRuleAgendaItem(), salienceInt, salience, branchedLeftTuple);
            breaking = conditionalExecution.isBreaking();
        }
        if (!breaking) {
            trgLeftTuples.addInsert(sink.createLeftTuple(leftTuple, sink, leftTuple.getPropagationContext(), useLeftMemory));
        }
        leftTuple.clearStaged();
        leftTuple = next;
    }
}
Also used : ConditionalBranchEvaluator(org.drools.core.reteoo.ConditionalBranchEvaluator) ConditionalExecution(org.drools.core.reteoo.ConditionalBranchEvaluator.ConditionalExecution) Salience(org.drools.core.spi.Salience) LeftTuple(org.drools.core.reteoo.LeftTuple) RuleTerminalNode(org.drools.core.reteoo.RuleTerminalNode)

Example 63 with RuleTerminalNode

use of org.drools.core.reteoo.RuleTerminalNode in project drools by kiegroup.

the class NamedConsequenceBuilder method build.

public void build(BuildContext context, BuildUtils utils, RuleConditionElement rce) {
    NamedConsequence namedConsequence = (NamedConsequence) rce;
    Timer timer = context.getRule().getTimer();
    if (timer != null) {
        ReteooComponentBuilder builder = utils.getBuilderFor(Timer.class);
        builder.build(context, utils, context.getRule().getTimer());
    }
    RuleTerminalNode terminalNode = buildTerminalNodeForNamedConsequence(context, namedConsequence);
    terminalNode.attach(context);
    terminalNode.networkUpdated(new UpdateContext());
    // adds the terminal node to the list of nodes created/added by this sub-rule
    context.getNodes().add(terminalNode);
    if (timer != null) {
        context.setTupleSource(context.getTupleSource().getLeftTupleSource());
    }
    context.setTerminated(namedConsequence.isTerminal());
}
Also used : Timer(org.drools.core.time.impl.Timer) UpdateContext(org.drools.core.common.UpdateContext) NamedConsequence(org.drools.core.rule.NamedConsequence) RuleTerminalNode(org.drools.core.reteoo.RuleTerminalNode)

Example 64 with RuleTerminalNode

use of org.drools.core.reteoo.RuleTerminalNode in project drools by kiegroup.

the class ConsequenceGenerator method generate.

public static void generate(final ConsequenceStub stub, KnowledgeHelper knowledgeHelper, WorkingMemory workingMemory) {
    RuleTerminalNode rtn = (RuleTerminalNode) knowledgeHelper.getMatch().getTuple().getTupleSink();
    final Declaration[] declarations = rtn.getRequiredDeclarations();
    final Tuple tuple = knowledgeHelper.getTuple();
    // Sort declarations based on their offset, so it can ascend the tuple's parents stack only once
    final List<DeclarationMatcher> declarationMatchers = matchDeclarationsToTuple(declarations);
    final ClassGenerator generator = createInvokerClassGenerator(stub, workingMemory).setInterfaces(Consequence.class, CompiledInvoker.class);
    generator.addMethod(ACC_PUBLIC, "getName", generator.methodDescr(String.class), new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            push(stub.getGeneratedInvokerClassName());
            mv.visitInsn(ARETURN);
        }
    }).addMethod(ACC_PUBLIC, "evaluate", generator.methodDescr(null, KnowledgeHelper.class, WorkingMemory.class), new String[] { "java/lang/Exception" }, new GeneratorHelper.EvaluateMethod() {

        public void body(MethodVisitor mv) {
            // Tuple tuple = knowledgeHelper.getTuple();
            mv.visitVarInsn(ALOAD, 1);
            invokeInterface(KnowledgeHelper.class, "getTuple", Tuple.class);
            cast(LeftTuple.class);
            // LeftTuple
            mv.visitVarInsn(ASTORE, 3);
            // Declaration[] declarations = ((RuleTerminalNode)knowledgeHelper.getMatch().getTuple().getTupleSink()).getDeclarations();
            mv.visitVarInsn(ALOAD, 1);
            invokeInterface(KnowledgeHelper.class, "getMatch", Activation.class);
            invokeInterface(Activation.class, "getTuple", Tuple.class);
            invokeInterface(Tuple.class, "getTupleSink", Sink.class);
            cast(RuleTerminalNode.class);
            invokeVirtual(RuleTerminalNode.class, "getRequiredDeclarations", Declaration[].class);
            mv.visitVarInsn(ASTORE, 4);
            Tuple currentTuple = tuple;
            // astore start position for objects to store in loop
            objAstorePos = 6;
            int[] paramsPos = new int[declarations.length];
            // declarationMatchers is already sorted by offset with tip declarations now first
            for (DeclarationMatcher matcher : declarationMatchers) {
                // original index refers to the array position with RuleTerminalNode.getDeclarations()
                int i = matcher.getOriginalIndex();
                int handlePos = objAstorePos;
                int objPos = ++objAstorePos;
                paramsPos[i] = handlePos;
                currentTuple = traverseTuplesUntilDeclaration(currentTuple, matcher.getRootDistance(), 3);
                // handle = tuple.getFactHandle()
                mv.visitVarInsn(ALOAD, 3);
                invokeInterface(Tuple.class, "getOriginalFactHandle", InternalFactHandle.class);
                mv.visitVarInsn(ASTORE, handlePos);
                String declarationType = declarations[i].getTypeName();
                if (stub.getNotPatterns()[i]) {
                    // notPattern indexes field declarations
                    // declarations[i].getValue((InternalWorkingMemory)workingMemory, fact[i].getObject());
                    // org.kie.rule.Declaration[]
                    mv.visitVarInsn(ALOAD, 4);
                    // i
                    push(i);
                    // declarations[i]
                    mv.visitInsn(AALOAD);
                    // WorkingMemory
                    mv.visitVarInsn(ALOAD, 2);
                    cast(InternalWorkingMemory.class);
                    // handle[i]
                    mv.visitVarInsn(ALOAD, handlePos);
                    invokeInterface(InternalFactHandle.class, "getObject", Object.class);
                    storeObjectFromDeclaration(declarations[i], declarationType);
                    // The facthandle should be set to that of the field, if it's an object, otherwise this will return null
                    // fact[i] = (InternalFactHandle)workingMemory.getFactHandle(obj);
                    mv.visitVarInsn(ALOAD, 2);
                    loadAsObject(objPos);
                    invokeInterface(WorkingMemory.class, "getFactHandle", FactHandle.class, Object.class);
                    cast(InternalFactHandle.class);
                    mv.visitVarInsn(ASTORE, handlePos);
                } else {
                    // handle[i]
                    mv.visitVarInsn(ALOAD, handlePos);
                    invokeInterface(InternalFactHandle.class, "getObject", Object.class);
                    mv.visitTypeInsn(CHECKCAST, internalName(declarationType));
                    // obj[i]
                    objAstorePos += store(objPos, declarationType);
                }
            }
            // @{ruleClassName}.@{methodName}(KnowledgeHelper, @foreach{declr : declarations} Object, FactHandle @end)
            StringBuilder consequenceMethodDescr = new StringBuilder("(L" + KnowledgeHelper.class.getName().replace('.', '/') + ";");
            // KnowledgeHelper
            mv.visitVarInsn(ALOAD, 1);
            for (int i = 0; i < declarations.length; i++) {
                // obj[i]
                load(paramsPos[i] + 1);
                // handle[i]
                mv.visitVarInsn(ALOAD, paramsPos[i]);
                consequenceMethodDescr.append(typeDescr(declarations[i].getTypeName())).append("L" + FactHandle.class.getName().replace('.', '/') + ";");
            }
            // @foreach{type : globalTypes, identifier : globals} @{type} @{identifier} = ( @{type} ) workingMemory.getGlobal( "@{identifier}" );
            parseGlobals(stub.getGlobals(), stub.getGlobalTypes(), 2, consequenceMethodDescr);
            consequenceMethodDescr.append(")V");
            mv.visitMethodInsn(INVOKESTATIC, stub.getInternalRuleClassName(), stub.getMethodName(), consequenceMethodDescr.toString());
            mv.visitInsn(RETURN);
        }
    });
    stub.setConsequence(generator.<Consequence>newInstance());
}
Also used : InternalFactHandle(org.drools.core.common.InternalFactHandle) FactHandle(org.kie.api.runtime.rule.FactHandle) InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) WorkingMemory(org.drools.core.WorkingMemory) Activation(org.drools.core.spi.Activation) DeclarationMatcher(org.drools.core.rule.builder.dialect.asm.GeneratorHelper.DeclarationMatcher) LeftTuple(org.drools.core.reteoo.LeftTuple) MethodVisitor(org.mvel2.asm.MethodVisitor) InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) GeneratorHelper.createInvokerClassGenerator(org.drools.core.rule.builder.dialect.asm.GeneratorHelper.createInvokerClassGenerator) Sink(org.drools.core.reteoo.Sink) KnowledgeHelper(org.drools.core.spi.KnowledgeHelper) Declaration(org.drools.core.rule.Declaration) InternalFactHandle(org.drools.core.common.InternalFactHandle) GeneratorHelper.matchDeclarationsToTuple(org.drools.core.rule.builder.dialect.asm.GeneratorHelper.matchDeclarationsToTuple) LeftTuple(org.drools.core.reteoo.LeftTuple) Tuple(org.drools.core.spi.Tuple) RuleTerminalNode(org.drools.core.reteoo.RuleTerminalNode)

Example 65 with RuleTerminalNode

use of org.drools.core.reteoo.RuleTerminalNode in project drools by kiegroup.

the class DefaultKnowledgeHelper method cancelMatch.

public void cancelMatch(Match act) {
    AgendaItem match = (AgendaItem) act;
    ((RuleTerminalNode) match.getTerminalNode()).cancelMatch(match, workingMemory);
}
Also used : RuleAgendaItem(org.drools.core.phreak.RuleAgendaItem) AgendaItem(org.drools.core.common.AgendaItem) RuleTerminalNode(org.drools.core.reteoo.RuleTerminalNode)

Aggregations

RuleTerminalNode (org.drools.core.reteoo.RuleTerminalNode)69 Test (org.junit.Test)54 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)38 ObjectTypeNode (org.drools.core.reteoo.ObjectTypeNode)30 LeftInputAdapterNode (org.drools.core.reteoo.LeftInputAdapterNode)28 InternalKnowledgeBase (org.drools.core.impl.InternalKnowledgeBase)23 KieBase (org.kie.api.KieBase)23 SegmentMemory (org.drools.core.reteoo.SegmentMemory)18 JoinNode (org.drools.core.reteoo.JoinNode)16 PathMemory (org.drools.core.reteoo.PathMemory)16 ArrayList (java.util.ArrayList)14 ClassObjectType (org.drools.core.base.ClassObjectType)13 RuleImpl (org.drools.core.definitions.rule.impl.RuleImpl)13 List (java.util.List)12 LiaNodeMemory (org.drools.core.reteoo.LeftInputAdapterNode.LiaNodeMemory)11 WorkingMemory (org.drools.core.WorkingMemory)10 RightInputAdapterNode (org.drools.core.reteoo.RightInputAdapterNode)9 FactHandle (org.kie.api.runtime.rule.FactHandle)9 KnowledgeBuilder (org.kie.internal.builder.KnowledgeBuilder)9 KnowledgeBaseImpl (org.drools.core.impl.KnowledgeBaseImpl)8