Search in sources :

Example 91 with LeftTuple

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

the class PhreakAccumulateNode method doLeftUpdatesProcessChildren.

private void doLeftUpdatesProcessChildren(AccumulateNode accNode, AccumulateMemory am, InternalWorkingMemory wm, BetaMemory bm, Accumulate accumulate, BetaConstraints constraints, FastIterator rightIt, LeftTuple leftTuple, final AccumulateContext accctx, RightTuple rightTuple, LeftTuple childLeftTuple) {
    if (childLeftTuple == null) {
        // we had no children before, but there is a bucket to potentially match, so try as normal assert
        for (; rightTuple != null; rightTuple = (RightTuple) rightIt.next(rightTuple)) {
            if (constraints.isAllowedCachedLeft(bm.getContext(), rightTuple.getFactHandleForEvaluation())) {
                // add a new match
                addMatch(accNode, accumulate, leftTuple, rightTuple, null, null, wm, am, accctx, true);
            }
        }
    } else {
        boolean isDirty = false;
        // in the same bucket, so iterate and compare
        for (; rightTuple != null; rightTuple = (RightTuple) rightIt.next(rightTuple)) {
            if (constraints.isAllowedCachedLeft(bm.getContext(), rightTuple.getFactHandleForEvaluation())) {
                if (childLeftTuple == null || childLeftTuple.getRightParent() != rightTuple) {
                    // add a new match
                    addMatch(accNode, accumulate, leftTuple, rightTuple, childLeftTuple, null, wm, am, accctx, true);
                } else {
                    // we must re-add this to ensure deterministic iteration
                    LeftTuple temp = childLeftTuple.getHandleNext();
                    childLeftTuple.reAddRight();
                    childLeftTuple = temp;
                    isDirty = accumulate.hasRequiredDeclarations();
                }
            } else if (childLeftTuple != null && childLeftTuple.getRightParent() == rightTuple) {
                LeftTuple temp = childLeftTuple.getHandleNext();
                // remove the match
                removeMatch(accNode, accumulate, rightTuple, childLeftTuple, wm, am, accctx, false);
                childLeftTuple = temp;
                // the next line means that when a match is removed from the current leftTuple
                // and the accumulate does not support the reverse operation, then the whole
                // result is dirty (since removeMatch above is not recalculating the total)
                // and we need to do this later
                isDirty = !accumulate.supportsReverse();
            }
        // else do nothing, was false before and false now.
        }
        if (isDirty) {
            reaccumulateForLeftTuple(accNode, accumulate, leftTuple, wm, am, accctx);
        }
    }
}
Also used : LeftTuple(org.drools.core.reteoo.LeftTuple)

Example 92 with LeftTuple

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

the class PhreakAccumulateNode method evaluateResultConstraints.

private void evaluateResultConstraints(final AccumulateNode accNode, final LeftTupleSink sink, final Accumulate accumulate, final LeftTuple leftTuple, final PropagationContext context, final InternalWorkingMemory workingMemory, final AccumulateMemory memory, final AccumulateContext accctx, final TupleSets<LeftTuple> trgLeftTuples, final TupleSets<LeftTuple> stagedLeftTuples) {
    // get the actual result
    Object result = accumulate.getResult(memory.workingMemoryContext, accctx.context, leftTuple, workingMemory);
    if (result == null) {
        return;
    }
    if (accctx.getResultFactHandle() == null) {
        final InternalFactHandle handle = accNode.createResultFactHandle(context, workingMemory, leftTuple, result);
        accctx.setResultFactHandle(handle);
        accctx.setResultLeftTuple(sink.createLeftTuple(handle, leftTuple, sink));
    } else {
        accctx.getResultFactHandle().setObject(result);
    }
    // First alpha node filters
    AlphaNodeFieldConstraint[] resultConstraints = accNode.getResultConstraints();
    BetaConstraints resultBinder = accNode.getResultBinder();
    boolean isAllowed = true;
    for (AlphaNodeFieldConstraint resultConstraint : resultConstraints) {
        if (!resultConstraint.isAllowed(accctx.resultFactHandle, workingMemory)) {
            isAllowed = false;
            break;
        }
    }
    if (isAllowed) {
        resultBinder.updateFromTuple(memory.resultsContext, workingMemory, leftTuple);
        if (!resultBinder.isAllowedCachedLeft(memory.resultsContext, accctx.getResultFactHandle())) {
            isAllowed = false;
        }
        resultBinder.resetTuple(memory.resultsContext);
    }
    LeftTuple childLeftTuple = accctx.getResultLeftTuple();
    if (accctx.getPropagationContext() != null) {
        childLeftTuple.setPropagationContext(accctx.getPropagationContext());
        accctx.setPropagationContext(null);
    } else {
        childLeftTuple.setPropagationContext(leftTuple.getPropagationContext());
    }
    if (accctx.propagated) {
        normalizeStagedTuples(stagedLeftTuples, childLeftTuple);
        if (isAllowed) {
            // modify
            trgLeftTuples.addUpdate(childLeftTuple);
        } else {
            // retract
            trgLeftTuples.addDelete(childLeftTuple);
            accctx.propagated = false;
        }
    } else if (isAllowed) {
        // assert
        trgLeftTuples.addInsert(childLeftTuple);
        accctx.propagated = true;
    }
}
Also used : AlphaNodeFieldConstraint(org.drools.core.spi.AlphaNodeFieldConstraint) BetaConstraints(org.drools.core.common.BetaConstraints) InternalFactHandle(org.drools.core.common.InternalFactHandle) LeftTuple(org.drools.core.reteoo.LeftTuple)

Example 93 with LeftTuple

use of org.drools.core.reteoo.LeftTuple 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 94 with LeftTuple

use of org.drools.core.reteoo.LeftTuple 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 95 with LeftTuple

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

the class PhreakBranchNode method doLeftDeletes.

public void doLeftDeletes(LeftTupleSink sink, InternalAgenda agenda, TupleSets<LeftTuple> srcLeftTuples, TupleSets<LeftTuple> trgLeftTuples, TupleSets<LeftTuple> stagedLeftTuples, RuleExecutor executor) {
    for (LeftTuple leftTuple = srcLeftTuples.getDeleteFirst(); leftTuple != null; ) {
        LeftTuple next = leftTuple.getStagedNext();
        BranchTuples branchTuples = getBranchTuples(sink, leftTuple);
        if (branchTuples.rtnLeftTuple != null) {
            if (branchTuples.rtnLeftTuple.getMemory() != null) {
                executor.removeLeftTuple(branchTuples.rtnLeftTuple);
            }
            PhreakRuleTerminalNode.doLeftDelete(agenda, executor, branchTuples.rtnLeftTuple);
        }
        if (branchTuples.mainLeftTuple != null) {
            RuleNetworkEvaluator.deleteChildLeftTuple(branchTuples.mainLeftTuple, trgLeftTuples, stagedLeftTuples);
        }
        leftTuple.clearStaged();
        leftTuple = next;
    }
}
Also used : LeftTuple(org.drools.core.reteoo.LeftTuple)

Aggregations

LeftTuple (org.drools.core.reteoo.LeftTuple)125 RightTuple (org.drools.core.reteoo.RightTuple)41 TupleMemory (org.drools.core.reteoo.TupleMemory)37 InternalFactHandle (org.drools.core.common.InternalFactHandle)34 FastIterator (org.drools.core.util.FastIterator)22 BetaConstraints (org.drools.core.common.BetaConstraints)21 BetaMemory (org.drools.core.reteoo.BetaMemory)21 ContextEntry (org.drools.core.rule.ContextEntry)20 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)18 PhreakJoinNode.updateChildLeftTuple (org.drools.core.phreak.PhreakJoinNode.updateChildLeftTuple)16 AccumulateContext (org.drools.core.reteoo.AccumulateNode.AccumulateContext)13 SegmentMemory (org.drools.core.reteoo.SegmentMemory)13 Test (org.junit.Test)13 KieSession (org.kie.api.runtime.KieSession)13 Tuple (org.drools.core.spi.Tuple)12 WorkingMemory (org.drools.core.WorkingMemory)11 LeftInputAdapterNode (org.drools.core.reteoo.LeftInputAdapterNode)11 FromMemory (org.drools.core.reteoo.FromNode.FromMemory)10 AccumulateMemory (org.drools.core.reteoo.AccumulateNode.AccumulateMemory)9 ArrayList (java.util.ArrayList)8