use of org.drools.core.reteoo.PathEndNode 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;
}
use of org.drools.core.reteoo.PathEndNode 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.PathEndNode in project drools by kiegroup.
the class AddRemoveRule method flushLeftTupleIfNecessary.
public static boolean flushLeftTupleIfNecessary(InternalWorkingMemory wm, SegmentMemory sm, LeftTuple leftTuple, boolean streamMode, short stagedType) {
PathMemory pmem = streamMode ? sm.getPathMemories().get(0) : sm.getFirstDataDrivenPathMemory();
if (pmem == null) {
return false;
}
TupleSets<LeftTuple> leftTupleSets = new TupleSetsImpl<LeftTuple>();
if (leftTuple != null) {
switch(stagedType) {
case Tuple.INSERT:
leftTupleSets.addInsert(leftTuple);
break;
case Tuple.DELETE:
leftTupleSets.addDelete(leftTuple);
break;
case Tuple.UPDATE:
leftTupleSets.addUpdate(leftTuple);
break;
}
}
forceFlushLeftTuple(pmem, sm, wm, leftTupleSets);
if (pmem.isDataDriven() && pmem.getNodeType() == NodeTypeEnums.RightInputAdaterNode) {
for (PathEndNode pnode : pmem.getPathEndNode().getPathEndNodes()) {
if (pnode instanceof TerminalNode) {
PathMemory outPmem = wm.getNodeMemory((TerminalNode) pnode);
if (outPmem.isDataDriven()) {
SegmentMemory outSmem = outPmem.getSegmentMemories()[0];
if (outSmem != null) {
forceFlushLeftTuple(outPmem, outSmem, wm, new TupleSetsImpl<LeftTuple>());
}
}
}
}
}
return true;
}
use of org.drools.core.reteoo.PathEndNode in project drools by kiegroup.
the class AddRemoveRule method insertFacts.
private static void insertFacts(PathEndNodes endNodes, InternalWorkingMemory[] wms) {
Set<LeftTupleNode> visited = new HashSet<LeftTupleNode>();
for (PathEndNode endNode : endNodes.subjectEndNodes) {
LeftTupleNode[] nodes = endNode.getPathNodes();
for (int i = 0; i < nodes.length; i++) {
LeftTupleNode node = nodes[i];
if (NodeTypeEnums.isBetaNode(node) && node.getAssociationsSize() == 1) {
if (!visited.add(node)) {
// this is to avoid rentering a path, and processing nodes twice. This can happen for nested subnetworks.
continue;
}
BetaNode bn = (BetaNode) node;
if (!bn.isRightInputIsRiaNode()) {
for (int j = 0; j < wms.length; j++) {
PropagationContextFactory pctxFactory = wms[j].getKnowledgeBase().getConfiguration().getComponentFactory().getPropagationContextFactory();
final PropagationContext pctx = pctxFactory.createPropagationContext(wms[j].getNextPropagationIdCounter(), PropagationContext.Type.RULE_ADDITION, null, null, null);
bn.getRightInput().updateSink(bn, pctx, wms[j]);
}
}
}
}
}
}
use of org.drools.core.reteoo.PathEndNode in project drools by kiegroup.
the class ReteooRuleBuilder method setPathEndNodes.
private void setPathEndNodes(BuildContext context) {
// Store the paths in reverse order, from the outermost (the main path) to the innermost subnetwork paths
PathEndNode[] pathEndNodes = context.getPathEndNodes().toArray(new PathEndNode[context.getPathEndNodes().size()]);
for (int i = 0; i < pathEndNodes.length; i++) {
PathEndNode node = context.getPathEndNodes().get(pathEndNodes.length - 1 - i);
pathEndNodes[i] = node;
if (node instanceof RightInputAdapterNode && node.getPathEndNodes() != null) {
PathEndNode[] riaPathEndNodes = new PathEndNode[node.getPathEndNodes().length + i];
System.arraycopy(pathEndNodes, 0, riaPathEndNodes, 0, i);
System.arraycopy(node.getPathEndNodes(), 0, riaPathEndNodes, i, node.getPathEndNodes().length);
node.setPathEndNodes(riaPathEndNodes);
} else {
node.setPathEndNodes(pathEndNodes);
}
}
}
Aggregations