use of org.drools.core.reteoo.SegmentMemory in project drools by kiegroup.
the class AddRemoveRule method removeRule.
/**
* This method is called before the rule nodes are removed from the network.
* For remove tuples are processed before the segments and pmems have been adjusted
*/
public static void removeRule(TerminalNode tn, InternalWorkingMemory[] wms, InternalKnowledgeBase kBase) {
if (log.isTraceEnabled()) {
log.trace("Removing 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();
PathEndNodeMemories tnms = getPathEndMemories(wm, pathEndNodes);
if (!tnms.subjectPmems.isEmpty()) {
if (NodeTypeEnums.LeftInputAdapterNode == firstSplit.getType() && firstSplit.getAssociationsSize() == 1) {
if (tnms.subjectPmem != null) {
flushStagedTuples(firstSplit, tnms.subjectPmem, wm);
}
processLeftTuples(firstSplit, wm, false, tn.getRule());
removeNewPaths(wm, tnms.subjectPmems);
} else {
flushStagedTuples(tn, tnms.subjectPmem, pathEndNodes, wm);
processLeftTuples(firstSplit, wm, false, tn.getRule());
removeNewPaths(wm, tnms.subjectPmems);
Map<PathMemory, SegmentMemory[]> prevSmemsLookup = reInitPathMemories(tnms.otherPmems, tn);
// must collect all visited SegmentMemories, for link notification
Set<SegmentMemory> smemsToNotify = handleExistingPaths(tn, prevSmemsLookup, tnms.otherPmems, wm, ExistingPathStrategy.REMOVE_STRATEGY);
notifySegments(smemsToNotify, wm);
}
}
if (tnms.subjectPmem != null && tnms.subjectPmem.isInitialized() && tnms.subjectPmem.getRuleAgendaItem().isQueued()) {
// SubjectPmem can be null, if it was never initialized
tnms.subjectPmem.getRuleAgendaItem().dequeue();
}
}
}
use of org.drools.core.reteoo.SegmentMemory 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.SegmentMemory in project drools by kiegroup.
the class AddRemoveRule method removeNewPaths.
private static void removeNewPaths(InternalWorkingMemory wm, List<PathMemory> pmems) {
Set<Integer> visitedNodes = new HashSet<Integer>();
for (PathMemory pmem : pmems) {
LeftTupleSink tipNode = (LeftTupleSink) pmem.getPathEndNode();
LeftTupleNode child = tipNode;
LeftTupleNode parent = tipNode.getLeftTupleSource();
while (true) {
if (child.getAssociationsSize() == 1 && NodeTypeEnums.isBetaNode(child)) {
// If this is a beta node, it'll delete all the right input data
deleteRightInputData((LeftTupleSink) child, wm);
}
if (parent != null && parent.getAssociationsSize() != 1 && child.getAssociationsSize() == 1) {
// all right input data must be propagated
if (!visitedNodes.contains(child.getId())) {
Memory mem = wm.getNodeMemories().peekNodeMemory(parent);
if (mem != null && mem.getSegmentMemory() != null) {
SegmentMemory sm = mem.getSegmentMemory();
if (sm.getFirst() != null) {
SegmentMemory childSm = wm.getNodeMemories().peekNodeMemory(child).getSegmentMemory();
sm.remove(childSm);
}
}
}
} 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)) {
mem.getSegmentMemory().removePathMemory(pmem);
}
}
}
if (parent == null) {
break;
}
visitedNodes.add(child.getId());
child = parent;
parent = parent.getLeftTupleSource();
}
}
}
use of org.drools.core.reteoo.SegmentMemory 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.SegmentMemory in project drools by kiegroup.
the class AddRemoveRule method mergeSegment.
private static void mergeSegment(SegmentMemory sm1, SegmentMemory sm2) {
if (sm1.getTipNode().getType() == NodeTypeEnums.LeftInputAdapterNode && !sm2.getStagedLeftTuples().isEmpty()) {
// If a rule has not been linked, lia can still have child segments with staged tuples that did not get flushed
// these are safe to just move to the parent SegmentMemory
sm1.getStagedLeftTuples().addAll(sm2.getStagedLeftTuples());
}
// sm1 may not be linked yet to sm2 because sm2 has been just created
if (sm1.contains(sm2)) {
sm1.remove(sm2);
}
if (sm2.getFirst() != null) {
for (SegmentMemory sm = sm2.getFirst(); sm != null; ) {
SegmentMemory next = sm.getNext();
sm2.remove(sm);
sm1.add(sm);
sm = next;
}
}
// re-assigned tip nodes
sm1.setTipNode(sm2.getTipNode());
mergeNodeMemories(sm1, sm2);
mergeBitMasks(sm1, sm2);
}
Aggregations