Search in sources :

Example 1 with MemoryFactory

use of org.drools.core.common.MemoryFactory in project drools by kiegroup.

the class SegmentUtilities method updateRiaAndTerminalMemory.

/**
 * This adds the segment memory to the terminal node or ria node's list of memories.
 * In the case of the terminal node this allows it to know that all segments from
 * the tip to root are linked.
 * In the case of the ria node its all the segments up to the start of the subnetwork.
 * This is because the rianode only cares if all of it's segments are linked, then
 * it sets the bit of node it is the right input for.
 */
private static int updateRiaAndTerminalMemory(LeftTupleSource lt, LeftTupleSource originalLt, SegmentMemory smem, InternalWorkingMemory wm, boolean fromPrototype, int nodeTypesInSegment) {
    nodeTypesInSegment = checkSegmentBoundary(lt, wm, nodeTypesInSegment);
    for (LeftTupleSink sink : lt.getSinkPropagator().getSinks()) {
        if (NodeTypeEnums.isLeftTupleSource(sink)) {
            nodeTypesInSegment = updateRiaAndTerminalMemory((LeftTupleSource) sink, originalLt, smem, wm, fromPrototype, nodeTypesInSegment);
        } else if (sink.getType() == NodeTypeEnums.RightInputAdaterNode) {
            // Even though we don't add the pmem and smem together, all pmem's for all pathend nodes must be initialized
            RiaNodeMemory riaMem = (RiaNodeMemory) wm.getNodeMemory((MemoryFactory) sink);
            // Only add the RIANode, if the LeftTupleSource is part of the RIANode subnetwork
            if (inSubNetwork((RightInputAdapterNode) sink, originalLt)) {
                PathMemory pmem = riaMem.getRiaPathMemory();
                smem.addPathMemory(pmem);
                if (smem.getPos() < pmem.getSegmentMemories().length) {
                    pmem.setSegmentMemory(smem.getPos(), smem);
                }
                if (fromPrototype) {
                    ObjectSink[] nodes = ((RightInputAdapterNode) sink).getObjectSinkPropagator().getSinks();
                    for (ObjectSink node : nodes) {
                        // check if the SegmentMemory has been already created by the BetaNode and if so avoid to build it twice
                        if (NodeTypeEnums.isLeftTupleSource(node) && wm.getNodeMemory((MemoryFactory) node).getSegmentMemory() == null) {
                            restoreSegmentFromPrototype(wm, (LeftTupleSource) node, nodeTypesInSegment);
                        }
                    }
                } else if ((pmem.getAllLinkedMaskTest() & (1L << pmem.getSegmentMemories().length)) == 0) {
                    // must eagerly initialize child segment memories
                    ObjectSink[] nodes = ((RightInputAdapterNode) sink).getObjectSinkPropagator().getSinks();
                    for (ObjectSink node : nodes) {
                        if (NodeTypeEnums.isLeftTupleSource(node)) {
                            createSegmentMemory((LeftTupleSource) node, wm);
                        }
                    }
                }
            }
        } else if (NodeTypeEnums.isTerminalNode(sink)) {
            PathMemory pmem = (PathMemory) wm.getNodeMemory((MemoryFactory) sink);
            smem.addPathMemory(pmem);
            // with the former one and in this case doesn't have to be added to the the path memory
            if (smem.getPos() < pmem.getSegmentMemories().length) {
                pmem.setSegmentMemory(smem.getPos(), smem);
                if (smem.isSegmentLinked()) {
                    // not's can cause segments to be linked, and the rules need to be notified for evaluation
                    smem.notifyRuleLinkSegment(wm);
                }
                checkEagerSegmentCreation(sink.getLeftTupleSource(), wm, nodeTypesInSegment);
            }
        }
    }
    return nodeTypesInSegment;
}
Also used : LeftTupleSource(org.drools.core.reteoo.LeftTupleSource) RiaNodeMemory(org.drools.core.reteoo.RightInputAdapterNode.RiaNodeMemory) LeftTupleSink(org.drools.core.reteoo.LeftTupleSink) ObjectSink(org.drools.core.reteoo.ObjectSink) MemoryFactory(org.drools.core.common.MemoryFactory) RightInputAdapterNode(org.drools.core.reteoo.RightInputAdapterNode) PathMemory(org.drools.core.reteoo.PathMemory)

Example 2 with MemoryFactory

use of org.drools.core.common.MemoryFactory in project drools by kiegroup.

the class NotNodeLeftTuple method getAccumulatedObjects.

@Override
public Collection<Object> getAccumulatedObjects() {
    if (NodeTypeEnums.ExistsNode != getTupleSink().getType()) {
        return Collections.emptyList();
    }
    BetaNode betaNode = ((BetaNode) getTupleSink());
    BetaConstraints constraints = betaNode.getRawConstraints();
    InternalWorkingMemory wm = getFactHandle().getEntryPoint().getInternalWorkingMemory();
    BetaMemory bm = (BetaMemory) wm.getNodeMemory((MemoryFactory) getTupleSink());
    TupleMemory rtm = bm.getRightTupleMemory();
    FastIterator it = betaNode.getRightIterator(rtm);
    ContextEntry[] contextEntry = bm.getContext();
    constraints.updateFromTuple(contextEntry, wm, this);
    Collection<Object> result = new ArrayList<>();
    for (RightTuple rightTuple = betaNode.getFirstRightTuple(this, rtm, null, it); rightTuple != null; ) {
        RightTuple nextRight = (RightTuple) it.next(rightTuple);
        InternalFactHandle fh = rightTuple.getFactHandleForEvaluation();
        if (constraints.isAllowedCachedLeft(contextEntry, fh)) {
            result.add(fh.getObject());
        }
        rightTuple = nextRight;
    }
    return result;
}
Also used : BetaConstraints(org.drools.core.common.BetaConstraints) ArrayList(java.util.ArrayList) MemoryFactory(org.drools.core.common.MemoryFactory) ContextEntry(org.drools.core.rule.ContextEntry) InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) FastIterator(org.drools.core.util.FastIterator) InternalFactHandle(org.drools.core.common.InternalFactHandle)

Example 3 with MemoryFactory

use of org.drools.core.common.MemoryFactory in project drools by kiegroup.

the class LinkingTest method testNonReactiveSubNetworkOwnSegmentMasks.

@Test
public void testNonReactiveSubNetworkOwnSegmentMasks() throws Exception {
    String str = "";
    str += "package org.kie \n";
    str += "import " + A.class.getCanonicalName() + "\n";
    str += "import " + B.class.getCanonicalName() + "\n";
    str += "import " + C.class.getCanonicalName() + "\n";
    str += "import " + D.class.getCanonicalName() + "\n";
    str += "import " + E.class.getCanonicalName() + "\n";
    str += "import " + F.class.getCanonicalName() + "\n";
    str += "import " + G.class.getCanonicalName() + "\n";
    str += "global java.util.List list \n";
    str += "rule rule1 when \n";
    str += "   A() \n";
    str += "   exists( B() and C() ) \n";
    str += "   exists( eval(1==1) ) \n";
    str += "   D() \n";
    str += "then \n";
    str += "end \n";
    str += "rule rule2 when \n";
    str += "   A() \n";
    str += "   exists( B() and C() ) \n";
    str += "   exists( eval(1==1) ) \n";
    str += "   E() \n";
    str += "then \n";
    str += "end \n";
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add(ResourceFactory.newByteArrayResource(str.getBytes()), ResourceType.DRL);
    assertFalse(kbuilder.getErrors().toString(), kbuilder.hasErrors());
    InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
    kbase.addPackages(kbuilder.getKnowledgePackages());
    ObjectTypeNode node = getObjectTypeNode(kbase, A.class);
    InternalWorkingMemory wm = ((StatefulKnowledgeSessionImpl) kbase.newKieSession());
    LeftInputAdapterNode liaNode = (LeftInputAdapterNode) node.getObjectSinkPropagator().getSinks()[0];
    assertEquals(2, liaNode.getSinkPropagator().size());
    JoinNode bNode = (JoinNode) liaNode.getSinkPropagator().getSinks()[0];
    JoinNode cNode = (JoinNode) bNode.getSinkPropagator().getSinks()[0];
    ExistsNode exists1n = (ExistsNode) liaNode.getSinkPropagator().getSinks()[1];
    EvalConditionNode evalNode = (EvalConditionNode) exists1n.getSinkPropagator().getSinks()[0];
    ExistsNode exists2n = (ExistsNode) exists1n.getSinkPropagator().getSinks()[1];
    JoinNode dNode = (JoinNode) exists2n.getSinkPropagator().getSinks()[0];
    RuleTerminalNode rtn = (RuleTerminalNode) dNode.getSinkPropagator().getSinks()[0];
    wm.insert(new A());
    PathMemory pmem = (PathMemory) wm.getNodeMemory(rtn);
    assertEquals(4, pmem.getSegmentMemories().length);
    // the exists eval segment does not need to be linked in
    assertEquals(11, pmem.getAllLinkedMaskTest());
    RightInputAdapterNode.RiaNodeMemory riaMem = (RightInputAdapterNode.RiaNodeMemory) wm.getNodeMemory((MemoryFactory) exists1n.getRightInput());
    // second segment must be linked in
    assertEquals(2, riaMem.getRiaPathMemory().getAllLinkedMaskTest());
    wm.insert(new B());
    wm.insert(new C());
    assertEquals(2, riaMem.getRiaPathMemory().getSegmentMemories().length);
    riaMem = (RightInputAdapterNode.RiaNodeMemory) wm.getNodeMemory((MemoryFactory) exists2n.getRightInput());
    // no segments to be linked in
    assertEquals(0, riaMem.getRiaPathMemory().getAllLinkedMaskTest());
}
Also used : EvalConditionNode(org.drools.core.reteoo.EvalConditionNode) JoinNode(org.drools.core.reteoo.JoinNode) ObjectTypeNode(org.drools.core.reteoo.ObjectTypeNode) MemoryFactory(org.drools.core.common.MemoryFactory) ExistsNode(org.drools.core.reteoo.ExistsNode) InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) KnowledgeBuilder(org.kie.internal.builder.KnowledgeBuilder) InternalKnowledgeBase(org.drools.core.impl.InternalKnowledgeBase) RightInputAdapterNode(org.drools.core.reteoo.RightInputAdapterNode) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode) RuleTerminalNode(org.drools.core.reteoo.RuleTerminalNode) PathMemory(org.drools.core.reteoo.PathMemory) Test(org.junit.Test)

Example 4 with MemoryFactory

use of org.drools.core.common.MemoryFactory 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 you make a fix here, it most likely needs to be in PhreakActivationIteratorToo ***
    // Must iterate up until a node with memory is found, this can be followed to find the LeftTuples
    // which provide the potential peer of the tuple being added or removed
    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()) {
                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
    LeftInputAdapterNode lian = (LeftInputAdapterNode) node;
    ObjectSource os = lian.getObjectSource();
    while (os.getType() != NodeTypeEnums.ObjectTypeNode) {
        os = os.getParentObjectSource();
    }
    ObjectTypeNode otn = (ObjectTypeNode) os;
    final ObjectTypeNodeMemory omem = wm.getNodeMemory(otn);
    if (omem == null) {
        // no OTN memory yet, i.e. no inserted matching objects, so no Tuples to process
        return;
    }
    Iterator<InternalFactHandle> it = omem.iterator();
    while (it.hasNext()) {
        InternalFactHandle fh = it.next();
        fh.forEachLeftTuple(lt -> {
            LeftTuple nextLt = lt.getHandleNext();
            // Each lt is for a different lian, skip any lian not associated with the rule. Need to use lt parent (souce) not child to check the lian.
            if (lt.getTupleSource().isAssociatedWith(rule)) {
                visitChild(lt, insert, wm, rule);
                if (lt.getHandlePrevious() != null) {
                    lt.getHandlePrevious().setHandleNext(nextLt);
                }
                if (nextLt != null) {
                    nextLt.setHandlePrevious(lt.getHandlePrevious());
                }
            }
        });
    }
}
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) ObjectTypeNode(org.drools.core.reteoo.ObjectTypeNode) 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) ObjectTypeNodeMemory(org.drools.core.reteoo.ObjectTypeNode.ObjectTypeNodeMemory) FromMemory(org.drools.core.reteoo.FromNode.FromMemory) ObjectSource(org.drools.core.reteoo.ObjectSource) FastIterator(org.drools.core.util.FastIterator) InternalFactHandle(org.drools.core.common.InternalFactHandle) 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) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode)

Aggregations

MemoryFactory (org.drools.core.common.MemoryFactory)4 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)3 PathMemory (org.drools.core.reteoo.PathMemory)3 InternalFactHandle (org.drools.core.common.InternalFactHandle)2 LeftInputAdapterNode (org.drools.core.reteoo.LeftInputAdapterNode)2 ObjectTypeNode (org.drools.core.reteoo.ObjectTypeNode)2 RightInputAdapterNode (org.drools.core.reteoo.RightInputAdapterNode)2 RiaNodeMemory (org.drools.core.reteoo.RightInputAdapterNode.RiaNodeMemory)2 FastIterator (org.drools.core.util.FastIterator)2 ArrayList (java.util.ArrayList)1 BetaConstraints (org.drools.core.common.BetaConstraints)1 Memory (org.drools.core.common.Memory)1 InternalKnowledgeBase (org.drools.core.impl.InternalKnowledgeBase)1 AccumulateContext (org.drools.core.reteoo.AccumulateNode.AccumulateContext)1 AccumulateMemory (org.drools.core.reteoo.AccumulateNode.AccumulateMemory)1 BetaMemory (org.drools.core.reteoo.BetaMemory)1 EvalConditionNode (org.drools.core.reteoo.EvalConditionNode)1 ExistsNode (org.drools.core.reteoo.ExistsNode)1 FromMemory (org.drools.core.reteoo.FromNode.FromMemory)1 JoinNode (org.drools.core.reteoo.JoinNode)1