Search in sources :

Example 16 with LeftTuple

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

the class RuleNetworkEvaluator method evaluateNetwork.

public void evaluateNetwork(PathMemory pmem, RuleExecutor executor, InternalAgenda agenda) {
    SegmentMemory[] smems = pmem.getSegmentMemories();
    int smemIndex = 0;
    // 0
    SegmentMemory smem = smems[smemIndex];
    LeftInputAdapterNode liaNode = (LeftInputAdapterNode) smem.getRootNode();
    LinkedList<StackEntry> stack = new LinkedList<StackEntry>();
    NetworkNode node;
    Memory nodeMem;
    long bit = 1;
    if (liaNode == smem.getTipNode()) {
        // segment only has liaNode in it
        // nothing is staged in the liaNode, so skip to next segment
        // 1
        smem = smems[++smemIndex];
        node = smem.getRootNode();
        nodeMem = smem.getNodeMemories().getFirst();
    } else {
        // lia is in shared segment, so point to next node
        bit = 2;
        node = liaNode.getSinkPropagator().getFirstLeftTupleSink();
        // skip the liaNode memory
        nodeMem = smem.getNodeMemories().getFirst().getNext();
    }
    TupleSets<LeftTuple> srcTuples = smem.getStagedLeftTuples();
    if (log.isTraceEnabled()) {
        log.trace("Rule[name={}] segments={} {}", ((TerminalNode) pmem.getPathEndNode()).getRule().getName(), smems.length, srcTuples.toStringSizes());
    }
    outerEval(pmem, node, bit, nodeMem, smems, smemIndex, srcTuples, agenda, stack, true, executor);
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory) Memory(org.drools.core.common.Memory) QueryElementNodeMemory(org.drools.core.reteoo.QueryElementNode.QueryElementNodeMemory) PathMemory(org.drools.core.reteoo.PathMemory) InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) ConditionalBranchMemory(org.drools.core.reteoo.ConditionalBranchNode.ConditionalBranchMemory) AccumulateMemory(org.drools.core.reteoo.AccumulateNode.AccumulateMemory) TupleMemory(org.drools.core.reteoo.TupleMemory) TimerNodeMemory(org.drools.core.reteoo.TimerNode.TimerNodeMemory) BetaMemory(org.drools.core.reteoo.BetaMemory) EvalMemory(org.drools.core.reteoo.EvalConditionNode.EvalMemory) SegmentMemory(org.drools.core.reteoo.SegmentMemory) FromMemory(org.drools.core.reteoo.FromNode.FromMemory) RiaPathMemory(org.drools.core.reteoo.RiaPathMemory) NetworkNode(org.drools.core.common.NetworkNode) LeftTuple(org.drools.core.reteoo.LeftTuple) LinkedList(org.drools.core.util.LinkedList) QueryTerminalNode(org.drools.core.reteoo.QueryTerminalNode) TerminalNode(org.drools.core.reteoo.TerminalNode) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode)

Example 17 with LeftTuple

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

the class RuleNetworkEvaluator method innerEval.

public void innerEval(PathMemory pmem, NetworkNode node, long bit, Memory nodeMem, SegmentMemory[] smems, int smemIndex, TupleSets<LeftTuple> trgTuples, InternalAgenda agenda, LinkedList<StackEntry> stack, boolean processRian, RuleExecutor executor) {
    TupleSets<LeftTuple> srcTuples;
    SegmentMemory smem = smems[smemIndex];
    TupleSets<LeftTuple> stagedLeftTuples = null;
    while (true) {
        // previous target, is now the source
        srcTuples = trgTuples;
        if (log.isTraceEnabled()) {
            int offset = getOffset(node);
            log.trace("{} {} {} {}", indent(offset), ++cycle, node.toString(), srcTuples.toStringSizes());
        }
        boolean emptySrcTuples = srcTuples.isEmpty();
        if (!(NodeTypeEnums.isBetaNode(node) && ((BetaNode) node).isRightInputIsRiaNode())) {
            // The engine cannot skip a ria node, as the dirty might be several levels deep
            if (emptySrcTuples && smem.getDirtyNodeMask() == 0) {
                // empty sources and segment is not dirty, skip to non empty src tuples or dirty segment.
                boolean foundDirty = false;
                for (int i = ++smemIndex, length = smems.length; i < length; i++) {
                    if (log.isTraceEnabled()) {
                        int offset = getOffset(node);
                        log.trace("{} Skip Segment {}", indent(offset), i - 1);
                    }
                    // and may not yet be initialized
                    if (smem.isEmpty() && !NodeTypeEnums.isTerminalNode(smem.getTipNode())) {
                        SegmentUtilities.createChildSegments(agenda.getWorkingMemory(), smem, ((LeftTupleSource) smem.getTipNode()).getSinkPropagator());
                    }
                    smem = smems[i];
                    bit = 1;
                    srcTuples = smem.getStagedLeftTuples().takeAll();
                    emptySrcTuples = srcTuples.isEmpty();
                    node = smem.getRootNode();
                    nodeMem = smem.getNodeMemories().getFirst();
                    if (!emptySrcTuples || smem.getDirtyNodeMask() != 0 || (NodeTypeEnums.isBetaNode(node) && ((BetaNode) node).isRightInputIsRiaNode())) {
                        // break if dirty or if we reach a subnetwork. It must break for subnetworks, so they can be searched.
                        foundDirty = true;
                        smemIndex = i;
                        break;
                    }
                }
                if (!foundDirty) {
                    break;
                }
            }
            if (log.isTraceEnabled()) {
                int offset = getOffset(node);
                log.trace("{} Segment {}", indent(offset), smemIndex);
                log.trace("{} {} {} {}", indent(offset), cycle, node.toString(), srcTuples.toStringSizes());
            }
        }
        long dirtyMask = smem.getDirtyNodeMask();
        if (emptySrcTuples) {
            while ((dirtyMask & bit) == 0 && node != smem.getTipNode() && !(NodeTypeEnums.isBetaNode(node) && ((BetaNode) node).isRightInputIsRiaNode())) {
                if (log.isTraceEnabled()) {
                    int offset = getOffset(node);
                    log.trace("{} Skip Node {}", indent(offset), node);
                }
                // shift to check the next node
                bit = bit << 1;
                node = ((LeftTupleSource) node).getSinkPropagator().getFirstLeftTupleSink();
                nodeMem = nodeMem.getNext();
            }
        }
        boolean terminalNode = true;
        switch(node.getType()) {
            case NodeTypeEnums.RuleTerminalNode:
                pRtNode.doNode((TerminalNode) node, agenda, srcTuples, executor);
                break;
            case NodeTypeEnums.QueryTerminalNode:
                pQtNode.doNode((QueryTerminalNode) node, agenda, srcTuples, stack);
                break;
            case NodeTypeEnums.RightInputAdaterNode:
                doRiaNode2(agenda.getWorkingMemory(), srcTuples, (RightInputAdapterNode) node);
                break;
            default:
                terminalNode = false;
        }
        if (terminalNode) {
            break;
        }
        stagedLeftTuples = getTargetStagedLeftTuples(node, agenda.getWorkingMemory(), smem);
        LeftTupleSinkNode sink = ((LeftTupleSource) node).getSinkPropagator().getFirstLeftTupleSink();
        trgTuples = evalNode(pmem, node, bit, nodeMem, smems, smemIndex, agenda, stack, processRian, executor, srcTuples, smem, stagedLeftTuples, sink);
        if (trgTuples == null) {
            // Queries exists and has been placed StackEntry, and there are no current trgTuples to process
            break;
        }
        if (node != smem.getTipNode()) {
            // get next node and node memory in the segment
            node = sink;
            nodeMem = nodeMem.getNext();
            bit = bit << 1;
        } else {
            // Reached end of segment, start on new segment.
            // must put back all the LTs
            smem.getFirst().getStagedLeftTuples().addAll(stagedLeftTuples);
            // end of SegmentMemory, so we know that stagedLeftTuples is not null
            SegmentPropagator.propagate(smem, trgTuples, agenda.getWorkingMemory());
            bit = 1;
            smem = smems[++smemIndex];
            trgTuples = smem.getStagedLeftTuples().takeAll();
            if (log.isTraceEnabled()) {
                int offset = getOffset(node);
                log.trace("{} Segment {}", indent(offset), smemIndex);
            }
            node = smem.getRootNode();
            nodeMem = smem.getNodeMemories().getFirst();
        }
        // make sure it's reset, so ria nodes are processed
        processRian = true;
    }
    if (stagedLeftTuples != null && !stagedLeftTuples.isEmpty()) {
        // must put back all the LTs
        smem.getFirst().getStagedLeftTuples().addAll(stagedLeftTuples);
    }
}
Also used : LeftTupleSource(org.drools.core.reteoo.LeftTupleSource) SegmentMemory(org.drools.core.reteoo.SegmentMemory) BetaNode(org.drools.core.reteoo.BetaNode) LeftTupleSinkNode(org.drools.core.reteoo.LeftTupleSinkNode) LeftTuple(org.drools.core.reteoo.LeftTuple)

Example 18 with LeftTuple

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

the class RuleNetworkEvaluator method doUpdatesExistentialReorderRightMemory.

public static void doUpdatesExistentialReorderRightMemory(BetaMemory bm, BetaNode betaNode, TupleSets<RightTuple> srcRightTuples) {
    TupleMemory rtm = bm.getRightTupleMemory();
    boolean resumeFromCurrent = !(betaNode.isIndexedUnificationJoin() || rtm.getIndexType().isComparison());
    if (rtm.getIndexType() != TupleMemory.IndexType.NONE) {
        for (RightTuple rightTuple = srcRightTuples.getDeleteFirst(); rightTuple != null; rightTuple = rightTuple.getStagedNext()) {
            rtm.remove(rightTuple);
        }
    }
    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; rightTuple = rightTuple.getStagedNext()) {
        if (rightTuple.getMemory() != null) {
            rightTuple.setTempRightTupleMemory(rightTuple.getMemory());
            if (resumeFromCurrent) {
                if (rightTuple.getBlocked() != null) {
                    // look for a non-staged right tuple first forward ...
                    RightTuple tempRightTuple = (RightTuple) rightTuple.getNext();
                    while (tempRightTuple != null && tempRightTuple.getStagedType() != LeftTuple.NONE) {
                        // next cannot be an updated or deleted rightTuple
                        tempRightTuple = (RightTuple) tempRightTuple.getNext();
                    }
                    // ... and if cannot find one try backward
                    if (tempRightTuple == null) {
                        tempRightTuple = (RightTuple) rightTuple.getPrevious();
                        while (tempRightTuple != null && tempRightTuple.getStagedType() != LeftTuple.NONE) {
                            // next cannot be an updated or deleted rightTuple
                            tempRightTuple = (RightTuple) tempRightTuple.getPrevious();
                        }
                    }
                    rightTuple.setTempNextRightTuple(tempRightTuple);
                }
            }
            rightTuple.setTempBlocked(rightTuple.getBlocked());
            rightTuple.setBlocked(null);
            rtm.remove(rightTuple);
        }
    }
    for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; rightTuple = rightTuple.getStagedNext()) {
        rtm.add(rightTuple);
        if (resumeFromCurrent) {
            RightTuple tempRightTuple = rightTuple.getTempNextRightTuple();
            if (rightTuple.getBlocked() != null && tempRightTuple == null && rightTuple.getMemory() == rightTuple.getTempRightTupleMemory()) {
                // the next RightTuple was null, but current RightTuple was added back into the same bucket, so reset as root blocker to re-match can be attempted
                rightTuple.setTempNextRightTuple(rightTuple);
            }
        }
        for (LeftTuple childLeftTuple = rightTuple.getFirstChild(); childLeftTuple != null; ) {
            LeftTuple childNext = childLeftTuple.getRightParentNext();
            childLeftTuple.reAddLeft();
            childLeftTuple = childNext;
        }
    }
    if (rtm.getIndexType() != TupleMemory.IndexType.NONE) {
        for (RightTuple rightTuple = srcRightTuples.getDeleteFirst(); rightTuple != null; rightTuple = rightTuple.getStagedNext()) {
            rtm.add(rightTuple);
        }
    }
}
Also used : RightTuple(org.drools.core.reteoo.RightTuple) LeftTuple(org.drools.core.reteoo.LeftTuple) TupleMemory(org.drools.core.reteoo.TupleMemory)

Example 19 with LeftTuple

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

the class SegmentPropagator method processPeers.

private static void processPeers(SegmentMemory sourceSegment, TupleSets<LeftTuple> leftTuples, InternalWorkingMemory wm) {
    SegmentMemory firstSmem = sourceSegment.getFirst();
    // Process Deletes
    processPeerDeletes(leftTuples, leftTuples.getDeleteFirst(), firstSmem, wm);
    processPeerDeletes(leftTuples, leftTuples.getNormalizedDeleteFirst(), firstSmem, wm);
    // Process Updates
    for (LeftTuple leftTuple = leftTuples.getUpdateFirst(); leftTuple != null; leftTuple = leftTuple.getStagedNext()) {
        SegmentMemory smem = firstSmem.getNext();
        if (smem != null) {
            for (LeftTuple peer = leftTuple.getPeer(); peer != null; peer = peer.getPeer()) {
                // only stage, if not already staged, if insert, leave as insert
                if (peer.getStagedType() == LeftTuple.NONE) {
                    peer.setPropagationContext(leftTuple.getPropagationContext());
                    smem.getStagedLeftTuples().addUpdate(peer);
                }
                smem = smem.getNext();
            }
        }
    }
    // Process Inserts
    for (LeftTuple leftTuple = leftTuples.getInsertFirst(); leftTuple != null; leftTuple = leftTuple.getStagedNext()) {
        SegmentMemory smem = firstSmem.getNext();
        if (smem != null) {
            LeftTuple peer = leftTuple;
            for (; smem != null; smem = smem.getNext()) {
                if (peer.getPeer() != null) {
                    // if the tuple already has a peer avoid to create a new one ...
                    peer = peer.getPeer();
                    peer.setPropagationContext(leftTuple.getPropagationContext());
                    // ... and update the staged LeftTupleSets according to its current staged state
                    PhreakJoinNode.updateChildLeftTuple(peer, smem.getStagedLeftTuples(), smem.getStagedLeftTuples());
                } else {
                    peer = ((LeftTupleSink) smem.getRootNode()).createPeer(peer);
                    smem.getStagedLeftTuples().addInsert(peer);
                    if (smem.hasDataDrivenPathMemories()) {
                        for (PathMemory dataDrivenPmem : smem.getDataDrivenPathMemories()) {
                            // on insert only totally linked pmems need to be flushed
                            if (dataDrivenPmem.isRuleLinked()) {
                                forceFlushLeftTuple(dataDrivenPmem, smem, wm, smem.getStagedLeftTuples());
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
    firstSmem.getStagedLeftTuples().addAll(leftTuples);
    leftTuples.resetAll();
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory) AddRemoveRule.forceFlushLeftTuple(org.drools.core.phreak.AddRemoveRule.forceFlushLeftTuple) LeftTuple(org.drools.core.reteoo.LeftTuple) PathMemory(org.drools.core.reteoo.PathMemory)

Example 20 with LeftTuple

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

the class SegmentPropagator method processPeerDeletes.

private static void processPeerDeletes(TupleSets<LeftTuple> leftTuples, LeftTuple leftTuple, SegmentMemory firstSmem, InternalWorkingMemory wm) {
    for (; leftTuple != null; leftTuple = leftTuple.getStagedNext()) {
        SegmentMemory smem = firstSmem.getNext();
        if (smem != null) {
            for (LeftTuple peer = leftTuple.getPeer(); peer != null; peer = peer.getPeer()) {
                peer.setPropagationContext(leftTuple.getPropagationContext());
                TupleSets<LeftTuple> stagedLeftTuples = smem.getStagedLeftTuples();
                // if the peer is already staged as insert or update the LeftTupleSets will reconcile it internally
                stagedLeftTuples.addDelete(peer);
                if (smem.hasDataDrivenPathMemories()) {
                    forceFlushLeftTuple(smem.getFirstDataDrivenPathMemory(), smem, wm, smem.getStagedLeftTuples());
                }
                smem = smem.getNext();
            }
        }
    }
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory) AddRemoveRule.forceFlushLeftTuple(org.drools.core.phreak.AddRemoveRule.forceFlushLeftTuple) 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