Search in sources :

Example 16 with LeftTupleNode

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

the class AddRemoveRule method insertFacts.

private static void insertFacts(PathEndNodes endNodes, Collection<InternalWorkingMemory> wms) {
    Set<LeftTupleNode> visited = new HashSet<>();
    for (PathEndNode endNode : endNodes.subjectEndNodes) {
        LeftTupleNode[] nodes = endNode.getPathNodes();
        for (int i = 0; i < nodes.length; i++) {
            LeftTupleNode node = nodes[i];
            if (NodeTypeEnums.isBetaNode(node) && node.getAssociationsSize() == 1) {
                if (!visited.add(node)) {
                    // this is to avoid rentering a path, and processing nodes twice. This can happen for nested subnetworks.
                    continue;
                }
                BetaNode bn = (BetaNode) node;
                if (!bn.isRightInputIsRiaNode()) {
                    for (InternalWorkingMemory wm : wms) {
                        PropagationContextFactory pctxFactory = RuntimeComponentFactory.get().getPropagationContextFactory();
                        final PropagationContext pctx = pctxFactory.createPropagationContext(wm.getNextPropagationIdCounter(), PropagationContext.Type.RULE_ADDITION, null, null, null);
                        bn.getRightInput().updateSink(bn, pctx, wm);
                    }
                }
            }
        }
    }
}
Also used : InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) PropagationContextFactory(org.drools.core.common.PropagationContextFactory) BetaNode(org.drools.core.reteoo.BetaNode) PropagationContext(org.drools.core.spi.PropagationContext) LeftTupleNode(org.drools.core.reteoo.LeftTupleNode) PathEndNode(org.drools.core.reteoo.PathEndNode) HashSet(java.util.HashSet)

Example 17 with LeftTupleNode

use of org.drools.core.reteoo.LeftTupleNode 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<>();
    Set<SegmentMemory> visitedSegments = new HashSet<>();
    Set<LeftTupleNode> visitedNodes = new HashSet<>();
    Map<LeftTupleNode, SegmentMemory> nodeToSegmentMap = new HashMap<>();
    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++];
            LeftTupleSource 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(parentNode, wm, nodeTypesInSegment);
                nodeTypesInSegment = 0;
            }
        } while (!NodeTypeEnums.isEndNode(node));
        strategy.processSegmentMemories(smems, pmem);
    }
    return smemsToNotify;
}
Also used : LeftTupleSource(org.drools.core.reteoo.LeftTupleSource) 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 18 with LeftTupleNode

use of org.drools.core.reteoo.LeftTupleNode 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<>();
    for (PathMemory pmem : pmems) {
        LeftTupleSink tipNode = 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 19 with LeftTupleNode

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

the class AddRemoveRule method forceFlushLeftTuple.

public static void forceFlushLeftTuple(PathMemory pmem, SegmentMemory sm, ReteEvaluator reteEvaluator, 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 : reteEvaluator.getNodeMemory((AbstractTerminalNode) pmem.getPathEndNode().getPathEndNodes()[0]);
    ActivationsManager activationsManager = pmem.getActualActivationsManager(reteEvaluator);
    RuleNetworkEvaluator.INSTANCE.outerEval(pmem, node, bit, mem, smems, sm.getPos(), leftTupleSets, activationsManager, new LinkedList<>(), true, rtnPmem.getOrCreateRuleAgendaItem(activationsManager).getRuleExecutor());
}
Also used : AbstractTerminalNode(org.drools.core.reteoo.AbstractTerminalNode) 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) ActivationsManager(org.drools.core.common.ActivationsManager) LeftTupleNode(org.drools.core.reteoo.LeftTupleNode) PathMemory(org.drools.core.reteoo.PathMemory)

Example 20 with LeftTupleNode

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

Aggregations

LeftTupleNode (org.drools.core.reteoo.LeftTupleNode)20 SegmentMemory (org.drools.core.reteoo.SegmentMemory)14 PathMemory (org.drools.core.reteoo.PathMemory)13 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)11 Memory (org.drools.core.common.Memory)6 AccumulateMemory (org.drools.core.reteoo.AccumulateNode.AccumulateMemory)6 BetaMemory (org.drools.core.reteoo.BetaMemory)6 FromMemory (org.drools.core.reteoo.FromNode.FromMemory)6 ObjectTypeNodeMemory (org.drools.core.reteoo.ObjectTypeNode.ObjectTypeNodeMemory)6 RiaNodeMemory (org.drools.core.reteoo.RightInputAdapterNode.RiaNodeMemory)6 SegmentNodeMemory (org.drools.core.reteoo.SegmentNodeMemory)6 TupleMemory (org.drools.core.reteoo.TupleMemory)6 HashSet (java.util.HashSet)5 PathEndNode (org.drools.core.reteoo.PathEndNode)5 RuleImpl (org.drools.core.definitions.rule.impl.RuleImpl)4 BetaNode (org.drools.core.reteoo.BetaNode)4 LeftTupleSink (org.drools.core.reteoo.LeftTupleSink)4 LeftInputAdapterNode (org.drools.core.reteoo.LeftInputAdapterNode)3 ClassObjectType (org.drools.core.base.ClassObjectType)2 PropagationContextFactory (org.drools.core.common.PropagationContextFactory)2