Search in sources :

Example 11 with SegmentMemory

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

the class SegmentUtilities method createSegmentMemory.

public static SegmentMemory createSegmentMemory(LeftTupleSource tupleSource, Memory mem, InternalWorkingMemory wm) {
    // find segment root
    while (!SegmentUtilities.isRootNode(tupleSource, null)) {
        tupleSource = tupleSource.getLeftTupleSource();
    }
    LeftTupleSource segmentRoot = tupleSource;
    int nodeTypesInSegment = 0;
    SegmentMemory smem = restoreSegmentFromPrototype(wm, segmentRoot, nodeTypesInSegment);
    if (smem != null) {
        if (NodeTypeEnums.isBetaNode(segmentRoot) && ((BetaNode) segmentRoot).isRightInputIsRiaNode()) {
            createRiaSegmentMemory((BetaNode) segmentRoot, wm);
        }
        return smem;
    }
    smem = new SegmentMemory(segmentRoot);
    // Iterate all nodes on the same segment, assigning their position as a bit mask value
    // allLinkedTestMask is the resulting mask used to test if all nodes are linked in
    long nodePosMask = 1;
    long allLinkedTestMask = 0;
    // nodes after a branch CE can notify, but they cannot impact linking
    boolean updateNodeBit = true;
    while (true) {
        nodeTypesInSegment = updateNodeTypesMask(tupleSource, nodeTypesInSegment);
        if (NodeTypeEnums.isBetaNode(tupleSource)) {
            allLinkedTestMask = processBetaNode((BetaNode) tupleSource, wm, smem, nodePosMask, allLinkedTestMask, updateNodeBit);
        } else {
            switch(tupleSource.getType()) {
                case NodeTypeEnums.LeftInputAdapterNode:
                    allLinkedTestMask = processLiaNode((LeftInputAdapterNode) tupleSource, wm, smem, nodePosMask, allLinkedTestMask);
                    break;
                case NodeTypeEnums.EvalConditionNode:
                    processEvalNode((EvalConditionNode) tupleSource, wm, smem);
                    break;
                case NodeTypeEnums.ConditionalBranchNode:
                    updateNodeBit = processBranchNode((ConditionalBranchNode) tupleSource, wm, smem);
                    break;
                case NodeTypeEnums.FromNode:
                    processFromNode((FromNode) tupleSource, wm, smem);
                    break;
                case NodeTypeEnums.ReactiveFromNode:
                    processReactiveFromNode((MemoryFactory) tupleSource, wm, smem, nodePosMask);
                    break;
                case NodeTypeEnums.TimerConditionNode:
                    processTimerNode((TimerNode) tupleSource, wm, smem, nodePosMask);
                    break;
                case NodeTypeEnums.QueryElementNode:
                    updateNodeBit = processQueryNode((QueryElementNode) tupleSource, wm, segmentRoot, smem, nodePosMask);
                    break;
            }
        }
        nodePosMask = nodePosMask << 1;
        if (tupleSource.getSinkPropagator().size() == 1) {
            LeftTupleSinkNode sink = tupleSource.getSinkPropagator().getFirstLeftTupleSink();
            if (NodeTypeEnums.isLeftTupleSource(sink)) {
                tupleSource = (LeftTupleSource) sink;
            } else {
                // rtn or rian
                // While not technically in a segment, we want to be able to iterate easily from the last node memory to the ria/rtn memory
                // we don't use createNodeMemory, as these may already have been created by, but not added, by the method updateRiaAndTerminalMemory
                Memory memory = wm.getNodeMemory((MemoryFactory) sink);
                if (sink.getType() == NodeTypeEnums.RightInputAdaterNode) {
                    PathMemory riaPmem = ((RiaNodeMemory) memory).getRiaPathMemory();
                    smem.getNodeMemories().add(riaPmem);
                    RightInputAdapterNode rian = (RightInputAdapterNode) sink;
                    ObjectSink[] nodes = rian.getObjectSinkPropagator().getSinks();
                    for (ObjectSink node : nodes) {
                        if (NodeTypeEnums.isLeftTupleSource(node)) {
                            createSegmentMemory((LeftTupleSource) node, wm);
                        }
                    }
                } else if (NodeTypeEnums.isTerminalNode(sink)) {
                    smem.getNodeMemories().add(memory);
                }
                memory.setSegmentMemory(smem);
                smem.setTipNode(sink);
                break;
            }
        } else {
            // not in same segment
            smem.setTipNode(tupleSource);
            break;
        }
    }
    smem.setAllLinkedMaskTest(allLinkedTestMask);
    // iterate to find root and determine the SegmentNodes position in the RuleSegment
    LeftTupleSource pathRoot = segmentRoot;
    int ruleSegmentPosMask = 1;
    int counter = 0;
    while (pathRoot.getType() != NodeTypeEnums.LeftInputAdapterNode) {
        LeftTupleSource leftTupleSource = pathRoot.getLeftTupleSource();
        if (SegmentUtilities.isNonTerminalTipNode(leftTupleSource, null)) {
            // for each new found segment, increase the mask bit position
            ruleSegmentPosMask = ruleSegmentPosMask << 1;
            counter++;
        }
        pathRoot = leftTupleSource;
    }
    smem.setSegmentPosMaskBit(ruleSegmentPosMask);
    smem.setPos(counter);
    nodeTypesInSegment = updateRiaAndTerminalMemory(tupleSource, tupleSource, smem, wm, false, nodeTypesInSegment);
    ((KnowledgeBaseImpl) wm.getKnowledgeBase()).registerSegmentPrototype(segmentRoot, smem);
    return smem;
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory) BetaNode(org.drools.core.reteoo.BetaNode) Memory(org.drools.core.common.Memory) TimerNodeMemory(org.drools.core.reteoo.TimerNode.TimerNodeMemory) LiaNodeMemory(org.drools.core.reteoo.LeftInputAdapterNode.LiaNodeMemory) BetaMemory(org.drools.core.reteoo.BetaMemory) EvalMemory(org.drools.core.reteoo.EvalConditionNode.EvalMemory) QueryElementNodeMemory(org.drools.core.reteoo.QueryElementNode.QueryElementNodeMemory) SegmentMemory(org.drools.core.reteoo.SegmentMemory) PathMemory(org.drools.core.reteoo.PathMemory) InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) ConditionalBranchMemory(org.drools.core.reteoo.ConditionalBranchNode.ConditionalBranchMemory) RiaNodeMemory(org.drools.core.reteoo.RightInputAdapterNode.RiaNodeMemory) AccumulateMemory(org.drools.core.reteoo.AccumulateNode.AccumulateMemory) QueryElementNode(org.drools.core.reteoo.QueryElementNode) ConditionalBranchNode(org.drools.core.reteoo.ConditionalBranchNode) KnowledgeBaseImpl(org.drools.core.impl.KnowledgeBaseImpl) QueryNameConstraint(org.drools.core.rule.constraint.QueryNameConstraint) LeftTupleSource(org.drools.core.reteoo.LeftTupleSource) RiaNodeMemory(org.drools.core.reteoo.RightInputAdapterNode.RiaNodeMemory) LeftTupleSinkNode(org.drools.core.reteoo.LeftTupleSinkNode) ObjectSink(org.drools.core.reteoo.ObjectSink) RightInputAdapterNode(org.drools.core.reteoo.RightInputAdapterNode) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode) PathMemory(org.drools.core.reteoo.PathMemory)

Example 12 with SegmentMemory

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

the class SegmentUtilities method createChildSegments.

public static void createChildSegments(final InternalWorkingMemory wm, SegmentMemory smem, LeftTupleSinkPropagator sinkProp) {
    if (!smem.isEmpty()) {
        // this can happen when multiple threads are trying to initialize the segment
        return;
    }
    for (LeftTupleSinkNode sink = sinkProp.getFirstLeftTupleSink(); sink != null; sink = sink.getNextLeftTupleSinkNode()) {
        SegmentMemory childSmem = createChildSegment(wm, sink);
        childSmem.setPos(smem.getPos() + 1);
        smem.add(childSmem);
    }
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory) LeftTupleSinkNode(org.drools.core.reteoo.LeftTupleSinkNode)

Example 13 with SegmentMemory

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

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

the class AddRemoveRule method splitNodeMemories.

private static void splitNodeMemories(SegmentMemory sm1, SegmentMemory sm2, int pos) {
    LinkedList<Memory> smNodeMemories1 = sm1.getNodeMemories();
    LinkedList<Memory> smNodeMemories2 = sm2.getNodeMemories();
    Memory mem = smNodeMemories1.getFirst();
    int nodePosMask = 1;
    for (int i = 0, length = smNodeMemories1.size(); i < length; i++) {
        Memory next = mem.getNext();
        if (i > pos) {
            smNodeMemories1.remove(mem);
            smNodeMemories2.add(mem);
            mem.setSegmentMemory(sm2);
            // correct the NodePosMaskBit
            if (mem instanceof SegmentNodeMemory) {
                ((SegmentNodeMemory) mem).setNodePosMaskBit(nodePosMask);
            }
            nodePosMask = nodePosMask << 1;
        }
        mem = next;
    }
}
Also used : 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) SegmentNodeMemory(org.drools.core.reteoo.SegmentNodeMemory)

Example 15 with SegmentMemory

use of org.drools.core.reteoo.SegmentMemory 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)

Aggregations

SegmentMemory (org.drools.core.reteoo.SegmentMemory)67 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)43 PathMemory (org.drools.core.reteoo.PathMemory)30 Test (org.junit.Test)30 LeftInputAdapterNode (org.drools.core.reteoo.LeftInputAdapterNode)27 BetaMemory (org.drools.core.reteoo.BetaMemory)23 ObjectTypeNode (org.drools.core.reteoo.ObjectTypeNode)23 LiaNodeMemory (org.drools.core.reteoo.LeftInputAdapterNode.LiaNodeMemory)22 InternalKnowledgeBase (org.drools.core.impl.InternalKnowledgeBase)18 JoinNode (org.drools.core.reteoo.JoinNode)18 RuleTerminalNode (org.drools.core.reteoo.RuleTerminalNode)18 ArrayList (java.util.ArrayList)16 List (java.util.List)15 Memory (org.drools.core.common.Memory)14 AccumulateMemory (org.drools.core.reteoo.AccumulateNode.AccumulateMemory)12 LeftTuple (org.drools.core.reteoo.LeftTuple)12 Match (org.kie.api.runtime.rule.Match)11 RiaNodeMemory (org.drools.core.reteoo.RightInputAdapterNode.RiaNodeMemory)10 KieBase (org.kie.api.KieBase)10 Arrays.asList (java.util.Arrays.asList)9