use of org.drools.core.reteoo.LeftTupleNode in project drools by kiegroup.
the class AddRemoveRule method insertFacts.
private static void insertFacts(PathEndNodes endNodes, Collection<InternalWorkingMemory> wms) {
Set<LeftTupleNode> visited = new HashSet<>();
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 (InternalWorkingMemory wm : wms) {
PropagationContextFactory pctxFactory = RuntimeComponentFactory.get().getPropagationContextFactory();
final PropagationContext pctx = pctxFactory.createPropagationContext(wm.getNextPropagationIdCounter(), PropagationContext.Type.RULE_ADDITION, null, null, null);
bn.getRightInput().updateSink(bn, pctx, wm);
}
}
}
}
}
}
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<>();
Set<SegmentMemory> visitedSegments = new HashSet<>();
Set<LeftTupleNode> visitedNodes = new HashSet<>();
Map<LeftTupleNode, SegmentMemory> nodeToSegmentMap = new HashMap<>();
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++];
LeftTupleSource 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(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 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<>();
for (PathMemory pmem : pmems) {
LeftTupleSink tipNode = 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 forceFlushLeftTuple.
public static void forceFlushLeftTuple(PathMemory pmem, SegmentMemory sm, ReteEvaluator reteEvaluator, 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 : reteEvaluator.getNodeMemory((AbstractTerminalNode) pmem.getPathEndNode().getPathEndNodes()[0]);
ActivationsManager activationsManager = pmem.getActualActivationsManager(reteEvaluator);
RuleNetworkEvaluator.INSTANCE.outerEval(pmem, node, bit, mem, smems, sm.getPos(), leftTupleSets, activationsManager, new LinkedList<>(), true, rtnPmem.getOrCreateRuleAgendaItem(activationsManager).getRuleExecutor());
}
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