use of org.drools.core.reteoo.LeftTupleNode in project drools by kiegroup.
the class AddRemoveRule method nodeSegmentPosition.
private static int nodeSegmentPosition(SegmentMemory sm1, LeftTupleNode splitNode) {
LeftTupleNode lt = splitNode;
int nodePos = 0;
while (lt != sm1.getRootNode()) {
lt = lt.getLeftTupleSource();
nodePos++;
}
return nodePos;
}
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 getPathEndMemories.
private static PathEndNodeMemories getPathEndMemories(InternalWorkingMemory wm, PathEndNodes pathEndNodes) {
PathEndNodeMemories tnMems = new PathEndNodeMemories();
for (LeftTupleNode node : pathEndNodes.otherEndNodes) {
if (node.getType() == NodeTypeEnums.RightInputAdaterNode) {
RiaNodeMemory riaMem = (RiaNodeMemory) wm.getNodeMemories().peekNodeMemory(node);
if (riaMem != null) {
tnMems.otherPmems.add(riaMem.getRiaPathMemory());
}
} else {
PathMemory pmem = (PathMemory) wm.getNodeMemories().peekNodeMemory(node);
if (pmem != null) {
tnMems.otherPmems.add(pmem);
}
}
}
tnMems.subjectPmem = (PathMemory) wm.getNodeMemories().peekNodeMemory(pathEndNodes.subjectEndNode);
if (tnMems.subjectPmem == null && !tnMems.otherPmems.isEmpty()) {
// If "other pmem's are initialized, then the subject needs to be initialized too.
tnMems.subjectPmem = (PathMemory) wm.getNodeMemory((MemoryFactory<Memory>) pathEndNodes.subjectEndNode);
}
for (LeftTupleNode node : pathEndNodes.subjectEndNodes) {
if (node.getType() == NodeTypeEnums.RightInputAdaterNode) {
RiaNodeMemory riaMem = (RiaNodeMemory) wm.getNodeMemories().peekNodeMemory(node);
if (riaMem == null && !tnMems.otherPmems.isEmpty()) {
riaMem = (RiaNodeMemory) wm.getNodeMemory((MemoryFactory<Memory>) node);
}
if (riaMem != null) {
tnMems.subjectPmems.add(riaMem.getRiaPathMemory());
}
} else {
PathMemory pmem = (PathMemory) wm.getNodeMemories().peekNodeMemory(node);
if (pmem != null) {
tnMems.subjectPmems.add(pmem);
}
}
}
return tnMems;
}
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<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.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;
}
Aggregations