Search in sources :

Example 51 with SegmentMemory

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

the class AddRemoveRule method splitSegment.

public static SegmentMemory splitSegment(InternalWorkingMemory wm, SegmentMemory sm1, LeftTupleNode splitNode) {
    // create new segment, starting after split
    LeftTupleNode childNode = splitNode.getSinkPropagator().getFirstLeftTupleSink();
    // we know there is only one sink
    SegmentMemory sm2 = new SegmentMemory(childNode);
    wm.getNodeMemories().peekNodeMemory(childNode).setSegmentMemory(sm2);
    // Move the children of sm1 to sm2
    if (sm1.getFirst() != null) {
        for (SegmentMemory sm = sm1.getFirst(); sm != null; ) {
            SegmentMemory next = sm.getNext();
            sm1.remove(sm);
            sm2.add(sm);
            sm = next;
        }
    }
    sm1.add(sm2);
    // clone for now, it's corrected later
    sm2.setPos(sm1.getPos());
    // clone for now, it's corrected later
    sm2.setSegmentPosMaskBit(sm1.getSegmentPosMaskBit());
    // clone for now, it's corrected later
    sm2.setLinkedNodeMask(sm1.getLinkedNodeMask());
    sm2.mergePathMemories(sm1);
    // re-assigned tip nodes
    sm2.setTipNode(sm1.getTipNode());
    // splitNode is now tip of original segment
    sm1.setTipNode(splitNode);
    if (sm1.getTipNode().getType() == NodeTypeEnums.LeftInputAdapterNode) {
        if (!sm1.getStagedLeftTuples().isEmpty()) {
            // Segments with only LiaNode's cannot have staged LeftTuples, so move them down to the new Segment
            sm2.getStagedLeftTuples().addAll(sm1.getStagedLeftTuples());
        }
    }
    // find the pos of the node in the segment
    int pos = nodeSegmentPosition(sm1, splitNode);
    splitNodeMemories(sm1, sm2, pos);
    splitBitMasks(sm1, sm2, pos);
    correctSegmentMemoryAfterSplitOnAdd(sm2);
    return sm2;
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory) LeftTupleNode(org.drools.core.reteoo.LeftTupleNode)

Example 52 with SegmentMemory

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

the class AddRemoveRule method handleExistingPaths.

private static Set<SegmentMemory> handleExistingPaths(TerminalNode tn, Map<PathMemory, SegmentMemory[]> prevSmemsLookup, List<PathMemory> pmems, InternalWorkingMemory wm, ExistingPathStrategy strategy) {
    Set<SegmentMemory> smemsToNotify = new HashSet<SegmentMemory>();
    Set<SegmentMemory> visitedSegments = new HashSet<SegmentMemory>();
    Set<LeftTupleNode> visitedNodes = new HashSet<LeftTupleNode>();
    Map<LeftTupleNode, SegmentMemory> nodeToSegmentMap = new HashMap<LeftTupleNode, SegmentMemory>();
    for (PathMemory pmem : pmems) {
        LeftTupleNode[] nodes = pmem.getPathEndNode().getPathNodes();
        SegmentMemory[] prevSmems = prevSmemsLookup.get(pmem);
        SegmentMemory[] smems = strategy.getSegmenMemories(pmem);
        LeftTupleNode node;
        int prevSmemIndex = 0;
        int smemIndex = 0;
        int smemSplitAdjustAmount = 0;
        int nodeIndex = 0;
        int nodeTypesInSegment = 0;
        // excluding the rule just added iterate while not split (i.e. find the next split, prior to this rule being added)
        // note it's checking for when the parent is the split, and thus node is the next root root.
        smems[smemIndex] = prevSmems[prevSmemIndex];
        do {
            node = nodes[nodeIndex++];
            LeftTupleNode parentNode = node.getLeftTupleSource();
            nodeTypesInSegment = SegmentUtilities.updateNodeTypesMask(parentNode, nodeTypesInSegment);
            if (isSplit(parentNode)) {
                smemIndex = strategy.incSmemIndex1(smemIndex);
                prevSmemIndex = strategy.incPrevSmemIndex1(prevSmemIndex);
                if (isSplit(parentNode, tn)) {
                    // check if the split is there even without the processed rule
                    smemIndex = strategy.incSmemIndex2(smemIndex);
                    prevSmemIndex = strategy.incPrevSmemIndex2(prevSmemIndex);
                    smems[smemIndex] = prevSmems[prevSmemIndex];
                    if (smems[smemIndex] != null && smemSplitAdjustAmount > 0 && visitedSegments.add(smems[smemIndex])) {
                        strategy.adjustSegment(wm, smemsToNotify, smems[smemIndex], smemSplitAdjustAmount);
                    }
                } else {
                    strategy.handleSplit(pmem, prevSmems, smems, smemIndex, prevSmemIndex, parentNode, node, tn, visitedNodes, smemsToNotify, nodeToSegmentMap, wm);
                    smemSplitAdjustAmount++;
                }
                SegmentUtilities.checkEagerSegmentCreation((LeftTupleSource) parentNode, wm, nodeTypesInSegment);
                nodeTypesInSegment = 0;
            }
        } while (!NodeTypeEnums.isEndNode(node));
        strategy.processSegmentMemories(smems, pmem);
    }
    return smemsToNotify;
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory) HashMap(java.util.HashMap) LeftTupleNode(org.drools.core.reteoo.LeftTupleNode) HashSet(java.util.HashSet) PathMemory(org.drools.core.reteoo.PathMemory)

Example 53 with SegmentMemory

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

the class AddRemoveRule method flushStagedTuples.

private static void flushStagedTuples(LeftTupleNode splitStartNode, PathMemory pmem, InternalWorkingMemory wm) {
    if (!pmem.isInitialized()) {
        // The rule has never been linked in and evaluated, so there will be nothing to flush.
        return;
    }
    // index before the segments are merged
    int smemIndex = getSegmentPos(splitStartNode);
    SegmentMemory[] smems = pmem.getSegmentMemories();
    SegmentMemory sm = null;
    // If there is no sharing, then there will not be any staged tuples in later segemnts, and thus no need to search for them if the current sm is empty.
    int length = smems.length;
    if (splitStartNode.getAssociationsSize() == 1) {
        length = 1;
    }
    while (smemIndex < length) {
        sm = smems[smemIndex];
        if (sm != null && !sm.getStagedLeftTuples().isEmpty()) {
            break;
        }
        smemIndex++;
    }
    if (smemIndex < length) {
        // it only found a SM that needed flushing, if smemIndex < length
        forceFlushLeftTuple(pmem, sm, wm, sm.getStagedLeftTuples().takeAll());
    }
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory)

Example 54 with SegmentMemory

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

the class AddRemoveRule method forceFlushLeftTuple.

public static void forceFlushLeftTuple(PathMemory pmem, SegmentMemory sm, InternalWorkingMemory wm, TupleSets<LeftTuple> leftTupleSets) {
    SegmentMemory[] smems = pmem.getSegmentMemories();
    LeftTupleNode node;
    Memory mem;
    long bit = 1;
    if (sm.getRootNode().getType() == NodeTypeEnums.LeftInputAdapterNode && sm.getTipNode().getType() != NodeTypeEnums.LeftInputAdapterNode) {
        // The segment is the first and it has the lian shared with other nodes, the lian must be skipped, so adjust the bit and sink
        node = sm.getRootNode().getSinkPropagator().getFirstLeftTupleSink();
        mem = sm.getNodeMemories().get(1);
        // adjust bit to point to next node
        bit = 2;
    } else {
        node = sm.getRootNode();
        mem = sm.getNodeMemories().get(0);
    }
    PathMemory rtnPmem = NodeTypeEnums.isTerminalNode(pmem.getPathEndNode()) ? pmem : wm.getNodeMemory((AbstractTerminalNode) pmem.getPathEndNode().getPathEndNodes()[0]);
    InternalAgenda agenda = pmem.getActualAgenda(wm);
    new RuleNetworkEvaluator().outerEval(pmem, node, bit, mem, smems, sm.getPos(), leftTupleSets, agenda, new LinkedList<StackEntry>(), true, rtnPmem.getOrCreateRuleAgendaItem(agenda).getRuleExecutor());
}
Also used : AbstractTerminalNode(org.drools.core.reteoo.AbstractTerminalNode) InternalAgenda(org.drools.core.common.InternalAgenda) 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) LeftTupleNode(org.drools.core.reteoo.LeftTupleNode) PathMemory(org.drools.core.reteoo.PathMemory)

Example 55 with SegmentMemory

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

the class AddRemoveRule method mergeNodeMemories.

private static void mergeNodeMemories(SegmentMemory sm1, SegmentMemory sm2) {
    LinkedList<Memory> smNodeMemories1 = sm1.getNodeMemories();
    LinkedList<Memory> smNodeMemories2 = sm2.getNodeMemories();
    int nodePosMask = 1;
    for (int i = 0, length = smNodeMemories1.size(); i < length; i++) {
        nodePosMask = nodePosMask >> 1;
    }
    for (Memory mem = smNodeMemories2.getFirst(); mem != null; ) {
        Memory next = mem.getNext();
        smNodeMemories2.remove(mem);
        smNodeMemories1.add(mem);
        mem.setSegmentMemory(sm1);
        // 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)

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