use of org.drools.core.reteoo.RightInputAdapterNode 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;
}
use of org.drools.core.reteoo.RightInputAdapterNode 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;
}
use of org.drools.core.reteoo.RightInputAdapterNode in project drools by kiegroup.
the class SegmentUtilities method updateRiaAndTerminalMemory.
/**
* This adds the segment memory to the terminal node or ria node's list of memories.
* In the case of the terminal node this allows it to know that all segments from
* the tip to root are linked.
* In the case of the ria node its all the segments up to the start of the subnetwork.
* This is because the rianode only cares if all of it's segments are linked, then
* it sets the bit of node it is the right input for.
*/
private static int updateRiaAndTerminalMemory(LeftTupleSource lt, LeftTupleSource originalLt, SegmentMemory smem, InternalWorkingMemory wm, boolean fromPrototype, int nodeTypesInSegment) {
nodeTypesInSegment = checkSegmentBoundary(lt, wm, nodeTypesInSegment);
for (LeftTupleSink sink : lt.getSinkPropagator().getSinks()) {
if (NodeTypeEnums.isLeftTupleSource(sink)) {
nodeTypesInSegment = updateRiaAndTerminalMemory((LeftTupleSource) sink, originalLt, smem, wm, fromPrototype, nodeTypesInSegment);
} else if (sink.getType() == NodeTypeEnums.RightInputAdaterNode) {
// Even though we don't add the pmem and smem together, all pmem's for all pathend nodes must be initialized
RiaNodeMemory riaMem = (RiaNodeMemory) wm.getNodeMemory((MemoryFactory) sink);
// Only add the RIANode, if the LeftTupleSource is part of the RIANode subnetwork
if (inSubNetwork((RightInputAdapterNode) sink, originalLt)) {
PathMemory pmem = riaMem.getRiaPathMemory();
smem.addPathMemory(pmem);
if (smem.getPos() < pmem.getSegmentMemories().length) {
pmem.setSegmentMemory(smem.getPos(), smem);
}
if (fromPrototype) {
ObjectSink[] nodes = ((RightInputAdapterNode) sink).getObjectSinkPropagator().getSinks();
for (ObjectSink node : nodes) {
// check if the SegmentMemory has been already created by the BetaNode and if so avoid to build it twice
if (NodeTypeEnums.isLeftTupleSource(node) && wm.getNodeMemory((MemoryFactory) node).getSegmentMemory() == null) {
restoreSegmentFromPrototype(wm, (LeftTupleSource) node, nodeTypesInSegment);
}
}
} else if ((pmem.getAllLinkedMaskTest() & (1L << pmem.getSegmentMemories().length)) == 0) {
// must eagerly initialize child segment memories
ObjectSink[] nodes = ((RightInputAdapterNode) sink).getObjectSinkPropagator().getSinks();
for (ObjectSink node : nodes) {
if (NodeTypeEnums.isLeftTupleSource(node)) {
createSegmentMemory((LeftTupleSource) node, wm);
}
}
}
}
} else if (NodeTypeEnums.isTerminalNode(sink)) {
PathMemory pmem = (PathMemory) wm.getNodeMemory((MemoryFactory) sink);
smem.addPathMemory(pmem);
// with the former one and in this case doesn't have to be added to the the path memory
if (smem.getPos() < pmem.getSegmentMemories().length) {
pmem.setSegmentMemory(smem.getPos(), smem);
if (smem.isSegmentLinked()) {
// not's can cause segments to be linked, and the rules need to be notified for evaluation
smem.notifyRuleLinkSegment(wm);
}
checkEagerSegmentCreation(sink.getLeftTupleSource(), wm, nodeTypesInSegment);
}
}
}
return nodeTypesInSegment;
}
use of org.drools.core.reteoo.RightInputAdapterNode in project drools by kiegroup.
the class AddRemoveRule method insertPeerRightTuple.
private static void insertPeerRightTuple(LeftTuple lt, InternalWorkingMemory wm, Rule rule, boolean insert) {
// There's a shared RightInputAdaterNode, so check if one of its sinks is associated only to the new rule
LeftTuple prevLt = null;
RightInputAdapterNode rian = lt.getTupleSink();
for (ObjectSink sink : rian.getObjectSinkPropagator().getSinks()) {
if (lt != null) {
if (prevLt != null && !insert && sink.isAssociatedWith(rule) && sink.getAssociationsSize() == 1) {
prevLt.setPeer(null);
}
prevLt = lt;
lt = lt.getPeer();
} else if (insert) {
BetaMemory bm = (BetaMemory) wm.getNodeMemory((BetaNode) sink);
prevLt = rian.createPeer(prevLt);
bm.linkNode((BetaNode) sink, wm);
bm.getStagedRightTuples().addInsert((RightTuple) prevLt);
}
}
}
use of org.drools.core.reteoo.RightInputAdapterNode in project drools by kiegroup.
the class AddRemoveRule method reInitPathMemories.
private static Map<PathMemory, SegmentMemory[]> reInitPathMemories(List<PathMemory> pathMems, TerminalNode removingTN) {
Map<PathMemory, SegmentMemory[]> previousSmems = new HashMap<PathMemory, SegmentMemory[]>();
for (PathMemory pmem : pathMems) {
// Re initialise all the PathMemories
previousSmems.put(pmem, pmem.getSegmentMemories());
LeftTupleSource startRianLts = null;
if (!NodeTypeEnums.isTerminalNode(pmem.getPathEndNode())) {
RightInputAdapterNode rian = (RightInputAdapterNode) pmem.getPathEndNode();
startRianLts = rian.getStartTupleSource();
}
PathEndNode pathEndNode = pmem.getPathEndNode();
// re-initialise the PathMemory
pathEndNode.resetPathMemSpec(removingTN);
AbstractTerminalNode.initPathMemory(pathEndNode, pmem);
}
return previousSmems;
}
Aggregations