Search in sources :

Example 1 with InternalWorkingMemory

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

the class PhreakRuleTerminalNode method doLeftTupleUpdate.

public static void doLeftTupleUpdate(TerminalNode rtnNode, RuleExecutor executor, InternalAgenda agenda, int salienceInt, Salience salience, LeftTuple leftTuple) {
    PropagationContext pctx = leftTuple.getPropagationContext();
    pctx = RuleTerminalNode.findMostRecentPropagationContext(leftTuple, pctx);
    boolean blocked = false;
    RuleTerminalNodeLeftTuple rtnLeftTuple = (RuleTerminalNodeLeftTuple) leftTuple;
    if (executor.isDeclarativeAgendaEnabled()) {
        if (rtnLeftTuple.getBlockers() != null && !rtnLeftTuple.getBlockers().isEmpty()) {
            // declarativeAgenda still blocking LeftTuple, so don't add back ot list
            blocked = true;
        }
    } else {
        blocked = rtnNode.getRule().isNoLoop() && rtnNode.equals(pctx.getTerminalNodeOrigin());
    }
    InternalWorkingMemory wm = agenda.getWorkingMemory();
    if (salience != null) {
        salienceInt = salience.getValue(new DefaultKnowledgeHelper(rtnLeftTuple, wm), rtnNode.getRule(), wm);
    }
    if (agenda.getActivationsFilter() != null && !agenda.getActivationsFilter().accept(rtnLeftTuple, wm, rtnNode)) {
        // only relevant for serialization, to not re-fire Matches already fired
        return;
    }
    if (!blocked) {
        boolean addToExector = true;
        if (rtnNode.getRule().isLockOnActive() && pctx.getType() != PropagationContext.Type.RULE_ADDITION) {
            long handleRecency = pctx.getFactHandle().getRecency();
            InternalAgendaGroup agendaGroup = executor.getRuleAgendaItem().getAgendaGroup();
            if (blockedByLockOnActive(rtnNode.getRule(), pctx, handleRecency, agendaGroup)) {
                addToExector = false;
            }
        }
        if (addToExector) {
            if (!rtnLeftTuple.isQueued()) {
                // not queued, so already fired, so it's effectively recreated
                EventSupport es = (EventSupport) wm;
                es.getAgendaEventSupport().fireActivationCreated(rtnLeftTuple, wm);
                rtnLeftTuple.update(salienceInt, pctx);
                executor.addLeftTuple(leftTuple);
                wm.getRuleEventSupport().onUpdateMatch(rtnLeftTuple);
            }
        }
    } else {
        // LeftTuple is blocked, and thus not queued, so just update it's values
        rtnLeftTuple.update(salienceInt, pctx);
    }
    if (!rtnNode.isFireDirect() && executor.isDeclarativeAgendaEnabled()) {
        agenda.modifyActivation(rtnLeftTuple, rtnLeftTuple.isQueued());
    }
}
Also used : InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) InternalAgendaGroup(org.drools.core.common.InternalAgendaGroup) PropagationContext(org.drools.core.spi.PropagationContext) EventSupport(org.drools.core.common.EventSupport) RuleTerminalNodeLeftTuple(org.drools.core.reteoo.RuleTerminalNodeLeftTuple) DefaultKnowledgeHelper(org.drools.core.base.DefaultKnowledgeHelper)

Example 2 with InternalWorkingMemory

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

the class PhreakTimerNode method scheduleLeftTuple.

private void scheduleLeftTuple(final TimerNode timerNode, final TimerNodeMemory tm, final PathMemory pmem, final SegmentMemory smem, final LeftTupleSink sink, final InternalAgenda agenda, final Timer timer, final TimerService timerService, final long timestamp, final String[] calendarNames, final Calendars calendars, final LeftTuple leftTuple, final TupleSets<LeftTuple> trgLeftTuples, final TupleSets<LeftTuple> stagedLeftTuples) {
    InternalWorkingMemory wm = agenda.getWorkingMemory();
    if (leftTuple.getPropagationContext().getReaderContext() == null) {
        final Trigger trigger = createTrigger(timerNode, wm, timer, timestamp, calendarNames, calendars, leftTuple);
        // regular propagation
        scheduleTimer(timerNode, tm, smem, sink, wm, timerService, timestamp, leftTuple, trgLeftTuples, stagedLeftTuples, trigger);
    } else {
        // de-serializing, so we need to correlate timers before scheduling them
        Scheduler scheduler = new Scheduler() {

            @Override
            public void schedule(Trigger t) {
                scheduleTimer(timerNode, tm, smem, sink, wm, timerService, timestamp, leftTuple, trgLeftTuples, stagedLeftTuples, t);
                evaluate(pmem, agenda, sink, tm, trgLeftTuples);
            }

            @Override
            public Trigger getTrigger() {
                return createTrigger(timerNode, wm, timer, timestamp, calendarNames, calendars, leftTuple);
            }
        };
        TupleKey key = PersisterHelper.createTupleKey(leftTuple);
        leftTuple.getPropagationContext().getReaderContext().addTimerNodeScheduler(timerNode.getId(), key, scheduler);
        leftTuple.setContextObject(key);
    }
}
Also used : InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) Trigger(org.drools.core.time.Trigger) TupleKey(org.drools.core.marshalling.impl.ProtobufInputMarshaller.TupleKey)

Example 3 with InternalWorkingMemory

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

the class RuleNetworkEvaluator method doRiaNode2.

private void doRiaNode2(InternalWorkingMemory wm, TupleSets<LeftTuple> srcTuples, RightInputAdapterNode riaNode) {
    ObjectSink[] sinks = riaNode.getObjectSinkPropagator().getSinks();
    BetaNode betaNode = (BetaNode) sinks[0];
    BetaMemory bm;
    Memory nodeMem = wm.getNodeMemory(betaNode);
    if (NodeTypeEnums.AccumulateNode == betaNode.getType()) {
        bm = ((AccumulateMemory) nodeMem).getBetaMemory();
    } else {
        bm = (BetaMemory) nodeMem;
    }
    TupleSets<RightTuple> rightTuples = bm.getStagedRightTuples();
    // Build up iteration array for other sinks
    BetaNode[] bns = null;
    BetaMemory[] bms = null;
    int length = sinks.length;
    if (length > 1) {
        bns = new BetaNode[sinks.length - 1];
        bms = new BetaMemory[sinks.length - 1];
        for (int i = 1; i < length; i++) {
            bns[i - 1] = (BetaNode) sinks[i];
            Memory nodeMem2 = wm.getNodeMemory(bns[i - 1]);
            if (NodeTypeEnums.AccumulateNode == betaNode.getType()) {
                bms[i - 1] = ((AccumulateMemory) nodeMem2).getBetaMemory();
            } else {
                bms[i - 1] = (BetaMemory) nodeMem2;
            }
        }
    }
    // subtract one, as first is not in the array;
    length--;
    for (SubnetworkTuple subnetworkTuple = (SubnetworkTuple) srcTuples.getInsertFirst(); subnetworkTuple != null; ) {
        SubnetworkTuple next = (SubnetworkTuple) subnetworkTuple.getStagedNext();
        if (bm.getStagedRightTuples().isEmpty()) {
            bm.setNodeDirtyWithoutNotify();
        }
        subnetworkTuple.prepareStagingOnRight();
        rightTuples.addInsert(subnetworkTuple);
        if (bns != null) {
            for (int i = 0; i < length; i++) {
                if (bms[i].getStagedRightTuples().isEmpty()) {
                    bms[i].setNodeDirtyWithoutNotify();
                }
                subnetworkTuple = riaNode.createPeer(subnetworkTuple);
                bms[i].getStagedRightTuples().addInsert(subnetworkTuple);
            }
        }
        subnetworkTuple = next;
    }
    for (SubnetworkTuple subnetworkTuple = (SubnetworkTuple) srcTuples.getDeleteFirst(); subnetworkTuple != null; ) {
        SubnetworkTuple next = (SubnetworkTuple) subnetworkTuple.getStagedNext();
        if (rightTuples.isEmpty()) {
            bm.setNodeDirtyWithoutNotify();
        }
        switch(subnetworkTuple.getStagedTypeOnRight()) {
            // handle clash with already staged entries
            case Tuple.INSERT:
                rightTuples.removeInsert(subnetworkTuple);
                break;
            case Tuple.UPDATE:
                rightTuples.removeUpdate(subnetworkTuple);
                break;
        }
        subnetworkTuple.prepareStagingOnRight();
        rightTuples.addDelete(subnetworkTuple);
        if (bns != null) {
            for (int i = 0; i < length; i++) {
                subnetworkTuple = (SubnetworkTuple) subnetworkTuple.getPeer();
                if (bms[i].getStagedRightTuples().isEmpty()) {
                    bms[i].setNodeDirtyWithoutNotify();
                }
                bms[i].getStagedRightTuples().addDelete(subnetworkTuple);
                subnetworkTuple.setStagedOnRight();
            }
        }
        subnetworkTuple = next;
    }
    for (SubnetworkTuple subnetworkTuple = (SubnetworkTuple) srcTuples.getUpdateFirst(); subnetworkTuple != null; ) {
        SubnetworkTuple next = (SubnetworkTuple) subnetworkTuple.getStagedNext();
        if (rightTuples.isEmpty()) {
            bm.setNodeDirtyWithoutNotify();
        }
        subnetworkTuple.prepareStagingOnRight();
        rightTuples.addUpdate(subnetworkTuple);
        if (bns != null) {
            for (int i = 0; i < length; i++) {
                subnetworkTuple = (SubnetworkTuple) subnetworkTuple.getPeer();
                if (bms[i].getStagedRightTuples().isEmpty()) {
                    bms[i].setNodeDirtyWithoutNotify();
                }
                bms[i].getStagedRightTuples().addUpdate(subnetworkTuple);
                subnetworkTuple.setStagedOnRight();
            }
        }
        subnetworkTuple = next;
    }
    srcTuples.resetAll();
}
Also used : BetaNode(org.drools.core.reteoo.BetaNode) Memory(org.drools.core.common.Memory) QueryElementNodeMemory(org.drools.core.reteoo.QueryElementNode.QueryElementNodeMemory) PathMemory(org.drools.core.reteoo.PathMemory) InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) ConditionalBranchMemory(org.drools.core.reteoo.ConditionalBranchNode.ConditionalBranchMemory) AccumulateMemory(org.drools.core.reteoo.AccumulateNode.AccumulateMemory) TupleMemory(org.drools.core.reteoo.TupleMemory) TimerNodeMemory(org.drools.core.reteoo.TimerNode.TimerNodeMemory) BetaMemory(org.drools.core.reteoo.BetaMemory) EvalMemory(org.drools.core.reteoo.EvalConditionNode.EvalMemory) SegmentMemory(org.drools.core.reteoo.SegmentMemory) FromMemory(org.drools.core.reteoo.FromNode.FromMemory) RiaPathMemory(org.drools.core.reteoo.RiaPathMemory) ObjectSink(org.drools.core.reteoo.ObjectSink) BetaMemory(org.drools.core.reteoo.BetaMemory) RightTuple(org.drools.core.reteoo.RightTuple) SubnetworkTuple(org.drools.core.reteoo.SubnetworkTuple)

Example 4 with InternalWorkingMemory

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

the class SegmentUtilities method createRiaSegmentMemory.

private static RightInputAdapterNode createRiaSegmentMemory(BetaNode betaNode, InternalWorkingMemory wm) {
    RightInputAdapterNode riaNode = (RightInputAdapterNode) betaNode.getRightInput();
    LeftTupleSource subnetworkLts = riaNode.getLeftTupleSource();
    while (subnetworkLts.getLeftTupleSource() != riaNode.getStartTupleSource()) {
        subnetworkLts = subnetworkLts.getLeftTupleSource();
    }
    Memory rootSubNetwokrMem = wm.getNodeMemory((MemoryFactory) subnetworkLts);
    SegmentMemory subNetworkSegmentMemory = rootSubNetwokrMem.getSegmentMemory();
    if (subNetworkSegmentMemory == null) {
        // we need to stop recursion here
        createSegmentMemory(subnetworkLts, rootSubNetwokrMem, wm);
    }
    return riaNode;
}
Also used : LeftTupleSource(org.drools.core.reteoo.LeftTupleSource) SegmentMemory(org.drools.core.reteoo.SegmentMemory) 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) RightInputAdapterNode(org.drools.core.reteoo.RightInputAdapterNode)

Example 5 with InternalWorkingMemory

use of org.drools.core.common.InternalWorkingMemory 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)

Aggregations

InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)285 Test (org.junit.Test)217 ObjectTypeNode (org.drools.core.reteoo.ObjectTypeNode)140 KieBase (org.kie.api.KieBase)129 ArrayList (java.util.ArrayList)96 LeftInputAdapterNode (org.drools.core.reteoo.LeftInputAdapterNode)91 List (java.util.List)76 SegmentMemory (org.drools.core.reteoo.SegmentMemory)74 KieSession (org.kie.api.runtime.KieSession)71 RuleTerminalNode (org.drools.core.reteoo.RuleTerminalNode)69 JoinNode (org.drools.core.reteoo.JoinNode)62 BetaMemory (org.drools.core.reteoo.BetaMemory)57 InternalKnowledgeBase (org.drools.core.impl.InternalKnowledgeBase)48 PathMemory (org.drools.core.reteoo.PathMemory)48 LiaNodeMemory (org.drools.core.reteoo.LeftInputAdapterNode.LiaNodeMemory)45 BetaNode (org.drools.core.reteoo.BetaNode)44 FactHandle (org.kie.api.runtime.rule.FactHandle)44 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)35 AlphaNode (org.drools.core.reteoo.AlphaNode)35 ClassObjectType (org.drools.core.base.ClassObjectType)30