Search in sources :

Example 1 with LeftTupleNode

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

the class RuleNetworkEvaluator method evalQueryNode.

private boolean evalQueryNode(PathMemory pmem, NetworkNode node, long bit, Memory nodeMem, SegmentMemory[] smems, int smemIndex, TupleSets<LeftTuple> trgTuples, InternalWorkingMemory wm, LinkedList<StackEntry> stack, TupleSets<LeftTuple> srcTuples, LeftTupleSinkNode sink, TupleSets<LeftTuple> stagedLeftTuples) {
    QueryElementNodeMemory qmem = (QueryElementNodeMemory) nodeMem;
    if (srcTuples.isEmpty() && qmem.getResultLeftTuples().isEmpty()) {
        // no point in evaluating query element, and setting up stack, if there is nothing to process
        return false;
    }
    QueryElementNode qnode = (QueryElementNode) node;
    if (log.isTraceEnabled()) {
        int offset = getOffset(node);
        log.trace("{} query result tuples {}", indent(offset), qmem.getResultLeftTuples().toStringSizes());
    }
    // result tuples can happen when reactivity occurs inside of the query, prior to evaluation
    // we will need special behaviour to add the results again, when this query result resumes
    qmem.getResultLeftTuples().addTo(trgTuples);
    qmem.setNodeCleanWithoutNotify();
    if (!srcTuples.isEmpty()) {
        // only process the Query Node if there are src tuples
        StackEntry stackEntry = new StackEntry(node, bit, sink, pmem, nodeMem, smems, smemIndex, trgTuples, true, true);
        stack.add(stackEntry);
        pQueryNode.doNode(qnode, (QueryElementNodeMemory) nodeMem, stackEntry, wm, srcTuples, trgTuples, stagedLeftTuples);
        SegmentMemory qsmem = ((QueryElementNodeMemory) nodeMem).getQuerySegmentMemory();
        List<PathMemory> qpmems = qsmem.getPathMemories();
        // Build the evaluation information for each 'or' branch
        for (int i = 0; i < qpmems.size(); i++) {
            PathMemory qpmem = qpmems.get(i);
            pmem = qpmem;
            smems = qpmem.getSegmentMemories();
            smemIndex = 0;
            // 0
            SegmentMemory smem = smems[smemIndex];
            LeftTupleNode liaNode = (LeftInputAdapterNode) qpmem.getPathEndNode().getPathNodes()[0];
            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();
                bit = 1;
            } else {
                // lia is in shared segment, so point to next node
                node = liaNode.getSinkPropagator().getFirstLeftTupleSink();
                // skip the liaNode memory
                nodeMem = smem.getNodeMemories().getFirst().getNext();
                bit = 2;
            }
            trgTuples = smem.getStagedLeftTuples().takeAll();
            stackEntry = new StackEntry(node, bit, null, pmem, nodeMem, smems, smemIndex, trgTuples, false, true);
            if (log.isTraceEnabled()) {
                int offset = getOffset(stackEntry.getNode());
                log.trace("{} ORQueue branch={} {} {}", indent(offset), i, stackEntry.getNode().toString(), trgTuples.toStringSizes());
            }
            stack.add(stackEntry);
        }
        return true;
    } else {
        return false;
    }
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory) QueryElementNode(org.drools.core.reteoo.QueryElementNode) QueryElementNodeMemory(org.drools.core.reteoo.QueryElementNode.QueryElementNodeMemory) LeftTupleNode(org.drools.core.reteoo.LeftTupleNode) PathMemory(org.drools.core.reteoo.PathMemory) RiaPathMemory(org.drools.core.reteoo.RiaPathMemory) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode)

Example 2 with LeftTupleNode

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

the class AddRemoveRule method removeRule.

/**
 * This method is called before the rule nodes are removed from the network.
 * For remove tuples are processed before the segments and pmems have been adjusted
 */
public static void removeRule(TerminalNode tn, InternalWorkingMemory[] wms, InternalKnowledgeBase kBase) {
    if (log.isTraceEnabled()) {
        log.trace("Removing Rule {}", tn.getRule().getName());
    }
    boolean hasProtos = kBase.hasSegmentPrototypes();
    boolean hasWms = wms.length > 0;
    if (!hasProtos && !hasWms) {
        return;
    }
    RuleImpl rule = tn.getRule();
    LeftTupleNode firstSplit = getNetworkSplitPoint(tn);
    PathEndNodes pathEndNodes = getPathEndNodes(kBase, firstSplit, tn, rule, hasProtos, hasWms);
    for (InternalWorkingMemory wm : wms) {
        wm.flushPropagations();
        PathEndNodeMemories tnms = getPathEndMemories(wm, pathEndNodes);
        if (!tnms.subjectPmems.isEmpty()) {
            if (NodeTypeEnums.LeftInputAdapterNode == firstSplit.getType() && firstSplit.getAssociationsSize() == 1) {
                if (tnms.subjectPmem != null) {
                    flushStagedTuples(firstSplit, tnms.subjectPmem, wm);
                }
                processLeftTuples(firstSplit, wm, false, tn.getRule());
                removeNewPaths(wm, tnms.subjectPmems);
            } else {
                flushStagedTuples(tn, tnms.subjectPmem, pathEndNodes, wm);
                processLeftTuples(firstSplit, wm, false, tn.getRule());
                removeNewPaths(wm, tnms.subjectPmems);
                Map<PathMemory, SegmentMemory[]> prevSmemsLookup = reInitPathMemories(tnms.otherPmems, tn);
                // must collect all visited SegmentMemories, for link notification
                Set<SegmentMemory> smemsToNotify = handleExistingPaths(tn, prevSmemsLookup, tnms.otherPmems, wm, ExistingPathStrategy.REMOVE_STRATEGY);
                notifySegments(smemsToNotify, wm);
            }
        }
        if (tnms.subjectPmem != null && tnms.subjectPmem.isInitialized() && tnms.subjectPmem.getRuleAgendaItem().isQueued()) {
            // SubjectPmem can be null, if it was never initialized
            tnms.subjectPmem.getRuleAgendaItem().dequeue();
        }
    }
}
Also used : InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) SegmentMemory(org.drools.core.reteoo.SegmentMemory) LeftTupleNode(org.drools.core.reteoo.LeftTupleNode) RuleImpl(org.drools.core.definitions.rule.impl.RuleImpl) PathMemory(org.drools.core.reteoo.PathMemory)

Example 3 with LeftTupleNode

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

the class AddRemoveRule method addRule.

/**
 * This method is called after the rule nodes have been added to the network
 * For add tuples are processed after the segments and pmems have been adjusted
 */
public static void addRule(TerminalNode tn, InternalWorkingMemory[] wms, InternalKnowledgeBase kBase) {
    if (log.isTraceEnabled()) {
        log.trace("Adding Rule {}", tn.getRule().getName());
    }
    boolean hasProtos = kBase.hasSegmentPrototypes();
    boolean hasWms = wms.length > 0;
    if (!hasProtos && !hasWms) {
        return;
    }
    RuleImpl rule = tn.getRule();
    LeftTupleNode firstSplit = getNetworkSplitPoint(tn);
    PathEndNodes pathEndNodes = getPathEndNodes(kBase, firstSplit, tn, rule, hasProtos, hasWms);
    for (InternalWorkingMemory wm : wms) {
        wm.flushPropagations();
        if (NodeTypeEnums.LeftInputAdapterNode == firstSplit.getType() && firstSplit.getAssociationsSize() == 1) {
            // rule added with no sharing
            insertLiaFacts(firstSplit, wm);
        } else {
            PathEndNodeMemories tnms = getPathEndMemories(wm, pathEndNodes);
            if (tnms.subjectPmem == null) {
                // If the existing PathMemories are not yet initialized there are no Segments or tuples to process
                continue;
            }
            Map<PathMemory, SegmentMemory[]> prevSmemsLookup = reInitPathMemories(tnms.otherPmems, null);
            // must collect all visited SegmentMemories, for link notification
            Set<SegmentMemory> smemsToNotify = handleExistingPaths(tn, prevSmemsLookup, tnms.otherPmems, wm, ExistingPathStrategy.ADD_STRATEGY);
            addNewPaths(wm, smemsToNotify, tnms.subjectPmems);
            processLeftTuples(firstSplit, wm, true, rule);
            notifySegments(smemsToNotify, wm);
        }
    }
    if (hasWms) {
        insertFacts(pathEndNodes, wms);
    } else {
        for (PathEndNode node : pathEndNodes.otherEndNodes) {
            node.resetPathMemSpec(null);
        }
    }
}
Also used : InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) SegmentMemory(org.drools.core.reteoo.SegmentMemory) LeftTupleNode(org.drools.core.reteoo.LeftTupleNode) PathEndNode(org.drools.core.reteoo.PathEndNode) RuleImpl(org.drools.core.definitions.rule.impl.RuleImpl) PathMemory(org.drools.core.reteoo.PathMemory)

Example 4 with LeftTupleNode

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

the class NodePositionInPathTest method test.

@Test
public void test() {
    String drl = "rule R1 when\n" + "    Integer()\n" + "    exists( Integer() and Integer() )\n" + "    String()\n" + "then\n" + "end\n" + "rule R2 when\n" + "    Integer()\n" + "    exists( Integer() and String() )\n" + "then\n" + "end\n";
    KieBase kbase = new KieHelper().addContent(drl, ResourceType.DRL).build();
    ReteDumper.dumpRete(((InternalKnowledgeBase) kbase));
    Rete rete = ((KnowledgeBaseImpl) kbase).getRete();
    LeftInputAdapterNode liaNode = null;
    for (ObjectTypeNode otn : rete.getObjectTypeNodes()) {
        Class<?> otnType = ((ClassObjectType) otn.getObjectType()).getClassType();
        if (Integer.class == otnType) {
            liaNode = (LeftInputAdapterNode) otn.getObjectSinkPropagator().getSinks()[0];
        }
    }
    assertEquals(0, liaNode.getPositionInPath());
    LeftTupleSink[] liaSinks = liaNode.getSinkPropagator().getSinks();
    BetaNode join1 = (BetaNode) liaSinks[0];
    assertEquals(1, join1.getPositionInPath());
    ExistsNode ex1 = (ExistsNode) liaSinks[1];
    assertEquals(1, ex1.getPositionInPath());
    BetaNode join2 = (BetaNode) ex1.getSinkPropagator().getSinks()[0];
    assertEquals(2, join2.getPositionInPath());
    RuleTerminalNode rtn1 = (RuleTerminalNode) join2.getSinkPropagator().getSinks()[0];
    assertEquals(3, rtn1.getPositionInPath());
    ExistsNode ex2 = (ExistsNode) liaSinks[2];
    assertEquals(1, ex2.getPositionInPath());
    RuleTerminalNode rtn2 = (RuleTerminalNode) ex2.getSinkPropagator().getSinks()[0];
    assertEquals(2, rtn2.getPositionInPath());
    BetaNode join3 = (BetaNode) join1.getSinkPropagator().getSinks()[0];
    assertEquals(2, join3.getPositionInPath());
    RightInputAdapterNode ria1 = (RightInputAdapterNode) join3.getSinkPropagator().getSinks()[0];
    assertEquals(3, ria1.getPositionInPath());
    BetaNode join4 = (BetaNode) join1.getSinkPropagator().getSinks()[1];
    assertEquals(2, join4.getPositionInPath());
    RightInputAdapterNode ria2 = (RightInputAdapterNode) join4.getSinkPropagator().getSinks()[0];
    assertEquals(3, ria2.getPositionInPath());
    LeftTupleNode[] rtn1PathNodes = rtn1.getPathNodes();
    assertEquals(4, rtn1PathNodes.length);
    checkNodePosition(rtn1PathNodes, liaNode);
    checkNodePosition(rtn1PathNodes, ex1);
    checkNodePosition(rtn1PathNodes, join2);
    checkNodePosition(rtn1PathNodes, rtn1);
    LeftTupleNode[] rtn2PathNodes = rtn2.getPathNodes();
    assertEquals(3, rtn2PathNodes.length);
    checkNodePosition(rtn2PathNodes, liaNode);
    checkNodePosition(rtn2PathNodes, ex2);
    checkNodePosition(rtn2PathNodes, rtn2);
    LeftTupleNode[] ria1PathNodes = ria1.getPathNodes();
    assertEquals(4, ria1PathNodes.length);
    checkNodePosition(ria1PathNodes, liaNode);
    checkNodePosition(ria1PathNodes, join1);
    checkNodePosition(ria1PathNodes, join3);
    checkNodePosition(ria1PathNodes, ria1);
    LeftTupleNode[] ria2PathNodes = ria2.getPathNodes();
    assertEquals(4, ria2PathNodes.length);
    checkNodePosition(ria2PathNodes, liaNode);
    checkNodePosition(ria2PathNodes, join1);
    checkNodePosition(ria2PathNodes, join4);
    checkNodePosition(ria2PathNodes, ria2);
}
Also used : Rete(org.drools.core.reteoo.Rete) BetaNode(org.drools.core.reteoo.BetaNode) ClassObjectType(org.drools.core.base.ClassObjectType) ObjectTypeNode(org.drools.core.reteoo.ObjectTypeNode) LeftTupleSink(org.drools.core.reteoo.LeftTupleSink) KieHelper(org.kie.internal.utils.KieHelper) KnowledgeBaseImpl(org.drools.core.impl.KnowledgeBaseImpl) ExistsNode(org.drools.core.reteoo.ExistsNode) KieBase(org.kie.api.KieBase) LeftTupleNode(org.drools.core.reteoo.LeftTupleNode) InternalKnowledgeBase(org.drools.core.impl.InternalKnowledgeBase) RightInputAdapterNode(org.drools.core.reteoo.RightInputAdapterNode) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode) RuleTerminalNode(org.drools.core.reteoo.RuleTerminalNode) Test(org.junit.Test)

Example 5 with LeftTupleNode

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

the class AddRemoveRule method removeRule.

/**
 * This method is called before the rule nodes are removed from the network.
 * For remove tuples are processed before the segments and pmems have been adjusted
 */
public static void removeRule(TerminalNode tn, Collection<InternalWorkingMemory> wms, RuleBase kBase) {
    if (log.isTraceEnabled()) {
        log.trace("Removing Rule {}", tn.getRule().getName());
    }
    boolean hasProtos = kBase.hasSegmentPrototypes();
    boolean hasWms = !wms.isEmpty();
    if (!hasProtos && !hasWms) {
        return;
    }
    RuleImpl rule = tn.getRule();
    LeftTupleNode firstSplit = getNetworkSplitPoint(tn);
    PathEndNodes pathEndNodes = getPathEndNodes(kBase, firstSplit, tn, rule, hasProtos, hasWms);
    for (InternalWorkingMemory wm : wms) {
        wm.flushPropagations();
        PathEndNodeMemories tnms = getPathEndMemories(wm, pathEndNodes);
        if (!tnms.subjectPmems.isEmpty()) {
            if (NodeTypeEnums.LeftInputAdapterNode == firstSplit.getType() && firstSplit.getAssociationsSize() == 1) {
                if (tnms.subjectPmem != null) {
                    flushStagedTuples(firstSplit, tnms.subjectPmem, wm);
                }
                processLeftTuples(firstSplit, wm, false, tn.getRule());
                removeNewPaths(wm, tnms.subjectPmems);
            } else {
                flushStagedTuples(tn, tnms.subjectPmem, pathEndNodes, wm);
                processLeftTuples(firstSplit, wm, false, tn.getRule());
                removeNewPaths(wm, tnms.subjectPmems);
                Map<PathMemory, SegmentMemory[]> prevSmemsLookup = reInitPathMemories(tnms.otherPmems, tn);
                // must collect all visited SegmentMemories, for link notification
                Set<SegmentMemory> smemsToNotify = handleExistingPaths(tn, prevSmemsLookup, tnms.otherPmems, wm, ExistingPathStrategy.REMOVE_STRATEGY);
                notifySegments(smemsToNotify, wm);
            }
        }
        if (tnms.subjectPmem != null && tnms.subjectPmem.isInitialized() && tnms.subjectPmem.getRuleAgendaItem().isQueued()) {
            // SubjectPmem can be null, if it was never initialized
            tnms.subjectPmem.getRuleAgendaItem().dequeue();
        }
    }
    if (!hasWms) {
        for (PathEndNode node : pathEndNodes.otherEndNodes) {
            node.resetPathMemSpec(null);
        }
    }
}
Also used : InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) SegmentMemory(org.drools.core.reteoo.SegmentMemory) LeftTupleNode(org.drools.core.reteoo.LeftTupleNode) PathEndNode(org.drools.core.reteoo.PathEndNode) RuleImpl(org.drools.core.definitions.rule.impl.RuleImpl) PathMemory(org.drools.core.reteoo.PathMemory)

Aggregations

LeftTupleNode (org.drools.core.reteoo.LeftTupleNode)20 SegmentMemory (org.drools.core.reteoo.SegmentMemory)14 PathMemory (org.drools.core.reteoo.PathMemory)13 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)11 Memory (org.drools.core.common.Memory)6 AccumulateMemory (org.drools.core.reteoo.AccumulateNode.AccumulateMemory)6 BetaMemory (org.drools.core.reteoo.BetaMemory)6 FromMemory (org.drools.core.reteoo.FromNode.FromMemory)6 ObjectTypeNodeMemory (org.drools.core.reteoo.ObjectTypeNode.ObjectTypeNodeMemory)6 RiaNodeMemory (org.drools.core.reteoo.RightInputAdapterNode.RiaNodeMemory)6 SegmentNodeMemory (org.drools.core.reteoo.SegmentNodeMemory)6 TupleMemory (org.drools.core.reteoo.TupleMemory)6 HashSet (java.util.HashSet)5 PathEndNode (org.drools.core.reteoo.PathEndNode)5 RuleImpl (org.drools.core.definitions.rule.impl.RuleImpl)4 BetaNode (org.drools.core.reteoo.BetaNode)4 LeftTupleSink (org.drools.core.reteoo.LeftTupleSink)4 LeftInputAdapterNode (org.drools.core.reteoo.LeftInputAdapterNode)3 ClassObjectType (org.drools.core.base.ClassObjectType)2 PropagationContextFactory (org.drools.core.common.PropagationContextFactory)2