use of org.drools.core.reteoo.LeftTupleSink in project drools by kiegroup.
the class PassiveQueryTest method testPassiveQueryUsingSegmentPropagator.
@Test
public void testPassiveQueryUsingSegmentPropagator() throws Exception {
String str = "global java.util.List list\n" + "query Q (Integer i)\n" + " String( this == i.toString() )\n" + "end\n" + "rule R1a @Propagation(IMMEDIATE) when\n" + " $i : Integer()\n" + " ?Q( $i; )\n" + "then\n" + " list.add( \"R1a\" );\n" + "end\n" + "rule R1b @Propagation(IMMEDIATE) when\n" + " $i : Integer()\n" + " ?Q( $i; )\n" + " Long( intValue == $i )\n" + "then\n" + " list.add( \"R1b\" );\n" + "end\n" + "rule R2 when\n" + " $i : Integer()\n" + " ?Q( $i; )\n" + "then\n" + " list.add( \"R2\" );\n" + "end\n";
KieBase kbase = new KieHelper().addContent(str, ResourceType.DRL).build();
KieSession ksession = kbase.newKieSession();
List<String> list = new ArrayList<String>();
ksession.setGlobal("list", list);
ksession.insert(1L);
FactHandle fh = ksession.insert(1);
ksession.insert("1");
Rete rete = ((KnowledgeBaseImpl) kbase).getRete();
LeftInputAdapterNode lia = null;
for (ObjectTypeNode otn : rete.getObjectTypeNodes()) {
if (Integer.class == otn.getObjectType().getValueType().getClassType()) {
lia = (LeftInputAdapterNode) otn.getObjectSinkPropagator().getSinks()[0];
break;
}
}
LeftTupleSink[] sinks = lia.getSinkPropagator().getSinks();
QueryElementNode q1 = (QueryElementNode) sinks[0];
QueryElementNode q2 = (QueryElementNode) sinks[1];
InternalWorkingMemory wm = (InternalWorkingMemory) ksession;
wm.flushPropagations();
Memory memory1 = wm.getNodeMemory(q1);
assertTrue(memory1.getSegmentMemory().getStagedLeftTuples().isEmpty());
ksession.fireAllRules();
assertEquals(1, list.size());
assertEquals("R2", list.get(0));
list.clear();
ksession.delete(fh);
ksession.insert(1);
ksession.fireAllRules();
assertEquals(3, list.size());
}
use of org.drools.core.reteoo.LeftTupleSink in project drools by kiegroup.
the class PathEndNodeTest method testSubNetworkSharing.
@Test
public void testSubNetworkSharing() throws Exception {
String str = "package org.test \n" + "rule xxx \n" + "when \n" + " $s : String()\n" + " not( Integer() and Long() )\n" + "then \n" + "end \n" + "rule yyy \n" + "when \n" + " $s : String()\n" + " not( Integer() and Long() )\n" + "then \n" + "end \n";
InternalKnowledgeBase kbase = (InternalKnowledgeBase) new KieHelper().addContent(str, ResourceType.DRL).build();
EntryPointNode epn = kbase.getRete().getEntryPointNode(EntryPointId.DEFAULT);
ObjectTypeNode otn = epn.getObjectTypeNodes().get(new ClassObjectType(Long.class));
BetaNode beta1 = (BetaNode) otn.getObjectSinkPropagator().getSinks()[0];
RightInputAdapterNode rian = (RightInputAdapterNode) beta1.getSinkPropagator().getSinks()[0];
BetaNode beta2 = (BetaNode) rian.getObjectSinkPropagator().getSinks()[0];
LeftTupleSink[] sinks = beta2.getSinkPropagator().getSinks();
RuleTerminalNode rtn1 = (RuleTerminalNode) sinks[0];
RuleTerminalNode rtn2 = (RuleTerminalNode) sinks[1];
assertEquals(3, rian.getPathEndNodes().length);
assertTrue(asList(rian.getPathEndNodes()).containsAll(asList(rtn1, rtn2, rian)));
kbase.removeRule("org.test", "xxx");
assertEquals(2, rian.getPathEndNodes().length);
RuleTerminalNode remainingRTN = rtn1.getRule().getName().equals("yyy") ? rtn1 : rtn2;
assertTrue(asList(rian.getPathEndNodes()).containsAll(asList(remainingRTN, rian)));
}
use of org.drools.core.reteoo.LeftTupleSink in project drools by kiegroup.
the class LeftTupleIterator method getFirstLeftTuple.
public LeftTuple getFirstLeftTuple(LeftTupleSource source, LeftTupleSink sink, InternalWorkingMemory wm) {
if (source instanceof AccumulateNode) {
AccumulateMemory accmem = (AccumulateMemory) wm.getNodeMemory((MemoryFactory) source);
BetaMemory memory = accmem.getBetaMemory();
FastIterator localIt = memory.getLeftTupleMemory().fullFastIterator();
Tuple leftTuple = BetaNode.getFirstTuple(memory.getLeftTupleMemory(), localIt);
if (leftTuple != null) {
AccumulateContext accctx = (AccumulateContext) leftTuple.getContextObject();
return accctx.getResultLeftTuple();
}
return null;
}
if (source instanceof JoinNode || source instanceof NotNode || source instanceof FromNode || source instanceof AccumulateNode) {
BetaMemory memory;
FastIterator localIt;
if (source instanceof FromNode) {
memory = ((FromMemory) wm.getNodeMemory((MemoryFactory) source)).getBetaMemory();
} else if (source instanceof AccumulateNode) {
memory = ((AccumulateMemory) wm.getNodeMemory((MemoryFactory) source)).getBetaMemory();
} else {
memory = (BetaMemory) wm.getNodeMemory((MemoryFactory) source);
}
localIt = memory.getLeftTupleMemory().fullFastIterator();
Tuple leftTuple = BetaNode.getFirstTuple(memory.getLeftTupleMemory(), localIt);
while (leftTuple != null) {
for (LeftTuple childleftTuple = leftTuple.getFirstChild(); childleftTuple != null; childleftTuple = childleftTuple.getHandleNext()) {
if (childleftTuple.getTupleSink() == sink) {
return childleftTuple;
}
}
leftTuple = (LeftTuple) localIt.next(leftTuple);
}
}
if (source instanceof ExistsNode) {
BetaMemory memory = (BetaMemory) wm.getNodeMemory((MemoryFactory) source);
FastIterator localIt = memory.getRightTupleMemory().fullFastIterator();
RightTuple rightTuple = (RightTuple) BetaNode.getFirstTuple(memory.getRightTupleMemory(), localIt);
while (rightTuple != null) {
if (rightTuple.getBlocked() != null) {
for (LeftTuple leftTuple = rightTuple.getBlocked(); leftTuple != null; leftTuple = leftTuple.getBlockedNext()) {
for (LeftTuple childleftTuple = leftTuple.getFirstChild(); childleftTuple != null; childleftTuple = childleftTuple.getHandleNext()) {
if (childleftTuple.getTupleSink() == sink) {
return childleftTuple;
}
}
}
}
rightTuple = (RightTuple) localIt.next(rightTuple);
}
} else if (source instanceof LeftInputAdapterNode) {
ObjectSource os = ((LeftInputAdapterNode) source).getParentObjectSource();
while (!(os instanceof ObjectTypeNode)) {
os = os.getParentObjectSource();
}
ObjectTypeNode otn = (ObjectTypeNode) os;
otnIterator = wm.getNodeMemory(otn).iterator();
while (otnIterator.hasNext()) {
InternalFactHandle handle = otnIterator.next();
LeftTuple leftTuple = handle.findFirstLeftTuple(lt -> lt.getTupleSink() == sink);
if (leftTuple != null) {
return leftTuple;
}
}
} else if (source instanceof EvalConditionNode || source instanceof QueryElementNode) {
LeftTuple parentLeftTuple = getFirstLeftTuple(source.getLeftTupleSource(), (LeftTupleSink) source, wm);
while (parentLeftTuple != null) {
for (LeftTuple leftTuple = parentLeftTuple.getFirstChild(); leftTuple != null; leftTuple = leftTuple.getHandleNext()) {
if (leftTuple.getTupleSink() == sink) {
return leftTuple;
}
}
parentLeftTuple = getNextLeftTuple(source.getLeftTupleSource(), (LeftTupleSink) source, parentLeftTuple, wm);
}
}
return null;
}
use of org.drools.core.reteoo.LeftTupleSink 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<LeftTupleNode>();
for (PathMemory pmem : pmems) {
LeftTupleSink tipNode = (LeftTupleSink) 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();
}
}
}
use of org.drools.core.reteoo.LeftTupleSink in project drools by kiegroup.
the class RuleNetworkEvaluator method evalStackEntry.
public void evalStackEntry(StackEntry entry, LinkedList<StackEntry> stack, RuleExecutor executor, InternalAgenda agenda) {
NetworkNode node = entry.getNode();
Memory nodeMem = entry.getNodeMem();
TupleSets<LeftTuple> trgTuples = entry.getTrgTuples();
if (node.getType() == NodeTypeEnums.QueryElementNode) {
// copy across the results, if any from the query node memory
QueryElementNodeMemory qmem = (QueryElementNodeMemory) nodeMem;
qmem.setNodeCleanWithoutNotify();
qmem.getResultLeftTuples().addTo(trgTuples);
}
LeftTupleSinkNode sink = entry.getSink();
PathMemory pmem = entry.getRmem();
SegmentMemory[] smems = entry.getSmems();
int smemIndex = entry.getSmemIndex();
boolean processRian = entry.isProcessRian();
long bit = entry.getBit();
if (entry.isResumeFromNextNode()) {
SegmentMemory smem = smems[smemIndex];
if (node != smem.getTipNode()) {
// get next node and node memory in the segment
LeftTupleSink nextSink = sink.getNextLeftTupleSinkNode();
if (nextSink == null) {
node = sink;
} else {
// there is a nested subnetwork, take out path
node = nextSink;
}
nodeMem = nodeMem.getNext();
// update bit to new node
bit = bit << 1;
} else {
// Reached end of segment, start on new segment.
SegmentPropagator.propagate(smem, trgTuples, agenda.getWorkingMemory());
smem = smems[++smemIndex];
trgTuples = smem.getStagedLeftTuples().takeAll();
node = smem.getRootNode();
nodeMem = smem.getNodeMemories().getFirst();
// update bit to start of new segment
bit = 1;
}
}
if (log.isTraceEnabled()) {
int offset = getOffset(node);
log.trace("{} Resume {} {}", indent(offset), node.toString(), trgTuples.toStringSizes());
}
innerEval(pmem, node, bit, nodeMem, smems, smemIndex, trgTuples, agenda, stack, processRian, executor);
}
Aggregations