use of org.drools.core.reteoo.LeftTupleNode in project drools by kiegroup.
the class AddRemoveRule method handleExistingPaths.
private static Set<SegmentMemory> handleExistingPaths(TerminalNode tn, Map<PathMemory, SegmentMemory[]> prevSmemsLookup, List<PathMemory> pmems, InternalWorkingMemory wm, ExistingPathStrategy strategy) {
Set<SegmentMemory> smemsToNotify = new HashSet<SegmentMemory>();
Set<SegmentMemory> visitedSegments = new HashSet<SegmentMemory>();
Set<LeftTupleNode> visitedNodes = new HashSet<LeftTupleNode>();
Map<LeftTupleNode, SegmentMemory> nodeToSegmentMap = new HashMap<LeftTupleNode, SegmentMemory>();
for (PathMemory pmem : pmems) {
LeftTupleNode[] nodes = pmem.getPathEndNode().getPathNodes();
SegmentMemory[] prevSmems = prevSmemsLookup.get(pmem);
SegmentMemory[] smems = strategy.getSegmenMemories(pmem);
LeftTupleNode node;
int prevSmemIndex = 0;
int smemIndex = 0;
int smemSplitAdjustAmount = 0;
int nodeIndex = 0;
int nodeTypesInSegment = 0;
// excluding the rule just added iterate while not split (i.e. find the next split, prior to this rule being added)
// note it's checking for when the parent is the split, and thus node is the next root root.
smems[smemIndex] = prevSmems[prevSmemIndex];
do {
node = nodes[nodeIndex++];
LeftTupleNode parentNode = node.getLeftTupleSource();
nodeTypesInSegment = SegmentUtilities.updateNodeTypesMask(parentNode, nodeTypesInSegment);
if (isSplit(parentNode)) {
smemIndex = strategy.incSmemIndex1(smemIndex);
prevSmemIndex = strategy.incPrevSmemIndex1(prevSmemIndex);
if (isSplit(parentNode, tn)) {
// check if the split is there even without the processed rule
smemIndex = strategy.incSmemIndex2(smemIndex);
prevSmemIndex = strategy.incPrevSmemIndex2(prevSmemIndex);
smems[smemIndex] = prevSmems[prevSmemIndex];
if (smems[smemIndex] != null && smemSplitAdjustAmount > 0 && visitedSegments.add(smems[smemIndex])) {
strategy.adjustSegment(wm, smemsToNotify, smems[smemIndex], smemSplitAdjustAmount);
}
} else {
strategy.handleSplit(pmem, prevSmems, smems, smemIndex, prevSmemIndex, parentNode, node, tn, visitedNodes, smemsToNotify, nodeToSegmentMap, wm);
smemSplitAdjustAmount++;
}
SegmentUtilities.checkEagerSegmentCreation((LeftTupleSource) parentNode, wm, nodeTypesInSegment);
nodeTypesInSegment = 0;
}
} while (!NodeTypeEnums.isEndNode(node));
strategy.processSegmentMemories(smems, pmem);
}
return smemsToNotify;
}
use of org.drools.core.reteoo.LeftTupleNode 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.LeftTupleNode in project drools by kiegroup.
the class AddRemoveRule method forceFlushLeftTuple.
public static void forceFlushLeftTuple(PathMemory pmem, SegmentMemory sm, InternalWorkingMemory wm, TupleSets<LeftTuple> leftTupleSets) {
SegmentMemory[] smems = pmem.getSegmentMemories();
LeftTupleNode node;
Memory mem;
long bit = 1;
if (sm.getRootNode().getType() == NodeTypeEnums.LeftInputAdapterNode && sm.getTipNode().getType() != NodeTypeEnums.LeftInputAdapterNode) {
// The segment is the first and it has the lian shared with other nodes, the lian must be skipped, so adjust the bit and sink
node = sm.getRootNode().getSinkPropagator().getFirstLeftTupleSink();
mem = sm.getNodeMemories().get(1);
// adjust bit to point to next node
bit = 2;
} else {
node = sm.getRootNode();
mem = sm.getNodeMemories().get(0);
}
PathMemory rtnPmem = NodeTypeEnums.isTerminalNode(pmem.getPathEndNode()) ? pmem : wm.getNodeMemory((AbstractTerminalNode) pmem.getPathEndNode().getPathEndNodes()[0]);
InternalAgenda agenda = pmem.getActualAgenda(wm);
new RuleNetworkEvaluator().outerEval(pmem, node, bit, mem, smems, sm.getPos(), leftTupleSets, agenda, new LinkedList<StackEntry>(), true, rtnPmem.getOrCreateRuleAgendaItem(agenda).getRuleExecutor());
}
Aggregations