Search in sources :

Example 11 with LeftTupleSink

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

the class PassiveQueryTest method testPassiveQueryUsingSegmentPropagator.

@Test
public void testPassiveQueryUsingSegmentPropagator() throws Exception {
    String str = "global java.util.List list\n" + "query Q (Integer i)\n" + "    String( this == i.toString() )\n" + "end\n" + "rule R1a @Propagation(IMMEDIATE) when\n" + "    $i : Integer()\n" + "    ?Q( $i; )\n" + "then\n" + "    list.add( \"R1a\" );\n" + "end\n" + "rule R1b @Propagation(IMMEDIATE) when\n" + "    $i : Integer()\n" + "    ?Q( $i; )\n" + "    Long( intValue == $i )\n" + "then\n" + "    list.add( \"R1b\" );\n" + "end\n" + "rule R2 when\n" + "    $i : Integer()\n" + "    ?Q( $i; )\n" + "then\n" + "    list.add( \"R2\" );\n" + "end\n";
    KieBase kbase = new KieHelper().addContent(str, ResourceType.DRL).build();
    KieSession ksession = kbase.newKieSession();
    List<String> list = new ArrayList<String>();
    ksession.setGlobal("list", list);
    ksession.insert(1L);
    FactHandle fh = ksession.insert(1);
    ksession.insert("1");
    Rete rete = ((KnowledgeBaseImpl) kbase).getRete();
    LeftInputAdapterNode lia = null;
    for (ObjectTypeNode otn : rete.getObjectTypeNodes()) {
        if (Integer.class == otn.getObjectType().getValueType().getClassType()) {
            lia = (LeftInputAdapterNode) otn.getObjectSinkPropagator().getSinks()[0];
            break;
        }
    }
    LeftTupleSink[] sinks = lia.getSinkPropagator().getSinks();
    QueryElementNode q1 = (QueryElementNode) sinks[0];
    QueryElementNode q2 = (QueryElementNode) sinks[1];
    InternalWorkingMemory wm = (InternalWorkingMemory) ksession;
    wm.flushPropagations();
    Memory memory1 = wm.getNodeMemory(q1);
    assertTrue(memory1.getSegmentMemory().getStagedLeftTuples().isEmpty());
    ksession.fireAllRules();
    assertEquals(1, list.size());
    assertEquals("R2", list.get(0));
    list.clear();
    ksession.delete(fh);
    ksession.insert(1);
    ksession.fireAllRules();
    assertEquals(3, list.size());
}
Also used : Rete(org.drools.core.reteoo.Rete) FactHandle(org.kie.api.runtime.rule.FactHandle) Memory(org.drools.core.common.Memory) InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) QueryElementNode(org.drools.core.reteoo.QueryElementNode) ArrayList(java.util.ArrayList) ObjectTypeNode(org.drools.core.reteoo.ObjectTypeNode) LeftTupleSink(org.drools.core.reteoo.LeftTupleSink) KieHelper(org.kie.internal.utils.KieHelper) KnowledgeBaseImpl(org.drools.core.impl.KnowledgeBaseImpl) InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) KieBase(org.kie.api.KieBase) KieSession(org.kie.api.runtime.KieSession) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode) Test(org.junit.Test)

Example 12 with LeftTupleSink

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

the class PathEndNodeTest method testSubNetworkSharing.

@Test
public void testSubNetworkSharing() throws Exception {
    String str = "package org.test \n" + "rule xxx \n" + "when \n" + "  $s : String()\n" + "  not( Integer() and Long() )\n" + "then \n" + "end  \n" + "rule yyy \n" + "when \n" + "  $s : String()\n" + "  not( Integer() and Long() )\n" + "then \n" + "end  \n";
    InternalKnowledgeBase kbase = (InternalKnowledgeBase) new KieHelper().addContent(str, ResourceType.DRL).build();
    EntryPointNode epn = kbase.getRete().getEntryPointNode(EntryPointId.DEFAULT);
    ObjectTypeNode otn = epn.getObjectTypeNodes().get(new ClassObjectType(Long.class));
    BetaNode beta1 = (BetaNode) otn.getObjectSinkPropagator().getSinks()[0];
    RightInputAdapterNode rian = (RightInputAdapterNode) beta1.getSinkPropagator().getSinks()[0];
    BetaNode beta2 = (BetaNode) rian.getObjectSinkPropagator().getSinks()[0];
    LeftTupleSink[] sinks = beta2.getSinkPropagator().getSinks();
    RuleTerminalNode rtn1 = (RuleTerminalNode) sinks[0];
    RuleTerminalNode rtn2 = (RuleTerminalNode) sinks[1];
    assertEquals(3, rian.getPathEndNodes().length);
    assertTrue(asList(rian.getPathEndNodes()).containsAll(asList(rtn1, rtn2, rian)));
    kbase.removeRule("org.test", "xxx");
    assertEquals(2, rian.getPathEndNodes().length);
    RuleTerminalNode remainingRTN = rtn1.getRule().getName().equals("yyy") ? rtn1 : rtn2;
    assertTrue(asList(rian.getPathEndNodes()).containsAll(asList(remainingRTN, rian)));
}
Also used : EntryPointNode(org.drools.core.reteoo.EntryPointNode) 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) InternalKnowledgeBase(org.drools.core.impl.InternalKnowledgeBase) RightInputAdapterNode(org.drools.core.reteoo.RightInputAdapterNode) RuleTerminalNode(org.drools.core.reteoo.RuleTerminalNode) Test(org.junit.Test)

Example 13 with LeftTupleSink

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

the class LeftTupleIterator method getFirstLeftTuple.

public LeftTuple getFirstLeftTuple(LeftTupleSource source, LeftTupleSink sink, InternalWorkingMemory wm) {
    if (source instanceof AccumulateNode) {
        AccumulateMemory accmem = (AccumulateMemory) wm.getNodeMemory((MemoryFactory) source);
        BetaMemory memory = accmem.getBetaMemory();
        FastIterator localIt = memory.getLeftTupleMemory().fullFastIterator();
        Tuple leftTuple = BetaNode.getFirstTuple(memory.getLeftTupleMemory(), localIt);
        if (leftTuple != null) {
            AccumulateContext accctx = (AccumulateContext) leftTuple.getContextObject();
            return accctx.getResultLeftTuple();
        }
        return null;
    }
    if (source instanceof JoinNode || source instanceof NotNode || source instanceof FromNode || source instanceof AccumulateNode) {
        BetaMemory memory;
        FastIterator localIt;
        if (source instanceof FromNode) {
            memory = ((FromMemory) wm.getNodeMemory((MemoryFactory) source)).getBetaMemory();
        } else if (source instanceof AccumulateNode) {
            memory = ((AccumulateMemory) wm.getNodeMemory((MemoryFactory) source)).getBetaMemory();
        } else {
            memory = (BetaMemory) wm.getNodeMemory((MemoryFactory) source);
        }
        localIt = memory.getLeftTupleMemory().fullFastIterator();
        Tuple leftTuple = BetaNode.getFirstTuple(memory.getLeftTupleMemory(), localIt);
        while (leftTuple != null) {
            for (LeftTuple childleftTuple = leftTuple.getFirstChild(); childleftTuple != null; childleftTuple = childleftTuple.getHandleNext()) {
                if (childleftTuple.getTupleSink() == sink) {
                    return childleftTuple;
                }
            }
            leftTuple = (LeftTuple) localIt.next(leftTuple);
        }
    }
    if (source instanceof ExistsNode) {
        BetaMemory memory = (BetaMemory) wm.getNodeMemory((MemoryFactory) source);
        FastIterator localIt = memory.getRightTupleMemory().fullFastIterator();
        RightTuple rightTuple = (RightTuple) BetaNode.getFirstTuple(memory.getRightTupleMemory(), localIt);
        while (rightTuple != null) {
            if (rightTuple.getBlocked() != null) {
                for (LeftTuple leftTuple = rightTuple.getBlocked(); leftTuple != null; leftTuple = leftTuple.getBlockedNext()) {
                    for (LeftTuple childleftTuple = leftTuple.getFirstChild(); childleftTuple != null; childleftTuple = childleftTuple.getHandleNext()) {
                        if (childleftTuple.getTupleSink() == sink) {
                            return childleftTuple;
                        }
                    }
                }
            }
            rightTuple = (RightTuple) localIt.next(rightTuple);
        }
    } else if (source instanceof LeftInputAdapterNode) {
        ObjectSource os = ((LeftInputAdapterNode) source).getParentObjectSource();
        while (!(os instanceof ObjectTypeNode)) {
            os = os.getParentObjectSource();
        }
        ObjectTypeNode otn = (ObjectTypeNode) os;
        otnIterator = wm.getNodeMemory(otn).iterator();
        while (otnIterator.hasNext()) {
            InternalFactHandle handle = otnIterator.next();
            LeftTuple leftTuple = handle.findFirstLeftTuple(lt -> lt.getTupleSink() == sink);
            if (leftTuple != null) {
                return leftTuple;
            }
        }
    } else if (source instanceof EvalConditionNode || source instanceof QueryElementNode) {
        LeftTuple parentLeftTuple = getFirstLeftTuple(source.getLeftTupleSource(), (LeftTupleSink) source, wm);
        while (parentLeftTuple != null) {
            for (LeftTuple leftTuple = parentLeftTuple.getFirstChild(); leftTuple != null; leftTuple = leftTuple.getHandleNext()) {
                if (leftTuple.getTupleSink() == sink) {
                    return leftTuple;
                }
            }
            parentLeftTuple = getNextLeftTuple(source.getLeftTupleSource(), (LeftTupleSink) source, parentLeftTuple, wm);
        }
    }
    return null;
}
Also used : NotNode(org.drools.core.reteoo.NotNode) ExistsNode(org.drools.core.reteoo.ExistsNode) EvalConditionNode(org.drools.core.reteoo.EvalConditionNode) FastIterator(org.drools.core.util.FastIterator) AccumulateNode(org.drools.core.reteoo.AccumulateNode) AccumulateContext(org.drools.core.reteoo.AccumulateNode.AccumulateContext) BetaMemory(org.drools.core.reteoo.BetaMemory) JoinNode(org.drools.core.reteoo.JoinNode) FromNode(org.drools.core.reteoo.FromNode) LeftTuple(org.drools.core.reteoo.LeftTuple) RightTuple(org.drools.core.reteoo.RightTuple) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode) QueryElementNode(org.drools.core.reteoo.QueryElementNode) Tuple(org.drools.core.spi.Tuple) BetaNode(org.drools.core.reteoo.BetaNode) AccumulateMemory(org.drools.core.reteoo.AccumulateNode.AccumulateMemory) FromMemory(org.drools.core.reteoo.FromNode.FromMemory) ObjectSource(org.drools.core.reteoo.ObjectSource) LeftTupleSink(org.drools.core.reteoo.LeftTupleSink) ObjectTypeNode(org.drools.core.reteoo.ObjectTypeNode) Iterator(org.drools.core.util.Iterator) LeftTupleSource(org.drools.core.reteoo.LeftTupleSource) AccumulateMemory(org.drools.core.reteoo.AccumulateNode.AccumulateMemory) NotNode(org.drools.core.reteoo.NotNode) EvalConditionNode(org.drools.core.reteoo.EvalConditionNode) AccumulateNode(org.drools.core.reteoo.AccumulateNode) JoinNode(org.drools.core.reteoo.JoinNode) QueryElementNode(org.drools.core.reteoo.QueryElementNode) ObjectTypeNode(org.drools.core.reteoo.ObjectTypeNode) LeftTupleSink(org.drools.core.reteoo.LeftTupleSink) BetaMemory(org.drools.core.reteoo.BetaMemory) FromNode(org.drools.core.reteoo.FromNode) LeftTuple(org.drools.core.reteoo.LeftTuple) ExistsNode(org.drools.core.reteoo.ExistsNode) RightTuple(org.drools.core.reteoo.RightTuple) ObjectSource(org.drools.core.reteoo.ObjectSource) FastIterator(org.drools.core.util.FastIterator) LeftTuple(org.drools.core.reteoo.LeftTuple) RightTuple(org.drools.core.reteoo.RightTuple) Tuple(org.drools.core.spi.Tuple) AccumulateContext(org.drools.core.reteoo.AccumulateNode.AccumulateContext) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode)

Example 14 with LeftTupleSink

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

the class AddRemoveRule method addNewPaths.

private static void addNewPaths(InternalWorkingMemory wm, Set<SegmentMemory> smemsToNotify, List<PathMemory> pmems) {
    // Multiple paths may be renetrant, in the case of a second subnetwork on the same rule.
    // Must make sure we don't duplicate the child smem, and when found, just update it with new pmem.
    Set<LeftTupleNode> visited = new HashSet<LeftTupleNode>();
    for (PathMemory pmem : pmems) {
        LeftTupleSink tipNode = (LeftTupleSink) pmem.getPathEndNode();
        LeftTupleNode child = tipNode;
        LeftTupleNode parent = tipNode.getLeftTupleSource();
        while (true) {
            if (visited.add(child)) {
                if (parent != null && parent.getAssociationsSize() != 1 && child.getAssociationsSize() == 1) {
                    // This is the split point that the new path enters an existing path.
                    // If the parent has other child SegmentMemorys then it must create a new child SegmentMemory
                    // If the parent is a query node, then it's internal data structure needs changing
                    // all right input data must be propagated
                    Memory mem = wm.getNodeMemories().peekNodeMemory(parent);
                    if (mem != null && mem.getSegmentMemory() != null) {
                        SegmentMemory sm = mem.getSegmentMemory();
                        if (sm.getFirst() != null && sm.size() < parent.getSinkPropagator().size()) {
                            LeftTupleSink[] sinks = parent.getSinkPropagator().getSinks();
                            for (int i = sm.size(); i < sinks.length; i++) {
                                SegmentMemory childSmem = SegmentUtilities.createChildSegment(wm, sinks[i]);
                                sm.add(childSmem);
                                pmem.setSegmentMemory(childSmem.getPos(), childSmem);
                                smemsToNotify.add(childSmem);
                            }
                        }
                        correctMemoryOnSplitsChanged(parent, null, wm);
                    }
                } else {
                    Memory mem = wm.getNodeMemories().peekNodeMemory(child);
                    // The root of each segment
                    if (mem != null) {
                        SegmentMemory sm = mem.getSegmentMemory();
                        if (sm != null && !sm.getPathMemories().contains(pmem)) {
                            sm.addPathMemory(pmem);
                            pmem.setSegmentMemory(sm.getPos(), sm);
                            sm.notifyRuleLinkSegment(wm, pmem);
                        }
                    }
                }
            } else {
                Memory mem = wm.getNodeMemories().peekNodeMemory(child);
                if (mem != null) {
                    mem.getSegmentMemory().notifyRuleLinkSegment(wm, pmem);
                }
            }
            if (parent == null) {
                break;
            }
            child = parent;
            parent = parent.getLeftTupleSource();
        }
    }
}
Also used : 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) LeftTupleSink(org.drools.core.reteoo.LeftTupleSink) LeftTupleNode(org.drools.core.reteoo.LeftTupleNode) HashSet(java.util.HashSet) PathMemory(org.drools.core.reteoo.PathMemory)

Example 15 with LeftTupleSink

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

the class RuleNetworkEvaluator method evalStackEntry.

public void evalStackEntry(StackEntry entry, LinkedList<StackEntry> stack, RuleExecutor executor, InternalAgenda agenda) {
    NetworkNode node = entry.getNode();
    Memory nodeMem = entry.getNodeMem();
    TupleSets<LeftTuple> trgTuples = entry.getTrgTuples();
    if (node.getType() == NodeTypeEnums.QueryElementNode) {
        // copy across the results, if any from the query node memory
        QueryElementNodeMemory qmem = (QueryElementNodeMemory) nodeMem;
        qmem.setNodeCleanWithoutNotify();
        qmem.getResultLeftTuples().addTo(trgTuples);
    }
    LeftTupleSinkNode sink = entry.getSink();
    PathMemory pmem = entry.getRmem();
    SegmentMemory[] smems = entry.getSmems();
    int smemIndex = entry.getSmemIndex();
    boolean processRian = entry.isProcessRian();
    long bit = entry.getBit();
    if (entry.isResumeFromNextNode()) {
        SegmentMemory smem = smems[smemIndex];
        if (node != smem.getTipNode()) {
            // get next node and node memory in the segment
            LeftTupleSink nextSink = sink.getNextLeftTupleSinkNode();
            if (nextSink == null) {
                node = sink;
            } else {
                // there is a nested subnetwork, take out path
                node = nextSink;
            }
            nodeMem = nodeMem.getNext();
            // update bit to new node
            bit = bit << 1;
        } else {
            // Reached end of segment, start on new segment.
            SegmentPropagator.propagate(smem, trgTuples, agenda.getWorkingMemory());
            smem = smems[++smemIndex];
            trgTuples = smem.getStagedLeftTuples().takeAll();
            node = smem.getRootNode();
            nodeMem = smem.getNodeMemories().getFirst();
            // update bit to start of new segment
            bit = 1;
        }
    }
    if (log.isTraceEnabled()) {
        int offset = getOffset(node);
        log.trace("{} Resume {} {}", indent(offset), node.toString(), trgTuples.toStringSizes());
    }
    innerEval(pmem, node, bit, nodeMem, smems, smemIndex, trgTuples, agenda, stack, processRian, 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) LeftTupleSink(org.drools.core.reteoo.LeftTupleSink) QueryElementNodeMemory(org.drools.core.reteoo.QueryElementNode.QueryElementNodeMemory) NetworkNode(org.drools.core.common.NetworkNode) LeftTuple(org.drools.core.reteoo.LeftTuple) LeftTupleSinkNode(org.drools.core.reteoo.LeftTupleSinkNode) PathMemory(org.drools.core.reteoo.PathMemory) RiaPathMemory(org.drools.core.reteoo.RiaPathMemory)

Aggregations

LeftTupleSink (org.drools.core.reteoo.LeftTupleSink)15 ObjectTypeNode (org.drools.core.reteoo.ObjectTypeNode)11 LeftInputAdapterNode (org.drools.core.reteoo.LeftInputAdapterNode)9 Test (org.junit.Test)8 KieBase (org.kie.api.KieBase)7 AccumulateMemory (org.drools.core.reteoo.AccumulateNode.AccumulateMemory)6 BetaMemory (org.drools.core.reteoo.BetaMemory)6 FromMemory (org.drools.core.reteoo.FromNode.FromMemory)6 KieSession (org.kie.api.runtime.KieSession)6 KieHelper (org.kie.internal.utils.KieHelper)5 ArrayList (java.util.ArrayList)4 ClassObjectType (org.drools.core.base.ClassObjectType)4 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)4 Memory (org.drools.core.common.Memory)4 InternalKnowledgeBase (org.drools.core.impl.InternalKnowledgeBase)4 BetaNode (org.drools.core.reteoo.BetaNode)4 LeftTuple (org.drools.core.reteoo.LeftTuple)4 PathMemory (org.drools.core.reteoo.PathMemory)4 RightInputAdapterNode (org.drools.core.reteoo.RightInputAdapterNode)4 TupleMemory (org.drools.core.reteoo.TupleMemory)4