Search in sources :

Example 1 with SegmentMemory

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

the class PhreakQueryNode method doLeftUpdates.

public void doLeftUpdates(QueryElementNode queryNode, QueryElementNodeMemory qmem, InternalWorkingMemory wm, TupleSets<LeftTuple> srcLeftTuples) {
    for (LeftTuple leftTuple = srcLeftTuples.getUpdateFirst(); leftTuple != null; ) {
        LeftTuple next = leftTuple.getStagedNext();
        InternalFactHandle fh = (InternalFactHandle) leftTuple.getContextObject();
        DroolsQuery dquery = (DroolsQuery) fh.getObject();
        dquery.setParameters(queryNode.getActualArguments(leftTuple, wm));
        SegmentMemory qsmem = qmem.getQuerySegmentMemory();
        LeftInputAdapterNode lian = (LeftInputAdapterNode) qsmem.getRootNode();
        LiaNodeMemory lmem = (LiaNodeMemory) qsmem.getNodeMemories().getFirst();
        if (dquery.isOpen()) {
            // there is only one, all other LTs are peers
            LeftTuple childLeftTuple = fh.getFirstLeftTuple();
            LeftInputAdapterNode.doUpdateObject(childLeftTuple, childLeftTuple.getPropagationContext(), wm, lian, false, lmem, qmem.getQuerySegmentMemory());
        } else {
            if (fh.getFirstLeftTuple() != null) {
                // @TODO remove later (mdp)
                throw new RuntimeException("defensive programming while testing");
            }
            LiaNodeMemory lm = (LiaNodeMemory) qmem.getQuerySegmentMemory().getNodeMemories().get(0);
            LeftInputAdapterNode.doInsertObject(fh, leftTuple.getPropagationContext(), lian, wm, lm, false, dquery.isOpen());
        }
        leftTuple.clearStaged();
        leftTuple = next;
    }
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory) InternalFactHandle(org.drools.core.common.InternalFactHandle) LeftTuple(org.drools.core.reteoo.LeftTuple) LiaNodeMemory(org.drools.core.reteoo.LeftInputAdapterNode.LiaNodeMemory) DroolsQuery(org.drools.core.base.DroolsQuery) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode)

Example 2 with SegmentMemory

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

the class RuleNetworkEvaluator method evalQueryNode.

private boolean evalQueryNode(PathMemory pmem, NetworkNode node, long bit, Memory nodeMem, SegmentMemory[] smems, int smemIndex, TupleSets<LeftTuple> trgTuples, InternalWorkingMemory wm, LinkedList<StackEntry> stack, TupleSets<LeftTuple> srcTuples, LeftTupleSinkNode sink, TupleSets<LeftTuple> stagedLeftTuples) {
    QueryElementNodeMemory qmem = (QueryElementNodeMemory) nodeMem;
    if (srcTuples.isEmpty() && qmem.getResultLeftTuples().isEmpty()) {
        // no point in evaluating query element, and setting up stack, if there is nothing to process
        return false;
    }
    QueryElementNode qnode = (QueryElementNode) node;
    if (log.isTraceEnabled()) {
        int offset = getOffset(node);
        log.trace("{} query result tuples {}", indent(offset), qmem.getResultLeftTuples().toStringSizes());
    }
    // result tuples can happen when reactivity occurs inside of the query, prior to evaluation
    // we will need special behaviour to add the results again, when this query result resumes
    qmem.getResultLeftTuples().addTo(trgTuples);
    qmem.setNodeCleanWithoutNotify();
    if (!srcTuples.isEmpty()) {
        // only process the Query Node if there are src tuples
        StackEntry stackEntry = new StackEntry(node, bit, sink, pmem, nodeMem, smems, smemIndex, trgTuples, true, true);
        stack.add(stackEntry);
        pQueryNode.doNode(qnode, (QueryElementNodeMemory) nodeMem, stackEntry, wm, srcTuples, trgTuples, stagedLeftTuples);
        SegmentMemory qsmem = ((QueryElementNodeMemory) nodeMem).getQuerySegmentMemory();
        List<PathMemory> qpmems = qsmem.getPathMemories();
        // Build the evaluation information for each 'or' branch
        for (int i = 0; i < qpmems.size(); i++) {
            PathMemory qpmem = qpmems.get(i);
            pmem = qpmem;
            smems = qpmem.getSegmentMemories();
            smemIndex = 0;
            // 0
            SegmentMemory smem = smems[smemIndex];
            LeftTupleNode liaNode = (LeftInputAdapterNode) qpmem.getPathEndNode().getPathNodes()[0];
            if (liaNode == smem.getTipNode()) {
                // segment only has liaNode in it
                // nothing is staged in the liaNode, so skip to next segment
                // 1
                smem = smems[++smemIndex];
                node = smem.getRootNode();
                nodeMem = smem.getNodeMemories().getFirst();
                bit = 1;
            } else {
                // lia is in shared segment, so point to next node
                node = liaNode.getSinkPropagator().getFirstLeftTupleSink();
                // skip the liaNode memory
                nodeMem = smem.getNodeMemories().getFirst().getNext();
                bit = 2;
            }
            trgTuples = smem.getStagedLeftTuples().takeAll();
            stackEntry = new StackEntry(node, bit, null, pmem, nodeMem, smems, smemIndex, trgTuples, false, true);
            if (log.isTraceEnabled()) {
                int offset = getOffset(stackEntry.getNode());
                log.trace("{} ORQueue branch={} {} {}", indent(offset), i, stackEntry.getNode().toString(), trgTuples.toStringSizes());
            }
            stack.add(stackEntry);
        }
        return true;
    } else {
        return false;
    }
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory) QueryElementNode(org.drools.core.reteoo.QueryElementNode) QueryElementNodeMemory(org.drools.core.reteoo.QueryElementNode.QueryElementNodeMemory) LeftTupleNode(org.drools.core.reteoo.LeftTupleNode) PathMemory(org.drools.core.reteoo.PathMemory) RiaPathMemory(org.drools.core.reteoo.RiaPathMemory) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode)

Example 3 with SegmentMemory

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

the class RuleNetworkEvaluator method doRiaNode.

private void doRiaNode(InternalAgenda agenda, PathMemory pmem, TupleSets<LeftTuple> srcTuples, BetaNode betaNode, LeftTupleSinkNode sink, SegmentMemory[] smems, int smemIndex, Memory nodeMem, BetaMemory bm, LinkedList<StackEntry> stack, RuleExecutor executor) {
    RiaPathMemory pathMem = bm.getRiaRuleMemory();
    SegmentMemory[] subnetworkSmems = pathMem.getSegmentMemories();
    SegmentMemory subSmem = null;
    for (int i = 0; subSmem == null; i++) {
        // segment positions outside of the subnetwork, in the parent chain, are null
        // so we must iterate to find the first non null segment memory
        subSmem = subnetworkSmems[i];
    }
    // Resume the node after the riaNode segment has been processed and the right input memory populated
    StackEntry stackEntry = new StackEntry(betaNode, bm.getNodePosMaskBit(), sink, pmem, nodeMem, smems, smemIndex, srcTuples, false, false);
    stack.add(stackEntry);
    if (log.isTraceEnabled()) {
        int offset = getOffset(betaNode);
        log.trace("{} RiaQueue {} {}", indent(offset), betaNode.toString(), srcTuples.toStringSizes());
    }
    TupleSets<LeftTuple> subLts = subSmem.getStagedLeftTuples().takeAll();
    // node is first in the segment, so bit is 1
    innerEval(pathMem, subSmem.getRootNode(), 1, subSmem.getNodeMemories().getFirst(), subnetworkSmems, subSmem.getPos(), subLts, agenda, stack, true, executor);
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory) RiaPathMemory(org.drools.core.reteoo.RiaPathMemory) LeftTuple(org.drools.core.reteoo.LeftTuple)

Example 4 with SegmentMemory

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

the class RuleNetworkEvaluator method evaluateNetwork.

public void evaluateNetwork(PathMemory pmem, RuleExecutor executor, InternalAgenda agenda) {
    SegmentMemory[] smems = pmem.getSegmentMemories();
    int smemIndex = 0;
    // 0
    SegmentMemory smem = smems[smemIndex];
    LeftInputAdapterNode liaNode = (LeftInputAdapterNode) smem.getRootNode();
    LinkedList<StackEntry> stack = new LinkedList<StackEntry>();
    NetworkNode node;
    Memory nodeMem;
    long bit = 1;
    if (liaNode == smem.getTipNode()) {
        // segment only has liaNode in it
        // nothing is staged in the liaNode, so skip to next segment
        // 1
        smem = smems[++smemIndex];
        node = smem.getRootNode();
        nodeMem = smem.getNodeMemories().getFirst();
    } else {
        // lia is in shared segment, so point to next node
        bit = 2;
        node = liaNode.getSinkPropagator().getFirstLeftTupleSink();
        // skip the liaNode memory
        nodeMem = smem.getNodeMemories().getFirst().getNext();
    }
    TupleSets<LeftTuple> srcTuples = smem.getStagedLeftTuples();
    if (log.isTraceEnabled()) {
        log.trace("Rule[name={}] segments={} {}", ((TerminalNode) pmem.getPathEndNode()).getRule().getName(), smems.length, srcTuples.toStringSizes());
    }
    outerEval(pmem, node, bit, nodeMem, smems, smemIndex, srcTuples, agenda, stack, true, executor);
}
Also used : SegmentMemory(org.drools.core.reteoo.SegmentMemory) 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) NetworkNode(org.drools.core.common.NetworkNode) LeftTuple(org.drools.core.reteoo.LeftTuple) LinkedList(org.drools.core.util.LinkedList) QueryTerminalNode(org.drools.core.reteoo.QueryTerminalNode) TerminalNode(org.drools.core.reteoo.TerminalNode) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode)

Example 5 with SegmentMemory

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

the class RuleNetworkEvaluator method innerEval.

public void innerEval(PathMemory pmem, NetworkNode node, long bit, Memory nodeMem, SegmentMemory[] smems, int smemIndex, TupleSets<LeftTuple> trgTuples, InternalAgenda agenda, LinkedList<StackEntry> stack, boolean processRian, RuleExecutor executor) {
    TupleSets<LeftTuple> srcTuples;
    SegmentMemory smem = smems[smemIndex];
    TupleSets<LeftTuple> stagedLeftTuples = null;
    while (true) {
        // previous target, is now the source
        srcTuples = trgTuples;
        if (log.isTraceEnabled()) {
            int offset = getOffset(node);
            log.trace("{} {} {} {}", indent(offset), ++cycle, node.toString(), srcTuples.toStringSizes());
        }
        boolean emptySrcTuples = srcTuples.isEmpty();
        if (!(NodeTypeEnums.isBetaNode(node) && ((BetaNode) node).isRightInputIsRiaNode())) {
            // The engine cannot skip a ria node, as the dirty might be several levels deep
            if (emptySrcTuples && smem.getDirtyNodeMask() == 0) {
                // empty sources and segment is not dirty, skip to non empty src tuples or dirty segment.
                boolean foundDirty = false;
                for (int i = ++smemIndex, length = smems.length; i < length; i++) {
                    if (log.isTraceEnabled()) {
                        int offset = getOffset(node);
                        log.trace("{} Skip Segment {}", indent(offset), i - 1);
                    }
                    // and may not yet be initialized
                    if (smem.isEmpty() && !NodeTypeEnums.isTerminalNode(smem.getTipNode())) {
                        SegmentUtilities.createChildSegments(agenda.getWorkingMemory(), smem, ((LeftTupleSource) smem.getTipNode()).getSinkPropagator());
                    }
                    smem = smems[i];
                    bit = 1;
                    srcTuples = smem.getStagedLeftTuples().takeAll();
                    emptySrcTuples = srcTuples.isEmpty();
                    node = smem.getRootNode();
                    nodeMem = smem.getNodeMemories().getFirst();
                    if (!emptySrcTuples || smem.getDirtyNodeMask() != 0 || (NodeTypeEnums.isBetaNode(node) && ((BetaNode) node).isRightInputIsRiaNode())) {
                        // break if dirty or if we reach a subnetwork. It must break for subnetworks, so they can be searched.
                        foundDirty = true;
                        smemIndex = i;
                        break;
                    }
                }
                if (!foundDirty) {
                    break;
                }
            }
            if (log.isTraceEnabled()) {
                int offset = getOffset(node);
                log.trace("{} Segment {}", indent(offset), smemIndex);
                log.trace("{} {} {} {}", indent(offset), cycle, node.toString(), srcTuples.toStringSizes());
            }
        }
        long dirtyMask = smem.getDirtyNodeMask();
        if (emptySrcTuples) {
            while ((dirtyMask & bit) == 0 && node != smem.getTipNode() && !(NodeTypeEnums.isBetaNode(node) && ((BetaNode) node).isRightInputIsRiaNode())) {
                if (log.isTraceEnabled()) {
                    int offset = getOffset(node);
                    log.trace("{} Skip Node {}", indent(offset), node);
                }
                // shift to check the next node
                bit = bit << 1;
                node = ((LeftTupleSource) node).getSinkPropagator().getFirstLeftTupleSink();
                nodeMem = nodeMem.getNext();
            }
        }
        boolean terminalNode = true;
        switch(node.getType()) {
            case NodeTypeEnums.RuleTerminalNode:
                pRtNode.doNode((TerminalNode) node, agenda, srcTuples, executor);
                break;
            case NodeTypeEnums.QueryTerminalNode:
                pQtNode.doNode((QueryTerminalNode) node, agenda, srcTuples, stack);
                break;
            case NodeTypeEnums.RightInputAdaterNode:
                doRiaNode2(agenda.getWorkingMemory(), srcTuples, (RightInputAdapterNode) node);
                break;
            default:
                terminalNode = false;
        }
        if (terminalNode) {
            break;
        }
        stagedLeftTuples = getTargetStagedLeftTuples(node, agenda.getWorkingMemory(), smem);
        LeftTupleSinkNode sink = ((LeftTupleSource) node).getSinkPropagator().getFirstLeftTupleSink();
        trgTuples = evalNode(pmem, node, bit, nodeMem, smems, smemIndex, agenda, stack, processRian, executor, srcTuples, smem, stagedLeftTuples, sink);
        if (trgTuples == null) {
            // Queries exists and has been placed StackEntry, and there are no current trgTuples to process
            break;
        }
        if (node != smem.getTipNode()) {
            // get next node and node memory in the segment
            node = sink;
            nodeMem = nodeMem.getNext();
            bit = bit << 1;
        } else {
            // Reached end of segment, start on new segment.
            // must put back all the LTs
            smem.getFirst().getStagedLeftTuples().addAll(stagedLeftTuples);
            // end of SegmentMemory, so we know that stagedLeftTuples is not null
            SegmentPropagator.propagate(smem, trgTuples, agenda.getWorkingMemory());
            bit = 1;
            smem = smems[++smemIndex];
            trgTuples = smem.getStagedLeftTuples().takeAll();
            if (log.isTraceEnabled()) {
                int offset = getOffset(node);
                log.trace("{} Segment {}", indent(offset), smemIndex);
            }
            node = smem.getRootNode();
            nodeMem = smem.getNodeMemories().getFirst();
        }
        // make sure it's reset, so ria nodes are processed
        processRian = true;
    }
    if (stagedLeftTuples != null && !stagedLeftTuples.isEmpty()) {
        // must put back all the LTs
        smem.getFirst().getStagedLeftTuples().addAll(stagedLeftTuples);
    }
}
Also used : LeftTupleSource(org.drools.core.reteoo.LeftTupleSource) SegmentMemory(org.drools.core.reteoo.SegmentMemory) BetaNode(org.drools.core.reteoo.BetaNode) LeftTupleSinkNode(org.drools.core.reteoo.LeftTupleSinkNode) LeftTuple(org.drools.core.reteoo.LeftTuple)

Aggregations

SegmentMemory (org.drools.core.reteoo.SegmentMemory)122 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)75 Test (org.junit.Test)60 LeftInputAdapterNode (org.drools.core.reteoo.LeftInputAdapterNode)50 PathMemory (org.drools.core.reteoo.PathMemory)49 ObjectTypeNode (org.drools.core.reteoo.ObjectTypeNode)44 BetaMemory (org.drools.core.reteoo.BetaMemory)42 LiaNodeMemory (org.drools.core.reteoo.LeftInputAdapterNode.LiaNodeMemory)42 JoinNode (org.drools.core.reteoo.JoinNode)37 RuleTerminalNode (org.drools.core.reteoo.RuleTerminalNode)36 ArrayList (java.util.ArrayList)31 List (java.util.List)29 KieBase (org.kie.api.KieBase)24 LeftTuple (org.drools.core.reteoo.LeftTuple)23 Memory (org.drools.core.common.Memory)22 Match (org.kie.api.runtime.rule.Match)22 AccumulateMemory (org.drools.core.reteoo.AccumulateNode.AccumulateMemory)18 Arrays.asList (java.util.Arrays.asList)17 InternalKnowledgeBase (org.drools.core.impl.InternalKnowledgeBase)17 QueryElementNodeMemory (org.drools.core.reteoo.QueryElementNode.QueryElementNodeMemory)14