Search in sources :

Example 41 with TupleMemory

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

the class Scenario method equalsRightMemory.

public void equalsRightMemory(List<RightTuple> rightTuples) {
    TupleMemory rtm = bm.getRightTupleMemory();
    int length = 0;
    for (RightTuple expectedRightTuple : rightTuples) {
        FastIterator it = betaNode.getRightIterator(rtm);
        Tuple actualRightTuple = null;
        for (actualRightTuple = BetaNode.getFirstTuple(rtm, it); actualRightTuple != null; actualRightTuple = (RightTuple) it.next(actualRightTuple)) {
            if (expectedRightTuple.equals(actualRightTuple)) {
                length++;
                break;
            }
        }
        if (actualRightTuple == null) {
            fail("Could not find RightTuple: " + expectedRightTuple);
        }
    }
    if (rightTuples.size() != rtm.size()) {
        fail("RightTuple memory size did not match: " + length);
    }
}
Also used : FastIterator(org.drools.core.util.FastIterator) RightTuple(org.drools.core.reteoo.RightTuple) TupleMemory(org.drools.core.reteoo.TupleMemory) LeftTuple(org.drools.core.reteoo.LeftTuple) RightTuple(org.drools.core.reteoo.RightTuple) Tuple(org.drools.core.spi.Tuple)

Example 42 with TupleMemory

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

the class AddRemoveRule method processLeftTuples.

/**
 * Populates the SegmentMemory with staged LeftTuples. If the parent is not a Beta or From node, it iterates up to find the first node with memory. If necessary
 * It traverses to the LiaNode's ObjectTypeNode. It then iterates the LeftTuple chains, where an existing LeftTuple is staged
 * as delete. Or a new LeftTuple is created and staged as an insert.
 */
private static void processLeftTuples(LeftTupleNode node, InternalWorkingMemory wm, boolean insert, Rule rule) {
    if (node instanceof AlphaTerminalNode) {
        processLeftTuplesOnLian(wm, insert, rule, (LeftInputAdapterNode) node);
        return;
    }
    Memory memory = wm.getNodeMemories().peekNodeMemory(node);
    if (memory == null || memory.getSegmentMemory() == null) {
        // segment has never been initialized, which means the rule(s) have never been linked and thus no Tuples to fix
        return;
    }
    SegmentMemory sm = memory.getSegmentMemory();
    while (NodeTypeEnums.LeftInputAdapterNode != node.getType()) {
        if (NodeTypeEnums.isBetaNode(node)) {
            BetaMemory bm;
            if (NodeTypeEnums.AccumulateNode == node.getType()) {
                AccumulateMemory am = (AccumulateMemory) memory;
                bm = am.getBetaMemory();
                FastIterator it = bm.getLeftTupleMemory().fullFastIterator();
                Tuple lt = BetaNode.getFirstTuple(bm.getLeftTupleMemory(), it);
                for (; lt != null; lt = (LeftTuple) it.next(lt)) {
                    AccumulateContext accctx = (AccumulateContext) lt.getContextObject();
                    visitChild(accctx.getResultLeftTuple(), insert, wm, rule);
                }
            } else if (NodeTypeEnums.ExistsNode == node.getType() && !((BetaNode) node).isRightInputIsRiaNode()) {
                // do not process exists with subnetworks
                // If there is a subnetwork, then there is no populated RTM, but the LTM is populated,
                // so this would be procsssed in the "else".
                bm = (BetaMemory) wm.getNodeMemory((MemoryFactory) node);
                // done off the RightTupleMemory, as exists only have unblocked tuples on the left side
                FastIterator it = bm.getRightTupleMemory().fullFastIterator();
                RightTuple rt = (RightTuple) BetaNode.getFirstTuple(bm.getRightTupleMemory(), it);
                for (; rt != null; rt = (RightTuple) it.next(rt)) {
                    for (LeftTuple lt = rt.getBlocked(); lt != null; lt = lt.getBlockedNext()) {
                        visitChild(wm, insert, rule, it, lt);
                    }
                }
            } else {
                bm = (BetaMemory) wm.getNodeMemory((MemoryFactory) node);
                FastIterator it = bm.getLeftTupleMemory().fullFastIterator();
                Tuple lt = BetaNode.getFirstTuple(bm.getLeftTupleMemory(), it);
                visitChild(wm, insert, rule, it, lt);
            }
            return;
        } else if (NodeTypeEnums.FromNode == node.getType()) {
            FromMemory fm = (FromMemory) wm.getNodeMemory((MemoryFactory) node);
            TupleMemory ltm = fm.getBetaMemory().getLeftTupleMemory();
            FastIterator it = ltm.fullFastIterator();
            for (LeftTuple lt = (LeftTuple) ltm.getFirst(null); lt != null; lt = (LeftTuple) it.next(lt)) {
                visitChild(lt, insert, wm, rule);
            }
            return;
        }
        if (sm.getRootNode() == node) {
            sm = wm.getNodeMemory((MemoryFactory<Memory>) node.getLeftTupleSource()).getSegmentMemory();
        }
        node = node.getLeftTupleSource();
    }
    // No beta or from nodes, so must retrieve LeftTuples from the LiaNode.
    // This is done by scanning all the LeftTuples referenced from the FactHandles in the ObjectTypeNode
    processLeftTuplesOnLian(wm, insert, rule, (LeftInputAdapterNode) node);
}
Also used : AccumulateMemory(org.drools.core.reteoo.AccumulateNode.AccumulateMemory) SegmentMemory(org.drools.core.reteoo.SegmentMemory) Memory(org.drools.core.common.Memory) PathMemory(org.drools.core.reteoo.PathMemory) InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) SegmentNodeMemory(org.drools.core.reteoo.SegmentNodeMemory) ObjectTypeNodeMemory(org.drools.core.reteoo.ObjectTypeNode.ObjectTypeNodeMemory) RiaNodeMemory(org.drools.core.reteoo.RightInputAdapterNode.RiaNodeMemory) AccumulateMemory(org.drools.core.reteoo.AccumulateNode.AccumulateMemory) TupleMemory(org.drools.core.reteoo.TupleMemory) BetaMemory(org.drools.core.reteoo.BetaMemory) SegmentMemory(org.drools.core.reteoo.SegmentMemory) FromMemory(org.drools.core.reteoo.FromNode.FromMemory) BetaMemory(org.drools.core.reteoo.BetaMemory) MemoryFactory(org.drools.core.common.MemoryFactory) RightTuple(org.drools.core.reteoo.RightTuple) LeftTuple(org.drools.core.reteoo.LeftTuple) TupleMemory(org.drools.core.reteoo.TupleMemory) FromMemory(org.drools.core.reteoo.FromNode.FromMemory) AlphaTerminalNode(org.drools.core.reteoo.AlphaTerminalNode) FastIterator(org.drools.core.util.FastIterator) Tuple(org.drools.core.spi.Tuple) LeftTuple(org.drools.core.reteoo.LeftTuple) RightTuple(org.drools.core.reteoo.RightTuple) AccumulateContext(org.drools.core.reteoo.AccumulateNode.AccumulateContext)

Example 43 with TupleMemory

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

the class PhreakExistsNode method doLeftUpdates.

public void doLeftUpdates(ExistsNode existsNode, LeftTupleSink sink, BetaMemory bm, ReteEvaluator reteEvaluator, TupleSets<LeftTuple> srcLeftTuples, TupleSets<LeftTuple> trgLeftTuples, TupleSets<LeftTuple> stagedLeftTuples) {
    TupleMemory ltm = bm.getLeftTupleMemory();
    TupleMemory rtm = bm.getRightTupleMemory();
    ContextEntry[] contextEntry = bm.getContext();
    BetaConstraints constraints = existsNode.getRawConstraints();
    boolean leftUpdateOptimizationAllowed = existsNode.isLeftUpdateOptimizationAllowed();
    for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
        LeftTuple next = leftTuple.getStagedNext();
        FastIterator rightIt = existsNode.getRightIterator(rtm);
        RightTuple firstRightTuple = existsNode.getFirstRightTuple(leftTuple, rtm, rightIt);
        // If in memory, remove it, because we'll need to add it anyway if it's not blocked, to ensure iteration order
        RightTuple blocker = leftTuple.getBlocker();
        if (blocker == null) {
            if (leftTuple.getMemory() != null) {
                // memory can be null, if blocker was deleted in same do loop
                ltm.remove(leftTuple);
            }
        } else {
            // check if we changed bucket
            if (rtm.isIndexed() && !rightIt.isFullIterator()) {
                // if newRightTuple is null, we assume there was a bucket change and that bucket is empty
                if (firstRightTuple == null || firstRightTuple.getMemory() != blocker.getMemory()) {
                    // we changed bucket, so blocker no longer blocks
                    blocker.removeBlocked(leftTuple);
                    blocker = null;
                }
            }
        }
        constraints.updateFromTuple(contextEntry, reteEvaluator, leftTuple);
        if (!leftUpdateOptimizationAllowed && blocker != null) {
            blocker.removeBlocked(leftTuple);
            blocker = null;
        }
        // if we where not blocked before (or changed buckets), or the previous blocker no longer blocks, then find the next blocker
        if (blocker == null || !constraints.isAllowedCachedLeft(contextEntry, blocker.getFactHandleForEvaluation())) {
            if (blocker != null) {
                // remove previous blocker if it exists, as we know it doesn't block any more
                blocker.removeBlocked(leftTuple);
            }
            // find first blocker, because it's a modify, we need to start from the beginning again
            for (RightTuple newBlocker = firstRightTuple; newBlocker != null; newBlocker = (RightTuple) rightIt.next(newBlocker)) {
                if (constraints.isAllowedCachedLeft(contextEntry, newBlocker.getFactHandleForEvaluation())) {
                    leftTuple.setBlocker(newBlocker);
                    newBlocker.addBlocked(leftTuple);
                    break;
                }
            }
        }
        if (leftTuple.getBlocker() == null) {
            // not blocked
            // add to memory so other fact handles can attempt to match
            ltm.add(leftTuple);
            if (leftTuple.getFirstChild() != null) {
                // no need to update pctx, as no right available, and pctx will exist on a parent LeftTuple anyway
                RuleNetworkEvaluator.unlinkAndDeleteChildLeftTuple(leftTuple.getFirstChild(), trgLeftTuples, stagedLeftTuples);
            }
        // with no previous children. do nothing.
        } else if (leftTuple.getFirstChild() == null) {
            // blocked, with no previous children, insert
            insertChildLeftTuple(sink, trgLeftTuples, leftTuple, leftTuple.getBlocker().getPropagationContext(), true);
        } else {
            // blocked, with previous children, modify
            LeftTuple childLeftTuple = leftTuple.getFirstChild();
            while (childLeftTuple != null) {
                childLeftTuple.setPropagationContext(leftTuple.getBlocker().getPropagationContext());
                updateChildLeftTuple(childLeftTuple, stagedLeftTuples, trgLeftTuples);
                childLeftTuple.reAddRight();
                childLeftTuple = childLeftTuple.getHandleNext();
            }
        }
        leftTuple.clearStaged();
        leftTuple = next;
    }
    constraints.resetTuple(contextEntry);
}
Also used : BetaConstraints(org.drools.core.common.BetaConstraints) FastIterator(org.drools.core.util.FastIterator) LeftTuple(org.drools.core.reteoo.LeftTuple) PhreakJoinNode.updateChildLeftTuple(org.drools.core.phreak.PhreakJoinNode.updateChildLeftTuple) RightTuple(org.drools.core.reteoo.RightTuple) TupleMemory(org.drools.core.reteoo.TupleMemory) ContextEntry(org.drools.core.rule.ContextEntry)

Example 44 with TupleMemory

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

the class PhreakExistsNode method doRightUpdates.

public void doRightUpdates(ExistsNode existsNode, LeftTupleSink sink, BetaMemory bm, ReteEvaluator reteEvaluator, TupleSets<RightTuple> srcRightTuples, TupleSets<LeftTuple> trgLeftTuples, TupleSets<LeftTuple> stagedLeftTuples) {
    TupleMemory ltm = bm.getLeftTupleMemory();
    TupleMemory rtm = bm.getRightTupleMemory();
    ContextEntry[] contextEntry = bm.getContext();
    BetaConstraints constraints = existsNode.getRawConstraints();
    boolean iterateFromStart = existsNode.isIndexedUnificationJoin() || rtm.getIndexType().isComparison();
    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; ) {
        RightTuple next = rightTuple.getStagedNext();
        if (ltm != null && ltm.size() > 0) {
            FastIterator leftIt = existsNode.getLeftIterator(ltm);
            LeftTuple firstLeftTuple = existsNode.getFirstLeftTuple(rightTuple, ltm, leftIt);
            constraints.updateFromFactHandle(contextEntry, reteEvaluator, rightTuple.getFactHandleForEvaluation());
            // first process non-blocked tuples, as we know only those ones are in the left memory.
            for (LeftTuple leftTuple = firstLeftTuple; leftTuple != null; ) {
                // preserve next now, in case we remove this leftTuple
                LeftTuple temp = (LeftTuple) leftIt.next(leftTuple);
                if (leftTuple.getStagedType() == LeftTuple.UPDATE) {
                    // ignore, as it will get processed via left iteration. Children cannot be processed twice
                    leftTuple = temp;
                    continue;
                }
                // we know that only unblocked LeftTuples are  still in the memory
                if (constraints.isAllowedCachedRight(contextEntry, leftTuple)) {
                    leftTuple.setBlocker(rightTuple);
                    rightTuple.addBlocked(leftTuple);
                    // this is now blocked so remove from memory
                    ltm.remove(leftTuple);
                    // subclasses like ForallNotNode might override this propagation
                    insertChildLeftTuple(sink, trgLeftTuples, leftTuple, rightTuple.getPropagationContext(), true);
                }
                leftTuple = temp;
            }
        }
        LeftTuple firstBlocked = rightTuple.getTempBlocked();
        if (firstBlocked != null) {
            RightTuple rootBlocker = rightTuple.getTempNextRightTuple();
            if (rootBlocker == null) {
                iterateFromStart = true;
            }
            FastIterator rightIt = existsNode.getRightIterator(rtm);
            // iterate all the existing previous blocked LeftTuples
            for (LeftTuple leftTuple = firstBlocked; leftTuple != null; ) {
                LeftTuple temp = leftTuple.getBlockedNext();
                // must null these as we are re-adding them to the list
                leftTuple.clearBlocker();
                if (leftTuple.getStagedType() == LeftTuple.UPDATE) {
                    // ignore, as it will get processed via left iteration. Children cannot be processed twice
                    // but need to add it back into list first
                    leftTuple.setBlocker(rightTuple);
                    rightTuple.addBlocked(leftTuple);
                    leftTuple = temp;
                    continue;
                }
                constraints.updateFromTuple(contextEntry, reteEvaluator, leftTuple);
                if (iterateFromStart) {
                    rootBlocker = existsNode.getFirstRightTuple(leftTuple, rtm, rightIt);
                }
                // we know that older tuples have been checked so continue next
                for (RightTuple newBlocker = rootBlocker; newBlocker != null; newBlocker = (RightTuple) rightIt.next(newBlocker)) {
                    // There may be UPDATE RightTuples too, but that's ok. They've already been re-added to the correct bucket, safe to be reprocessed.
                    if (leftTuple.getStagedType() != LeftTuple.DELETE && newBlocker.getStagedType() != LeftTuple.DELETE && constraints.isAllowedCachedLeft(contextEntry, newBlocker.getFactHandleForEvaluation())) {
                        leftTuple.setBlocker(newBlocker);
                        newBlocker.addBlocked(leftTuple);
                        break;
                    }
                }
                if (leftTuple.getBlocker() == null) {
                    // was previous blocked and not in memory, so add
                    if (ltm != null) {
                        ltm.add(leftTuple);
                    }
                    LeftTuple childLeftTuple = leftTuple.getFirstChild();
                    if (childLeftTuple != null) {
                        childLeftTuple.setPropagationContext(rightTuple.getPropagationContext());
                        RuleNetworkEvaluator.unlinkAndDeleteChildLeftTuple(childLeftTuple, trgLeftTuples, stagedLeftTuples);
                    }
                }
                leftTuple = temp;
            }
        }
        rightTuple.clearStaged();
        rightTuple = next;
    }
    constraints.resetFactHandle(contextEntry);
}
Also used : BetaConstraints(org.drools.core.common.BetaConstraints) FastIterator(org.drools.core.util.FastIterator) RightTuple(org.drools.core.reteoo.RightTuple) LeftTuple(org.drools.core.reteoo.LeftTuple) PhreakJoinNode.updateChildLeftTuple(org.drools.core.phreak.PhreakJoinNode.updateChildLeftTuple) TupleMemory(org.drools.core.reteoo.TupleMemory) ContextEntry(org.drools.core.rule.ContextEntry)

Example 45 with TupleMemory

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

the class PhreakExistsNode method doRightInserts.

public void doRightInserts(ExistsNode existsNode, LeftTupleSink sink, BetaMemory bm, ReteEvaluator reteEvaluator, TupleSets<RightTuple> srcRightTuples, TupleSets<LeftTuple> trgLeftTuples) {
    TupleMemory ltm = bm.getLeftTupleMemory();
    TupleMemory rtm = bm.getRightTupleMemory();
    ContextEntry[] contextEntry = bm.getContext();
    BetaConstraints constraints = existsNode.getRawConstraints();
    for (RightTuple rightTuple = srcRightTuples.getInsertFirst(); rightTuple != null; ) {
        RightTuple next = rightTuple.getStagedNext();
        rtm.add(rightTuple);
        if (ltm != null && ltm.size() > 0) {
            FastIterator it = existsNode.getLeftIterator(ltm);
            constraints.updateFromFactHandle(contextEntry, reteEvaluator, rightTuple.getFactHandleForEvaluation());
            for (LeftTuple leftTuple = existsNode.getFirstLeftTuple(rightTuple, ltm, it); leftTuple != null; ) {
                // preserve next now, in case we remove this leftTuple
                LeftTuple temp = (LeftTuple) it.next(leftTuple);
                if (leftTuple.getStagedType() == LeftTuple.UPDATE) {
                    // ignore, as it will get processed via left iteration. Children cannot be processed twice
                    leftTuple = temp;
                    continue;
                }
                // we know that only unblocked LeftTuples are  still in the memory
                if (constraints.isAllowedCachedRight(contextEntry, leftTuple)) {
                    leftTuple.setBlocker(rightTuple);
                    rightTuple.addBlocked(leftTuple);
                    ltm.remove(leftTuple);
                    insertChildLeftTuple(sink, trgLeftTuples, leftTuple, rightTuple.getPropagationContext(), true);
                }
                leftTuple = temp;
            }
        }
        rightTuple.clearStaged();
        rightTuple = next;
    }
    constraints.resetFactHandle(contextEntry);
}
Also used : BetaConstraints(org.drools.core.common.BetaConstraints) FastIterator(org.drools.core.util.FastIterator) RightTuple(org.drools.core.reteoo.RightTuple) LeftTuple(org.drools.core.reteoo.LeftTuple) PhreakJoinNode.updateChildLeftTuple(org.drools.core.phreak.PhreakJoinNode.updateChildLeftTuple) TupleMemory(org.drools.core.reteoo.TupleMemory) ContextEntry(org.drools.core.rule.ContextEntry)

Aggregations

TupleMemory (org.drools.core.reteoo.TupleMemory)66 LeftTuple (org.drools.core.reteoo.LeftTuple)59 RightTuple (org.drools.core.reteoo.RightTuple)52 FastIterator (org.drools.core.util.FastIterator)40 BetaConstraints (org.drools.core.common.BetaConstraints)36 ContextEntry (org.drools.core.rule.ContextEntry)36 PhreakJoinNode.updateChildLeftTuple (org.drools.core.phreak.PhreakJoinNode.updateChildLeftTuple)23 BetaMemory (org.drools.core.reteoo.BetaMemory)23 Accumulate (org.drools.core.rule.Accumulate)12 Tuple (org.drools.core.spi.Tuple)9 AccumulateContext (org.drools.core.reteoo.AccumulateNode.AccumulateContext)8 ArrayList (java.util.ArrayList)6 BetaNode (org.drools.core.reteoo.BetaNode)6 InternalFactHandle (org.drools.core.common.InternalFactHandle)5 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)5 BaseAccumulation (org.drools.core.reteoo.AccumulateNode.BaseAccumulation)5 ObjectTypeNode (org.drools.core.reteoo.ObjectTypeNode)5 PhreakPropagationContext (org.drools.core.common.PhreakPropagationContext)4 AccumulateContextEntry (org.drools.core.reteoo.AccumulateNode.AccumulateContextEntry)4 LeftInputAdapterNode (org.drools.core.reteoo.LeftInputAdapterNode)4