use of org.drools.core.reteoo.SegmentMemory 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;
}
use of org.drools.core.reteoo.SegmentMemory 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.SegmentMemory in project drools by kiegroup.
the class AddRemoveRule method flushStagedTuples.
private static void flushStagedTuples(LeftTupleNode splitStartNode, PathMemory pmem, InternalWorkingMemory wm) {
if (!pmem.isInitialized()) {
// The rule has never been linked in and evaluated, so there will be nothing to flush.
return;
}
// index before the segments are merged
int smemIndex = getSegmentPos(splitStartNode);
SegmentMemory[] smems = pmem.getSegmentMemories();
SegmentMemory sm = null;
// If there is no sharing, then there will not be any staged tuples in later segemnts, and thus no need to search for them if the current sm is empty.
int length = smems.length;
if (splitStartNode.getAssociationsSize() == 1) {
length = 1;
}
while (smemIndex < length) {
sm = smems[smemIndex];
if (sm != null && !sm.getStagedLeftTuples().isEmpty()) {
break;
}
smemIndex++;
}
if (smemIndex < length) {
// it only found a SM that needed flushing, if smemIndex < length
forceFlushLeftTuple(pmem, sm, wm, sm.getStagedLeftTuples().takeAll());
}
}
use of org.drools.core.reteoo.SegmentMemory 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());
}
use of org.drools.core.reteoo.SegmentMemory in project drools by kiegroup.
the class AddRemoveRule method mergeNodeMemories.
private static void mergeNodeMemories(SegmentMemory sm1, SegmentMemory sm2) {
LinkedList<Memory> smNodeMemories1 = sm1.getNodeMemories();
LinkedList<Memory> smNodeMemories2 = sm2.getNodeMemories();
int nodePosMask = 1;
for (int i = 0, length = smNodeMemories1.size(); i < length; i++) {
nodePosMask = nodePosMask >> 1;
}
for (Memory mem = smNodeMemories2.getFirst(); mem != null; ) {
Memory next = mem.getNext();
smNodeMemories2.remove(mem);
smNodeMemories1.add(mem);
mem.setSegmentMemory(sm1);
// correct the NodePosMaskBit
if (mem instanceof SegmentNodeMemory) {
((SegmentNodeMemory) mem).setNodePosMaskBit(nodePosMask);
}
nodePosMask = nodePosMask >> 1;
mem = next;
}
}
Aggregations