use of org.drools.core.reteoo.LeftTupleNode 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;
}
}
use of org.drools.core.reteoo.LeftTupleNode in project drools by kiegroup.
the class AddRemoveRule method removeRule.
/**
* This method is called before the rule nodes are removed from the network.
* For remove tuples are processed before the segments and pmems have been adjusted
*/
public static void removeRule(TerminalNode tn, InternalWorkingMemory[] wms, InternalKnowledgeBase kBase) {
if (log.isTraceEnabled()) {
log.trace("Removing Rule {}", tn.getRule().getName());
}
boolean hasProtos = kBase.hasSegmentPrototypes();
boolean hasWms = wms.length > 0;
if (!hasProtos && !hasWms) {
return;
}
RuleImpl rule = tn.getRule();
LeftTupleNode firstSplit = getNetworkSplitPoint(tn);
PathEndNodes pathEndNodes = getPathEndNodes(kBase, firstSplit, tn, rule, hasProtos, hasWms);
for (InternalWorkingMemory wm : wms) {
wm.flushPropagations();
PathEndNodeMemories tnms = getPathEndMemories(wm, pathEndNodes);
if (!tnms.subjectPmems.isEmpty()) {
if (NodeTypeEnums.LeftInputAdapterNode == firstSplit.getType() && firstSplit.getAssociationsSize() == 1) {
if (tnms.subjectPmem != null) {
flushStagedTuples(firstSplit, tnms.subjectPmem, wm);
}
processLeftTuples(firstSplit, wm, false, tn.getRule());
removeNewPaths(wm, tnms.subjectPmems);
} else {
flushStagedTuples(tn, tnms.subjectPmem, pathEndNodes, wm);
processLeftTuples(firstSplit, wm, false, tn.getRule());
removeNewPaths(wm, tnms.subjectPmems);
Map<PathMemory, SegmentMemory[]> prevSmemsLookup = reInitPathMemories(tnms.otherPmems, tn);
// must collect all visited SegmentMemories, for link notification
Set<SegmentMemory> smemsToNotify = handleExistingPaths(tn, prevSmemsLookup, tnms.otherPmems, wm, ExistingPathStrategy.REMOVE_STRATEGY);
notifySegments(smemsToNotify, wm);
}
}
if (tnms.subjectPmem != null && tnms.subjectPmem.isInitialized() && tnms.subjectPmem.getRuleAgendaItem().isQueued()) {
// SubjectPmem can be null, if it was never initialized
tnms.subjectPmem.getRuleAgendaItem().dequeue();
}
}
}
use of org.drools.core.reteoo.LeftTupleNode in project drools by kiegroup.
the class AddRemoveRule method addRule.
/**
* This method is called after the rule nodes have been added to the network
* For add tuples are processed after the segments and pmems have been adjusted
*/
public static void addRule(TerminalNode tn, InternalWorkingMemory[] wms, InternalKnowledgeBase kBase) {
if (log.isTraceEnabled()) {
log.trace("Adding Rule {}", tn.getRule().getName());
}
boolean hasProtos = kBase.hasSegmentPrototypes();
boolean hasWms = wms.length > 0;
if (!hasProtos && !hasWms) {
return;
}
RuleImpl rule = tn.getRule();
LeftTupleNode firstSplit = getNetworkSplitPoint(tn);
PathEndNodes pathEndNodes = getPathEndNodes(kBase, firstSplit, tn, rule, hasProtos, hasWms);
for (InternalWorkingMemory wm : wms) {
wm.flushPropagations();
if (NodeTypeEnums.LeftInputAdapterNode == firstSplit.getType() && firstSplit.getAssociationsSize() == 1) {
// rule added with no sharing
insertLiaFacts(firstSplit, wm);
} else {
PathEndNodeMemories tnms = getPathEndMemories(wm, pathEndNodes);
if (tnms.subjectPmem == null) {
// If the existing PathMemories are not yet initialized there are no Segments or tuples to process
continue;
}
Map<PathMemory, SegmentMemory[]> prevSmemsLookup = reInitPathMemories(tnms.otherPmems, null);
// must collect all visited SegmentMemories, for link notification
Set<SegmentMemory> smemsToNotify = handleExistingPaths(tn, prevSmemsLookup, tnms.otherPmems, wm, ExistingPathStrategy.ADD_STRATEGY);
addNewPaths(wm, smemsToNotify, tnms.subjectPmems);
processLeftTuples(firstSplit, wm, true, rule);
notifySegments(smemsToNotify, wm);
}
}
if (hasWms) {
insertFacts(pathEndNodes, wms);
} else {
for (PathEndNode node : pathEndNodes.otherEndNodes) {
node.resetPathMemSpec(null);
}
}
}
use of org.drools.core.reteoo.LeftTupleNode in project drools by kiegroup.
the class NodePositionInPathTest method test.
@Test
public void test() {
String drl = "rule R1 when\n" + " Integer()\n" + " exists( Integer() and Integer() )\n" + " String()\n" + "then\n" + "end\n" + "rule R2 when\n" + " Integer()\n" + " exists( Integer() and String() )\n" + "then\n" + "end\n";
KieBase kbase = new KieHelper().addContent(drl, ResourceType.DRL).build();
ReteDumper.dumpRete(((InternalKnowledgeBase) kbase));
Rete rete = ((KnowledgeBaseImpl) kbase).getRete();
LeftInputAdapterNode liaNode = null;
for (ObjectTypeNode otn : rete.getObjectTypeNodes()) {
Class<?> otnType = ((ClassObjectType) otn.getObjectType()).getClassType();
if (Integer.class == otnType) {
liaNode = (LeftInputAdapterNode) otn.getObjectSinkPropagator().getSinks()[0];
}
}
assertEquals(0, liaNode.getPositionInPath());
LeftTupleSink[] liaSinks = liaNode.getSinkPropagator().getSinks();
BetaNode join1 = (BetaNode) liaSinks[0];
assertEquals(1, join1.getPositionInPath());
ExistsNode ex1 = (ExistsNode) liaSinks[1];
assertEquals(1, ex1.getPositionInPath());
BetaNode join2 = (BetaNode) ex1.getSinkPropagator().getSinks()[0];
assertEquals(2, join2.getPositionInPath());
RuleTerminalNode rtn1 = (RuleTerminalNode) join2.getSinkPropagator().getSinks()[0];
assertEquals(3, rtn1.getPositionInPath());
ExistsNode ex2 = (ExistsNode) liaSinks[2];
assertEquals(1, ex2.getPositionInPath());
RuleTerminalNode rtn2 = (RuleTerminalNode) ex2.getSinkPropagator().getSinks()[0];
assertEquals(2, rtn2.getPositionInPath());
BetaNode join3 = (BetaNode) join1.getSinkPropagator().getSinks()[0];
assertEquals(2, join3.getPositionInPath());
RightInputAdapterNode ria1 = (RightInputAdapterNode) join3.getSinkPropagator().getSinks()[0];
assertEquals(3, ria1.getPositionInPath());
BetaNode join4 = (BetaNode) join1.getSinkPropagator().getSinks()[1];
assertEquals(2, join4.getPositionInPath());
RightInputAdapterNode ria2 = (RightInputAdapterNode) join4.getSinkPropagator().getSinks()[0];
assertEquals(3, ria2.getPositionInPath());
LeftTupleNode[] rtn1PathNodes = rtn1.getPathNodes();
assertEquals(4, rtn1PathNodes.length);
checkNodePosition(rtn1PathNodes, liaNode);
checkNodePosition(rtn1PathNodes, ex1);
checkNodePosition(rtn1PathNodes, join2);
checkNodePosition(rtn1PathNodes, rtn1);
LeftTupleNode[] rtn2PathNodes = rtn2.getPathNodes();
assertEquals(3, rtn2PathNodes.length);
checkNodePosition(rtn2PathNodes, liaNode);
checkNodePosition(rtn2PathNodes, ex2);
checkNodePosition(rtn2PathNodes, rtn2);
LeftTupleNode[] ria1PathNodes = ria1.getPathNodes();
assertEquals(4, ria1PathNodes.length);
checkNodePosition(ria1PathNodes, liaNode);
checkNodePosition(ria1PathNodes, join1);
checkNodePosition(ria1PathNodes, join3);
checkNodePosition(ria1PathNodes, ria1);
LeftTupleNode[] ria2PathNodes = ria2.getPathNodes();
assertEquals(4, ria2PathNodes.length);
checkNodePosition(ria2PathNodes, liaNode);
checkNodePosition(ria2PathNodes, join1);
checkNodePosition(ria2PathNodes, join4);
checkNodePosition(ria2PathNodes, ria2);
}
use of org.drools.core.reteoo.LeftTupleNode in project drools by kiegroup.
the class AddRemoveRule method removeRule.
/**
* This method is called before the rule nodes are removed from the network.
* For remove tuples are processed before the segments and pmems have been adjusted
*/
public static void removeRule(TerminalNode tn, Collection<InternalWorkingMemory> wms, RuleBase kBase) {
if (log.isTraceEnabled()) {
log.trace("Removing Rule {}", tn.getRule().getName());
}
boolean hasProtos = kBase.hasSegmentPrototypes();
boolean hasWms = !wms.isEmpty();
if (!hasProtos && !hasWms) {
return;
}
RuleImpl rule = tn.getRule();
LeftTupleNode firstSplit = getNetworkSplitPoint(tn);
PathEndNodes pathEndNodes = getPathEndNodes(kBase, firstSplit, tn, rule, hasProtos, hasWms);
for (InternalWorkingMemory wm : wms) {
wm.flushPropagations();
PathEndNodeMemories tnms = getPathEndMemories(wm, pathEndNodes);
if (!tnms.subjectPmems.isEmpty()) {
if (NodeTypeEnums.LeftInputAdapterNode == firstSplit.getType() && firstSplit.getAssociationsSize() == 1) {
if (tnms.subjectPmem != null) {
flushStagedTuples(firstSplit, tnms.subjectPmem, wm);
}
processLeftTuples(firstSplit, wm, false, tn.getRule());
removeNewPaths(wm, tnms.subjectPmems);
} else {
flushStagedTuples(tn, tnms.subjectPmem, pathEndNodes, wm);
processLeftTuples(firstSplit, wm, false, tn.getRule());
removeNewPaths(wm, tnms.subjectPmems);
Map<PathMemory, SegmentMemory[]> prevSmemsLookup = reInitPathMemories(tnms.otherPmems, tn);
// must collect all visited SegmentMemories, for link notification
Set<SegmentMemory> smemsToNotify = handleExistingPaths(tn, prevSmemsLookup, tnms.otherPmems, wm, ExistingPathStrategy.REMOVE_STRATEGY);
notifySegments(smemsToNotify, wm);
}
}
if (tnms.subjectPmem != null && tnms.subjectPmem.isInitialized() && tnms.subjectPmem.getRuleAgendaItem().isQueued()) {
// SubjectPmem can be null, if it was never initialized
tnms.subjectPmem.getRuleAgendaItem().dequeue();
}
}
if (!hasWms) {
for (PathEndNode node : pathEndNodes.otherEndNodes) {
node.resetPathMemSpec(null);
}
}
}
Aggregations