use of org.drools.core.reteoo.AccumulateNode.AccumulateMemory in project drools by kiegroup.
the class RuleNetworkEvaluator method doRiaNode2.
private void doRiaNode2(InternalWorkingMemory wm, TupleSets<LeftTuple> srcTuples, RightInputAdapterNode riaNode) {
ObjectSink[] sinks = riaNode.getObjectSinkPropagator().getSinks();
BetaNode betaNode = (BetaNode) sinks[0];
BetaMemory bm;
Memory nodeMem = wm.getNodeMemory(betaNode);
if (NodeTypeEnums.AccumulateNode == betaNode.getType()) {
bm = ((AccumulateMemory) nodeMem).getBetaMemory();
} else {
bm = (BetaMemory) nodeMem;
}
TupleSets<RightTuple> rightTuples = bm.getStagedRightTuples();
// Build up iteration array for other sinks
BetaNode[] bns = null;
BetaMemory[] bms = null;
int length = sinks.length;
if (length > 1) {
bns = new BetaNode[sinks.length - 1];
bms = new BetaMemory[sinks.length - 1];
for (int i = 1; i < length; i++) {
bns[i - 1] = (BetaNode) sinks[i];
Memory nodeMem2 = wm.getNodeMemory(bns[i - 1]);
if (NodeTypeEnums.AccumulateNode == betaNode.getType()) {
bms[i - 1] = ((AccumulateMemory) nodeMem2).getBetaMemory();
} else {
bms[i - 1] = (BetaMemory) nodeMem2;
}
}
}
// subtract one, as first is not in the array;
length--;
for (SubnetworkTuple subnetworkTuple = (SubnetworkTuple) srcTuples.getInsertFirst(); subnetworkTuple != null; ) {
SubnetworkTuple next = (SubnetworkTuple) subnetworkTuple.getStagedNext();
if (bm.getStagedRightTuples().isEmpty()) {
bm.setNodeDirtyWithoutNotify();
}
subnetworkTuple.prepareStagingOnRight();
rightTuples.addInsert(subnetworkTuple);
if (bns != null) {
for (int i = 0; i < length; i++) {
if (bms[i].getStagedRightTuples().isEmpty()) {
bms[i].setNodeDirtyWithoutNotify();
}
subnetworkTuple = riaNode.createPeer(subnetworkTuple);
bms[i].getStagedRightTuples().addInsert(subnetworkTuple);
}
}
subnetworkTuple = next;
}
for (SubnetworkTuple subnetworkTuple = (SubnetworkTuple) srcTuples.getDeleteFirst(); subnetworkTuple != null; ) {
SubnetworkTuple next = (SubnetworkTuple) subnetworkTuple.getStagedNext();
if (rightTuples.isEmpty()) {
bm.setNodeDirtyWithoutNotify();
}
switch(subnetworkTuple.getStagedTypeOnRight()) {
// handle clash with already staged entries
case Tuple.INSERT:
rightTuples.removeInsert(subnetworkTuple);
break;
case Tuple.UPDATE:
rightTuples.removeUpdate(subnetworkTuple);
break;
}
subnetworkTuple.prepareStagingOnRight();
rightTuples.addDelete(subnetworkTuple);
if (bns != null) {
for (int i = 0; i < length; i++) {
subnetworkTuple = (SubnetworkTuple) subnetworkTuple.getPeer();
if (bms[i].getStagedRightTuples().isEmpty()) {
bms[i].setNodeDirtyWithoutNotify();
}
bms[i].getStagedRightTuples().addDelete(subnetworkTuple);
subnetworkTuple.setStagedOnRight();
}
}
subnetworkTuple = next;
}
for (SubnetworkTuple subnetworkTuple = (SubnetworkTuple) srcTuples.getUpdateFirst(); subnetworkTuple != null; ) {
SubnetworkTuple next = (SubnetworkTuple) subnetworkTuple.getStagedNext();
if (rightTuples.isEmpty()) {
bm.setNodeDirtyWithoutNotify();
}
subnetworkTuple.prepareStagingOnRight();
rightTuples.addUpdate(subnetworkTuple);
if (bns != null) {
for (int i = 0; i < length; i++) {
subnetworkTuple = (SubnetworkTuple) subnetworkTuple.getPeer();
if (bms[i].getStagedRightTuples().isEmpty()) {
bms[i].setNodeDirtyWithoutNotify();
}
bms[i].getStagedRightTuples().addUpdate(subnetworkTuple);
subnetworkTuple.setStagedOnRight();
}
}
subnetworkTuple = next;
}
srcTuples.resetAll();
}
use of org.drools.core.reteoo.AccumulateNode.AccumulateMemory in project drools by kiegroup.
the class RuleNetworkEvaluator method evalBetaNode.
private boolean evalBetaNode(PathMemory pmem, NetworkNode node, Memory nodeMem, SegmentMemory[] smems, int smemIndex, TupleSets<LeftTuple> trgTuples, InternalAgenda agenda, LinkedList<StackEntry> stack, boolean processRian, RuleExecutor executor, TupleSets<LeftTuple> srcTuples, TupleSets<LeftTuple> stagedLeftTuples, LeftTupleSinkNode sink) {
BetaNode betaNode = (BetaNode) node;
BetaMemory bm;
AccumulateMemory am = null;
if (NodeTypeEnums.AccumulateNode == node.getType()) {
am = (AccumulateMemory) nodeMem;
bm = am.getBetaMemory();
} else {
bm = (BetaMemory) nodeMem;
}
if (processRian && betaNode.isRightInputIsRiaNode()) {
// if the subnetwork is nested in this segment, it will create srcTuples containing
// peer LeftTuples, suitable for the node in the main path.
doRiaNode(agenda, pmem, srcTuples, betaNode, sink, smems, smemIndex, nodeMem, bm, stack, executor);
// return here, doRiaNode queues the evaluation on the stack, which is necessary to handled nested query nodes
return true;
}
switchOnDoBetaNode(node, trgTuples, agenda.getWorkingMemory(), srcTuples, stagedLeftTuples, sink, bm, am);
return false;
}
use of org.drools.core.reteoo.AccumulateNode.AccumulateMemory in project drools by kiegroup.
the class ProtobufOutputMarshaller method writeAccumulateNodeMemory.
private static ProtobufMessages.NodeMemory writeAccumulateNodeMemory(final int nodeId, final Memory memory) {
// for accumulate nodes, we need to store the ID of created (result) handles
AccumulateMemory accmem = (AccumulateMemory) memory;
if (accmem.getBetaMemory().getLeftTupleMemory().size() > 0) {
ProtobufMessages.NodeMemory.AccumulateNodeMemory.Builder _accumulate = ProtobufMessages.NodeMemory.AccumulateNodeMemory.newBuilder();
final org.drools.core.util.Iterator<LeftTuple> tupleIter = accmem.getBetaMemory().getLeftTupleMemory().iterator();
for (LeftTuple leftTuple = tupleIter.next(); leftTuple != null; leftTuple = tupleIter.next()) {
AccumulateContext accctx = (AccumulateContext) leftTuple.getContextObject();
if (accctx.getResultFactHandle() != null) {
FactHandle _handle = ProtobufMessages.FactHandle.newBuilder().setId(accctx.getResultFactHandle().getId()).setRecency(accctx.getResultFactHandle().getRecency()).build();
_accumulate.addContext(ProtobufMessages.NodeMemory.AccumulateNodeMemory.AccumulateContext.newBuilder().setTuple(PersisterHelper.createTuple(leftTuple)).setResultHandle(_handle).build());
}
}
return ProtobufMessages.NodeMemory.newBuilder().setNodeId(nodeId).setNodeType(ProtobufMessages.NodeMemory.NodeType.ACCUMULATE).setAccumulate(_accumulate.build()).build();
}
return null;
}
use of org.drools.core.reteoo.AccumulateNode.AccumulateMemory in project drools by kiegroup.
the class LeftTupleIterator method getNextLeftTuple.
public LeftTuple getNextLeftTuple(LeftTupleSource source, LeftTupleSink sink, LeftTuple leftTuple, InternalWorkingMemory wm) {
if (otnIterator != null) {
LeftTuple leftParent = leftTuple.getLeftParent();
while (leftTuple != null) {
leftTuple = leftTuple.getHandleNext();
for (; leftTuple != null; leftTuple = leftTuple.getHandleNext()) {
// Iterate to find the next left tuple for this sink, skip tuples for other sinks due to sharing split
if (leftTuple.getTupleSink() == sink) {
return leftTuple;
}
}
}
// We have a parent LeftTuple so try there next
if (leftParent != null) {
// we know it has to be evalNode query element node
while (leftParent != null) {
leftParent = getNextLeftTuple(source.getLeftTupleSource(), (LeftTupleSink) source, leftParent, wm);
if (leftParent != null) {
for (leftTuple = leftParent.getFirstChild(); leftTuple != null; leftTuple = leftTuple.getHandleNext()) {
if (leftTuple.getTupleSink() == sink) {
return leftTuple;
}
}
}
}
return null;
}
// We have exhausted the current FactHandle, now try the next
while (otnIterator.hasNext()) {
InternalFactHandle handle = otnIterator.next();
leftTuple = handle.findFirstLeftTuple(lt -> lt.getTupleSink() == sink);
if (leftTuple != null) {
return leftTuple;
}
}
// We've exhausted this OTN so set the iterator to null
otnIterator = null;
} else if (source instanceof AccumulateNode) {
// when using phreak, accumulate result tuples will not link to leftParent, but to parent instead
BetaMemory memory = ((AccumulateMemory) wm.getNodeMemory((MemoryFactory) source)).getBetaMemory();
FastIterator localIt = memory.getLeftTupleMemory().fullFastIterator(leftTuple.getParent());
LeftTuple childLeftTuple = leftTuple;
leftTuple = childLeftTuple.getParent();
while (leftTuple != null) {
if (childLeftTuple == null) {
childLeftTuple = leftTuple.getFirstChild();
} else {
childLeftTuple = childLeftTuple.getHandleNext();
}
for (; childLeftTuple != null; childLeftTuple = childLeftTuple.getHandleNext()) {
if (childLeftTuple.getTupleSink() == sink) {
return childLeftTuple;
}
}
leftTuple = (LeftTuple) localIt.next(leftTuple);
}
} else if (source instanceof JoinNode || source instanceof NotNode || source instanceof FromNode || source instanceof AccumulateNode) {
BetaMemory memory;
FastIterator localIt;
if (source instanceof FromNode) {
memory = ((FromMemory) wm.getNodeMemory((MemoryFactory) source)).getBetaMemory();
} else if (source instanceof AccumulateNode) {
memory = ((AccumulateMemory) wm.getNodeMemory((MemoryFactory) source)).getBetaMemory();
} else {
memory = (BetaMemory) wm.getNodeMemory((MemoryFactory) source);
}
localIt = memory.getLeftTupleMemory().fullFastIterator(leftTuple.getLeftParent());
LeftTuple childLeftTuple = leftTuple;
leftTuple = childLeftTuple.getLeftParent();
while (leftTuple != null) {
if (childLeftTuple == null) {
childLeftTuple = leftTuple.getFirstChild();
} else {
childLeftTuple = childLeftTuple.getHandleNext();
}
for (; childLeftTuple != null; childLeftTuple = childLeftTuple.getHandleNext()) {
if (childLeftTuple.getTupleSink() == sink) {
return childLeftTuple;
}
}
leftTuple = (LeftTuple) localIt.next(leftTuple);
}
}
if (source instanceof ExistsNode) {
BetaMemory memory = (BetaMemory) wm.getNodeMemory((MemoryFactory) source);
RightTuple rightTuple = leftTuple.getLeftParent().getBlocker();
FastIterator localIt = memory.getRightTupleMemory().fullFastIterator(rightTuple);
for (LeftTuple childleftTuple = leftTuple.getHandleNext(); childleftTuple != null; childleftTuple = childleftTuple.getHandleNext()) {
if (childleftTuple.getTupleSink() == sink) {
return childleftTuple;
}
}
leftTuple = leftTuple.getLeftParent();
// now move onto next RightTuple
while (rightTuple != null) {
if (rightTuple.getBlocked() != null) {
if (leftTuple != null) {
leftTuple = leftTuple.getBlockedNext();
} else {
leftTuple = rightTuple.getBlocked();
}
for (; leftTuple != null; leftTuple = leftTuple.getBlockedNext()) {
for (LeftTuple childleftTuple = leftTuple.getFirstChild(); childleftTuple != null; childleftTuple = childleftTuple.getHandleNext()) {
if (childleftTuple.getTupleSink() == sink) {
return childleftTuple;
}
}
}
}
rightTuple = (RightTuple) localIt.next(rightTuple);
}
} else if (source instanceof EvalConditionNode || source instanceof QueryElementNode) {
LeftTuple childLeftTuple = leftTuple;
if (leftTuple != null) {
leftTuple = leftTuple.getLeftParent();
while (leftTuple != null) {
if (childLeftTuple != null) {
childLeftTuple = childLeftTuple.getHandleNext();
} else {
childLeftTuple = leftTuple.getFirstChild();
}
for (; childLeftTuple != null; childLeftTuple = childLeftTuple.getHandleNext()) {
if (childLeftTuple.getTupleSink() == sink) {
return childLeftTuple;
}
}
if (source instanceof EvalConditionNode) {
leftTuple = getNextLeftTuple(source.getLeftTupleSource(), (LeftTupleSink) source, leftTuple, wm);
} else {
leftTuple = getNextLeftTuple(source.getLeftTupleSource(), (LeftTupleSink) source, leftTuple, wm);
}
}
}
}
return null;
}
use of org.drools.core.reteoo.AccumulateNode.AccumulateMemory in project drools by kiegroup.
the class PhreakActivationIterator method processLeftTuples.
public static void processLeftTuples(LeftTupleSource node, List<AgendaItem> agendaItems, Set<RuleTerminalNode> nodeSet, InternalWorkingMemory wm) {
LeftTupleSource node1 = node;
while (NodeTypeEnums.LeftInputAdapterNode != node1.getType()) {
node1 = node1.getLeftTupleSource();
}
int maxShareCount = node1.getAssociationsSize();
while (NodeTypeEnums.LeftInputAdapterNode != node.getType()) {
Memory memory = wm.getNodeMemory((MemoryFactory) node);
if (memory.getSegmentMemory() == null) {
// segment has never been initialized, which means the rule has never been linked.
return;
}
if (node.getAssociationsSize() == maxShareCount) {
// the recurse must start from the first split node, otherwise we get partial overlaps in propagations
if (NodeTypeEnums.isBetaNode(node)) {
BetaMemory bm;
if (NodeTypeEnums.AccumulateNode == node.getType()) {
AccumulateMemory am = (AccumulateMemory) memory;
bm = am.getBetaMemory();
FastIterator it = bm.getLeftTupleMemory().fullFastIterator();
Tuple lt = BetaNode.getFirstTuple(bm.getLeftTupleMemory(), it);
for (; lt != null; lt = (LeftTuple) it.next(lt)) {
AccumulateContext accctx = (AccumulateContext) lt.getContextObject();
collectFromPeers(accctx.getResultLeftTuple(), agendaItems, nodeSet, wm);
}
} else if (NodeTypeEnums.ExistsNode == node.getType()) {
bm = (BetaMemory) wm.getNodeMemory((MemoryFactory) node);
// done off the RightTupleMemory, as exists only have unblocked tuples on the left side
FastIterator it = bm.getRightTupleMemory().fullFastIterator();
RightTuple rt = (RightTuple) BetaNode.getFirstTuple(bm.getRightTupleMemory(), it);
for (; rt != null; rt = (RightTuple) it.next(rt)) {
for (LeftTuple lt = rt.getBlocked(); lt != null; lt = lt.getBlockedNext()) {
if (lt.getFirstChild() != null) {
collectFromPeers(lt.getFirstChild(), agendaItems, nodeSet, wm);
}
}
}
} else {
bm = (BetaMemory) wm.getNodeMemory((MemoryFactory) node);
FastIterator it = bm.getLeftTupleMemory().fullFastIterator();
Tuple lt = BetaNode.getFirstTuple(bm.getLeftTupleMemory(), it);
for (; lt != null; lt = (LeftTuple) it.next(lt)) {
if (lt.getFirstChild() != null) {
collectFromLeftInput(lt.getFirstChild(), agendaItems, nodeSet, wm);
}
}
}
return;
} else if (NodeTypeEnums.FromNode == node.getType()) {
FromMemory fm = (FromMemory) wm.getNodeMemory((MemoryFactory) node);
TupleMemory ltm = fm.getBetaMemory().getLeftTupleMemory();
FastIterator it = ltm.fullFastIterator();
for (LeftTuple lt = (LeftTuple) ltm.getFirst(null); lt != null; lt = (LeftTuple) it.next(lt)) {
if (lt.getFirstChild() != null) {
collectFromLeftInput(lt.getFirstChild(), agendaItems, nodeSet, wm);
}
}
return;
}
}
node = node.getLeftTupleSource();
}
// No beta or from nodes, so must retrieve LeftTuples from the LiaNode.
// This is done by scanning all the LeftTuples referenced from the FactHandles in the ObjectTypeNode
LeftInputAdapterNode lian = (LeftInputAdapterNode) node;
Memory memory = wm.getNodeMemory((MemoryFactory) node);
if (memory.getSegmentMemory() == null) {
// segment has never been initialized, which means the rule has never been linked.
return;
}
ObjectSource os = lian.getObjectSource();
while (os.getType() != NodeTypeEnums.ObjectTypeNode) {
os = os.getParentObjectSource();
}
ObjectTypeNode otn = (ObjectTypeNode) os;
final ObjectTypeNodeMemory omem = wm.getNodeMemory(otn);
LeftTupleSink firstLiaSink = lian.getSinkPropagator().getFirstLeftTupleSink();
java.util.Iterator<InternalFactHandle> it = omem.iterator();
while (it.hasNext()) {
InternalFactHandle fh = it.next();
fh.forEachLeftTuple(lt -> {
if (lt.getTupleSink() == firstLiaSink) {
collectFromLeftInput(lt, agendaItems, nodeSet, wm);
}
});
}
}
Aggregations