use of org.drools.core.reteoo.LeftTuple in project drools by kiegroup.
the class RuleNetworkEvaluator method evaluateNetwork.
public void evaluateNetwork(PathMemory pmem, RuleExecutor executor, InternalAgenda agenda) {
SegmentMemory[] smems = pmem.getSegmentMemories();
int smemIndex = 0;
// 0
SegmentMemory smem = smems[smemIndex];
LeftInputAdapterNode liaNode = (LeftInputAdapterNode) smem.getRootNode();
LinkedList<StackEntry> stack = new LinkedList<StackEntry>();
NetworkNode node;
Memory nodeMem;
long bit = 1;
if (liaNode == smem.getTipNode()) {
// segment only has liaNode in it
// nothing is staged in the liaNode, so skip to next segment
// 1
smem = smems[++smemIndex];
node = smem.getRootNode();
nodeMem = smem.getNodeMemories().getFirst();
} else {
// lia is in shared segment, so point to next node
bit = 2;
node = liaNode.getSinkPropagator().getFirstLeftTupleSink();
// skip the liaNode memory
nodeMem = smem.getNodeMemories().getFirst().getNext();
}
TupleSets<LeftTuple> srcTuples = smem.getStagedLeftTuples();
if (log.isTraceEnabled()) {
log.trace("Rule[name={}] segments={} {}", ((TerminalNode) pmem.getPathEndNode()).getRule().getName(), smems.length, srcTuples.toStringSizes());
}
outerEval(pmem, node, bit, nodeMem, smems, smemIndex, srcTuples, agenda, stack, true, executor);
}
use of org.drools.core.reteoo.LeftTuple in project drools by kiegroup.
the class RuleNetworkEvaluator method innerEval.
public void innerEval(PathMemory pmem, NetworkNode node, long bit, Memory nodeMem, SegmentMemory[] smems, int smemIndex, TupleSets<LeftTuple> trgTuples, InternalAgenda agenda, LinkedList<StackEntry> stack, boolean processRian, RuleExecutor executor) {
TupleSets<LeftTuple> srcTuples;
SegmentMemory smem = smems[smemIndex];
TupleSets<LeftTuple> stagedLeftTuples = null;
while (true) {
// previous target, is now the source
srcTuples = trgTuples;
if (log.isTraceEnabled()) {
int offset = getOffset(node);
log.trace("{} {} {} {}", indent(offset), ++cycle, node.toString(), srcTuples.toStringSizes());
}
boolean emptySrcTuples = srcTuples.isEmpty();
if (!(NodeTypeEnums.isBetaNode(node) && ((BetaNode) node).isRightInputIsRiaNode())) {
// The engine cannot skip a ria node, as the dirty might be several levels deep
if (emptySrcTuples && smem.getDirtyNodeMask() == 0) {
// empty sources and segment is not dirty, skip to non empty src tuples or dirty segment.
boolean foundDirty = false;
for (int i = ++smemIndex, length = smems.length; i < length; i++) {
if (log.isTraceEnabled()) {
int offset = getOffset(node);
log.trace("{} Skip Segment {}", indent(offset), i - 1);
}
// and may not yet be initialized
if (smem.isEmpty() && !NodeTypeEnums.isTerminalNode(smem.getTipNode())) {
SegmentUtilities.createChildSegments(agenda.getWorkingMemory(), smem, ((LeftTupleSource) smem.getTipNode()).getSinkPropagator());
}
smem = smems[i];
bit = 1;
srcTuples = smem.getStagedLeftTuples().takeAll();
emptySrcTuples = srcTuples.isEmpty();
node = smem.getRootNode();
nodeMem = smem.getNodeMemories().getFirst();
if (!emptySrcTuples || smem.getDirtyNodeMask() != 0 || (NodeTypeEnums.isBetaNode(node) && ((BetaNode) node).isRightInputIsRiaNode())) {
// break if dirty or if we reach a subnetwork. It must break for subnetworks, so they can be searched.
foundDirty = true;
smemIndex = i;
break;
}
}
if (!foundDirty) {
break;
}
}
if (log.isTraceEnabled()) {
int offset = getOffset(node);
log.trace("{} Segment {}", indent(offset), smemIndex);
log.trace("{} {} {} {}", indent(offset), cycle, node.toString(), srcTuples.toStringSizes());
}
}
long dirtyMask = smem.getDirtyNodeMask();
if (emptySrcTuples) {
while ((dirtyMask & bit) == 0 && node != smem.getTipNode() && !(NodeTypeEnums.isBetaNode(node) && ((BetaNode) node).isRightInputIsRiaNode())) {
if (log.isTraceEnabled()) {
int offset = getOffset(node);
log.trace("{} Skip Node {}", indent(offset), node);
}
// shift to check the next node
bit = bit << 1;
node = ((LeftTupleSource) node).getSinkPropagator().getFirstLeftTupleSink();
nodeMem = nodeMem.getNext();
}
}
boolean terminalNode = true;
switch(node.getType()) {
case NodeTypeEnums.RuleTerminalNode:
pRtNode.doNode((TerminalNode) node, agenda, srcTuples, executor);
break;
case NodeTypeEnums.QueryTerminalNode:
pQtNode.doNode((QueryTerminalNode) node, agenda, srcTuples, stack);
break;
case NodeTypeEnums.RightInputAdaterNode:
doRiaNode2(agenda.getWorkingMemory(), srcTuples, (RightInputAdapterNode) node);
break;
default:
terminalNode = false;
}
if (terminalNode) {
break;
}
stagedLeftTuples = getTargetStagedLeftTuples(node, agenda.getWorkingMemory(), smem);
LeftTupleSinkNode sink = ((LeftTupleSource) node).getSinkPropagator().getFirstLeftTupleSink();
trgTuples = evalNode(pmem, node, bit, nodeMem, smems, smemIndex, agenda, stack, processRian, executor, srcTuples, smem, stagedLeftTuples, sink);
if (trgTuples == null) {
// Queries exists and has been placed StackEntry, and there are no current trgTuples to process
break;
}
if (node != smem.getTipNode()) {
// get next node and node memory in the segment
node = sink;
nodeMem = nodeMem.getNext();
bit = bit << 1;
} else {
// Reached end of segment, start on new segment.
// must put back all the LTs
smem.getFirst().getStagedLeftTuples().addAll(stagedLeftTuples);
// end of SegmentMemory, so we know that stagedLeftTuples is not null
SegmentPropagator.propagate(smem, trgTuples, agenda.getWorkingMemory());
bit = 1;
smem = smems[++smemIndex];
trgTuples = smem.getStagedLeftTuples().takeAll();
if (log.isTraceEnabled()) {
int offset = getOffset(node);
log.trace("{} Segment {}", indent(offset), smemIndex);
}
node = smem.getRootNode();
nodeMem = smem.getNodeMemories().getFirst();
}
// make sure it's reset, so ria nodes are processed
processRian = true;
}
if (stagedLeftTuples != null && !stagedLeftTuples.isEmpty()) {
// must put back all the LTs
smem.getFirst().getStagedLeftTuples().addAll(stagedLeftTuples);
}
}
use of org.drools.core.reteoo.LeftTuple in project drools by kiegroup.
the class RuleNetworkEvaluator method doUpdatesExistentialReorderRightMemory.
public static void doUpdatesExistentialReorderRightMemory(BetaMemory bm, BetaNode betaNode, TupleSets<RightTuple> srcRightTuples) {
TupleMemory rtm = bm.getRightTupleMemory();
boolean resumeFromCurrent = !(betaNode.isIndexedUnificationJoin() || rtm.getIndexType().isComparison());
if (rtm.getIndexType() != TupleMemory.IndexType.NONE) {
for (RightTuple rightTuple = srcRightTuples.getDeleteFirst(); rightTuple != null; rightTuple = rightTuple.getStagedNext()) {
rtm.remove(rightTuple);
}
}
for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; rightTuple = rightTuple.getStagedNext()) {
if (rightTuple.getMemory() != null) {
rightTuple.setTempRightTupleMemory(rightTuple.getMemory());
if (resumeFromCurrent) {
if (rightTuple.getBlocked() != null) {
// look for a non-staged right tuple first forward ...
RightTuple tempRightTuple = (RightTuple) rightTuple.getNext();
while (tempRightTuple != null && tempRightTuple.getStagedType() != LeftTuple.NONE) {
// next cannot be an updated or deleted rightTuple
tempRightTuple = (RightTuple) tempRightTuple.getNext();
}
// ... and if cannot find one try backward
if (tempRightTuple == null) {
tempRightTuple = (RightTuple) rightTuple.getPrevious();
while (tempRightTuple != null && tempRightTuple.getStagedType() != LeftTuple.NONE) {
// next cannot be an updated or deleted rightTuple
tempRightTuple = (RightTuple) tempRightTuple.getPrevious();
}
}
rightTuple.setTempNextRightTuple(tempRightTuple);
}
}
rightTuple.setTempBlocked(rightTuple.getBlocked());
rightTuple.setBlocked(null);
rtm.remove(rightTuple);
}
}
for (RightTuple rightTuple = srcRightTuples.getUpdateFirst(); rightTuple != null; rightTuple = rightTuple.getStagedNext()) {
rtm.add(rightTuple);
if (resumeFromCurrent) {
RightTuple tempRightTuple = rightTuple.getTempNextRightTuple();
if (rightTuple.getBlocked() != null && tempRightTuple == null && rightTuple.getMemory() == rightTuple.getTempRightTupleMemory()) {
// the next RightTuple was null, but current RightTuple was added back into the same bucket, so reset as root blocker to re-match can be attempted
rightTuple.setTempNextRightTuple(rightTuple);
}
}
for (LeftTuple childLeftTuple = rightTuple.getFirstChild(); childLeftTuple != null; ) {
LeftTuple childNext = childLeftTuple.getRightParentNext();
childLeftTuple.reAddLeft();
childLeftTuple = childNext;
}
}
if (rtm.getIndexType() != TupleMemory.IndexType.NONE) {
for (RightTuple rightTuple = srcRightTuples.getDeleteFirst(); rightTuple != null; rightTuple = rightTuple.getStagedNext()) {
rtm.add(rightTuple);
}
}
}
use of org.drools.core.reteoo.LeftTuple in project drools by kiegroup.
the class SegmentPropagator method processPeers.
private static void processPeers(SegmentMemory sourceSegment, TupleSets<LeftTuple> leftTuples, InternalWorkingMemory wm) {
SegmentMemory firstSmem = sourceSegment.getFirst();
// Process Deletes
processPeerDeletes(leftTuples, leftTuples.getDeleteFirst(), firstSmem, wm);
processPeerDeletes(leftTuples, leftTuples.getNormalizedDeleteFirst(), firstSmem, wm);
// Process Updates
for (LeftTuple leftTuple = leftTuples.getUpdateFirst(); leftTuple != null; leftTuple = leftTuple.getStagedNext()) {
SegmentMemory smem = firstSmem.getNext();
if (smem != null) {
for (LeftTuple peer = leftTuple.getPeer(); peer != null; peer = peer.getPeer()) {
// only stage, if not already staged, if insert, leave as insert
if (peer.getStagedType() == LeftTuple.NONE) {
peer.setPropagationContext(leftTuple.getPropagationContext());
smem.getStagedLeftTuples().addUpdate(peer);
}
smem = smem.getNext();
}
}
}
// Process Inserts
for (LeftTuple leftTuple = leftTuples.getInsertFirst(); leftTuple != null; leftTuple = leftTuple.getStagedNext()) {
SegmentMemory smem = firstSmem.getNext();
if (smem != null) {
LeftTuple peer = leftTuple;
for (; smem != null; smem = smem.getNext()) {
if (peer.getPeer() != null) {
// if the tuple already has a peer avoid to create a new one ...
peer = peer.getPeer();
peer.setPropagationContext(leftTuple.getPropagationContext());
// ... and update the staged LeftTupleSets according to its current staged state
PhreakJoinNode.updateChildLeftTuple(peer, smem.getStagedLeftTuples(), smem.getStagedLeftTuples());
} else {
peer = ((LeftTupleSink) smem.getRootNode()).createPeer(peer);
smem.getStagedLeftTuples().addInsert(peer);
if (smem.hasDataDrivenPathMemories()) {
for (PathMemory dataDrivenPmem : smem.getDataDrivenPathMemories()) {
// on insert only totally linked pmems need to be flushed
if (dataDrivenPmem.isRuleLinked()) {
forceFlushLeftTuple(dataDrivenPmem, smem, wm, smem.getStagedLeftTuples());
break;
}
}
}
}
}
}
}
firstSmem.getStagedLeftTuples().addAll(leftTuples);
leftTuples.resetAll();
}
use of org.drools.core.reteoo.LeftTuple in project drools by kiegroup.
the class SegmentPropagator method processPeerDeletes.
private static void processPeerDeletes(TupleSets<LeftTuple> leftTuples, LeftTuple leftTuple, SegmentMemory firstSmem, InternalWorkingMemory wm) {
for (; leftTuple != null; leftTuple = leftTuple.getStagedNext()) {
SegmentMemory smem = firstSmem.getNext();
if (smem != null) {
for (LeftTuple peer = leftTuple.getPeer(); peer != null; peer = peer.getPeer()) {
peer.setPropagationContext(leftTuple.getPropagationContext());
TupleSets<LeftTuple> stagedLeftTuples = smem.getStagedLeftTuples();
// if the peer is already staged as insert or update the LeftTupleSets will reconcile it internally
stagedLeftTuples.addDelete(peer);
if (smem.hasDataDrivenPathMemories()) {
forceFlushLeftTuple(smem.getFirstDataDrivenPathMemory(), smem, wm, smem.getStagedLeftTuples());
}
smem = smem.getNext();
}
}
}
}
Aggregations