Search in sources :

Example 6 with PathMemory

use of org.drools.core.reteoo.PathMemory 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 7 with PathMemory

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

the class SegmentUtilities method createChildSegmentForTerminalNode.

public static SegmentMemory createChildSegmentForTerminalNode(LeftTupleNode node, Memory memory) {
    // rtns or riatns don't need a queue
    SegmentMemory childSmem = new SegmentMemory(node);
    PathMemory pmem = NodeTypeEnums.isTerminalNode(node) ? (PathMemory) memory : ((RiaNodeMemory) memory).getRiaPathMemory();
    childSmem.setPos(pmem.getSegmentMemories().length - 1);
    pmem.setSegmentMemory(childSmem.getPos(), childSmem);
    pmem.setSegmentMemory(childSmem);
    childSmem.addPathMemory(pmem);
    childSmem.setTipNode(node);
    return childSmem;
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory) PathMemory(org.drools.core.reteoo.PathMemory)

Example 8 with PathMemory

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

the class AddRemoveRule method flushStagedTuples.

private static void flushStagedTuples(TerminalNode tn, PathMemory pmem, PathEndNodes pathEndNodes, InternalWorkingMemory wm) {
    // first flush the subject rule, then flush any staging lists that are part of a merge
    if (pmem.isInitialized()) {
        new RuleNetworkEvaluator().evaluateNetwork(pmem, pmem.getRuleAgendaItem().getRuleExecutor(), wm);
    }
    // With the removing rules being flushed, we need to check any splits that will be merged, to see if they need flushing
    // Beware that flushing a higher up node, might again cause lower nodes to have more staged items. So track flushed items
    // incase they need to be reflushed
    List<Flushed> flushed = new ArrayList<Flushed>();
    for (LeftTupleNode node : pathEndNodes.subjectSplits) {
        if (!isSplit(node, tn)) {
            // check if the split is there even without the processed rule
            Memory mem = wm.getNodeMemories().peekNodeMemory(node);
            if (mem != null) {
                SegmentMemory smem = mem.getSegmentMemory();
                if (!smem.isEmpty()) {
                    for (SegmentMemory childSmem = smem.getFirst(); childSmem != null; childSmem = childSmem.getNext()) {
                        if (!childSmem.getStagedLeftTuples().isEmpty()) {
                            PathMemory childPmem = childSmem.getPathMemories().get(0);
                            flushed.add(new Flushed(childSmem, childPmem));
                            forceFlushLeftTuple(childPmem, childSmem, wm, childSmem.getStagedLeftTuples().takeAll());
                        }
                    }
                }
            }
        }
    }
    // need to ensure that there is one full iteration, without any flushing. To avoid one flush causing populat of another already flushed segment
    int flushCount = 1;
    while (!flushed.isEmpty() && flushCount != 0) {
        flushCount = 0;
        for (Flushed path : flushed) {
            if (!path.segmentMemory.getStagedLeftTuples().isEmpty()) {
                flushCount++;
                forceFlushLeftTuple(pmem, path.segmentMemory, wm, path.segmentMemory.getStagedLeftTuples().takeAll());
            }
        }
    }
}
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) ArrayList(java.util.ArrayList) LeftTupleNode(org.drools.core.reteoo.LeftTupleNode) PathMemory(org.drools.core.reteoo.PathMemory)

Example 9 with PathMemory

use of org.drools.core.reteoo.PathMemory 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 10 with PathMemory

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

the class AddRemoveRule method reInitPathMemories.

private static Map<PathMemory, SegmentMemory[]> reInitPathMemories(List<PathMemory> pathMems, TerminalNode removingTN) {
    Map<PathMemory, SegmentMemory[]> previousSmems = new HashMap<PathMemory, SegmentMemory[]>();
    for (PathMemory pmem : pathMems) {
        // Re initialise all the PathMemories
        previousSmems.put(pmem, pmem.getSegmentMemories());
        LeftTupleSource startRianLts = null;
        if (!NodeTypeEnums.isTerminalNode(pmem.getPathEndNode())) {
            RightInputAdapterNode rian = (RightInputAdapterNode) pmem.getPathEndNode();
            startRianLts = rian.getStartTupleSource();
        }
        PathEndNode pathEndNode = pmem.getPathEndNode();
        // re-initialise the PathMemory
        pathEndNode.resetPathMemSpec(removingTN);
        AbstractTerminalNode.initPathMemory(pathEndNode, pmem);
    }
    return previousSmems;
}
Also used : LeftTupleSource(org.drools.core.reteoo.LeftTupleSource) SegmentMemory(org.drools.core.reteoo.SegmentMemory) HashMap(java.util.HashMap) PathEndNode(org.drools.core.reteoo.PathEndNode) RightInputAdapterNode(org.drools.core.reteoo.RightInputAdapterNode) PathMemory(org.drools.core.reteoo.PathMemory)

Aggregations

PathMemory (org.drools.core.reteoo.PathMemory)34 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)26 SegmentMemory (org.drools.core.reteoo.SegmentMemory)26 RuleTerminalNode (org.drools.core.reteoo.RuleTerminalNode)16 Test (org.junit.Test)16 InternalKnowledgeBase (org.drools.core.impl.InternalKnowledgeBase)14 BetaMemory (org.drools.core.reteoo.BetaMemory)13 LeftInputAdapterNode (org.drools.core.reteoo.LeftInputAdapterNode)13 JoinNode (org.drools.core.reteoo.JoinNode)12 ObjectTypeNode (org.drools.core.reteoo.ObjectTypeNode)11 LeftTupleNode (org.drools.core.reteoo.LeftTupleNode)9 Memory (org.drools.core.common.Memory)8 AccumulateMemory (org.drools.core.reteoo.AccumulateNode.AccumulateMemory)8 KnowledgeBuilder (org.kie.internal.builder.KnowledgeBuilder)8 ArrayList (java.util.ArrayList)7 FromMemory (org.drools.core.reteoo.FromNode.FromMemory)7 RightInputAdapterNode (org.drools.core.reteoo.RightInputAdapterNode)7 RiaNodeMemory (org.drools.core.reteoo.RightInputAdapterNode.RiaNodeMemory)7 TupleMemory (org.drools.core.reteoo.TupleMemory)7 List (java.util.List)6