use of org.drools.core.common.Memory 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.common.Memory 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.common.Memory in project drools by kiegroup.
the class SegmentUtilities method createRiaSegmentMemory.
private static RightInputAdapterNode createRiaSegmentMemory(BetaNode betaNode, InternalWorkingMemory wm) {
RightInputAdapterNode riaNode = (RightInputAdapterNode) betaNode.getRightInput();
LeftTupleSource subnetworkLts = riaNode.getLeftTupleSource();
while (subnetworkLts.getLeftTupleSource() != riaNode.getStartTupleSource()) {
subnetworkLts = subnetworkLts.getLeftTupleSource();
}
Memory rootSubNetwokrMem = wm.getNodeMemory((MemoryFactory) subnetworkLts);
SegmentMemory subNetworkSegmentMemory = rootSubNetwokrMem.getSegmentMemory();
if (subNetworkSegmentMemory == null) {
// we need to stop recursion here
createSegmentMemory(subnetworkLts, rootSubNetwokrMem, wm);
}
return riaNode;
}
use of org.drools.core.common.Memory in project drools by kiegroup.
the class SegmentUtilities method createSegmentMemory.
public static SegmentMemory createSegmentMemory(LeftTupleSource tupleSource, Memory mem, InternalWorkingMemory wm) {
// find segment root
while (!SegmentUtilities.isRootNode(tupleSource, null)) {
tupleSource = tupleSource.getLeftTupleSource();
}
LeftTupleSource segmentRoot = tupleSource;
int nodeTypesInSegment = 0;
SegmentMemory smem = restoreSegmentFromPrototype(wm, segmentRoot, nodeTypesInSegment);
if (smem != null) {
if (NodeTypeEnums.isBetaNode(segmentRoot) && ((BetaNode) segmentRoot).isRightInputIsRiaNode()) {
createRiaSegmentMemory((BetaNode) segmentRoot, wm);
}
return smem;
}
smem = new SegmentMemory(segmentRoot);
// Iterate all nodes on the same segment, assigning their position as a bit mask value
// allLinkedTestMask is the resulting mask used to test if all nodes are linked in
long nodePosMask = 1;
long allLinkedTestMask = 0;
// nodes after a branch CE can notify, but they cannot impact linking
boolean updateNodeBit = true;
while (true) {
nodeTypesInSegment = updateNodeTypesMask(tupleSource, nodeTypesInSegment);
if (NodeTypeEnums.isBetaNode(tupleSource)) {
allLinkedTestMask = processBetaNode((BetaNode) tupleSource, wm, smem, nodePosMask, allLinkedTestMask, updateNodeBit);
} else {
switch(tupleSource.getType()) {
case NodeTypeEnums.LeftInputAdapterNode:
allLinkedTestMask = processLiaNode((LeftInputAdapterNode) tupleSource, wm, smem, nodePosMask, allLinkedTestMask);
break;
case NodeTypeEnums.EvalConditionNode:
processEvalNode((EvalConditionNode) tupleSource, wm, smem);
break;
case NodeTypeEnums.ConditionalBranchNode:
updateNodeBit = processBranchNode((ConditionalBranchNode) tupleSource, wm, smem);
break;
case NodeTypeEnums.FromNode:
processFromNode((FromNode) tupleSource, wm, smem);
break;
case NodeTypeEnums.ReactiveFromNode:
processReactiveFromNode((MemoryFactory) tupleSource, wm, smem, nodePosMask);
break;
case NodeTypeEnums.TimerConditionNode:
processTimerNode((TimerNode) tupleSource, wm, smem, nodePosMask);
break;
case NodeTypeEnums.QueryElementNode:
updateNodeBit = processQueryNode((QueryElementNode) tupleSource, wm, segmentRoot, smem, nodePosMask);
break;
}
}
nodePosMask = nodePosMask << 1;
if (tupleSource.getSinkPropagator().size() == 1) {
LeftTupleSinkNode sink = tupleSource.getSinkPropagator().getFirstLeftTupleSink();
if (NodeTypeEnums.isLeftTupleSource(sink)) {
tupleSource = (LeftTupleSource) sink;
} else {
// rtn or rian
// While not technically in a segment, we want to be able to iterate easily from the last node memory to the ria/rtn memory
// we don't use createNodeMemory, as these may already have been created by, but not added, by the method updateRiaAndTerminalMemory
Memory memory = wm.getNodeMemory((MemoryFactory) sink);
if (sink.getType() == NodeTypeEnums.RightInputAdaterNode) {
PathMemory riaPmem = ((RiaNodeMemory) memory).getRiaPathMemory();
smem.getNodeMemories().add(riaPmem);
RightInputAdapterNode rian = (RightInputAdapterNode) sink;
ObjectSink[] nodes = rian.getObjectSinkPropagator().getSinks();
for (ObjectSink node : nodes) {
if (NodeTypeEnums.isLeftTupleSource(node)) {
createSegmentMemory((LeftTupleSource) node, wm);
}
}
} else if (NodeTypeEnums.isTerminalNode(sink)) {
smem.getNodeMemories().add(memory);
}
memory.setSegmentMemory(smem);
smem.setTipNode(sink);
break;
}
} else {
// not in same segment
smem.setTipNode(tupleSource);
break;
}
}
smem.setAllLinkedMaskTest(allLinkedTestMask);
// iterate to find root and determine the SegmentNodes position in the RuleSegment
LeftTupleSource pathRoot = segmentRoot;
int ruleSegmentPosMask = 1;
int counter = 0;
while (pathRoot.getType() != NodeTypeEnums.LeftInputAdapterNode) {
LeftTupleSource leftTupleSource = pathRoot.getLeftTupleSource();
if (SegmentUtilities.isNonTerminalTipNode(leftTupleSource, null)) {
// for each new found segment, increase the mask bit position
ruleSegmentPosMask = ruleSegmentPosMask << 1;
counter++;
}
pathRoot = leftTupleSource;
}
smem.setSegmentPosMaskBit(ruleSegmentPosMask);
smem.setPos(counter);
nodeTypesInSegment = updateRiaAndTerminalMemory(tupleSource, tupleSource, smem, wm, false, nodeTypesInSegment);
((KnowledgeBaseImpl) wm.getKnowledgeBase()).registerSegmentPrototype(segmentRoot, smem);
return smem;
}
use of org.drools.core.common.Memory in project drools by kiegroup.
the class ProtobufOutputMarshaller method writeNodeMemories.
private static void writeNodeMemories(MarshallerWriteContext context, ProtobufMessages.RuleData.Builder _ksb) throws IOException {
InternalWorkingMemory wm = context.wm;
NodeMemories memories = wm.getNodeMemories();
// so we iterate over all of them and process only those that require it
for (BaseNode baseNode : context.sinks.values()) {
Memory memory = memories.peekNodeMemory(baseNode);
if (memory != null) {
ProtobufMessages.NodeMemory _node = null;
switch(memory.getNodeType()) {
case NodeTypeEnums.AccumulateNode:
{
_node = writeAccumulateNodeMemory(baseNode.getId(), memory);
break;
}
case NodeTypeEnums.RightInputAdaterNode:
{
_node = writeRIANodeMemory(baseNode.getId(), baseNode, memories);
break;
}
case NodeTypeEnums.FromNode:
case NodeTypeEnums.ReactiveFromNode:
{
_node = writeFromNodeMemory(baseNode.getId(), memory);
break;
}
case NodeTypeEnums.QueryElementNode:
{
_node = writeQueryElementNodeMemory(baseNode.getId(), memory, wm);
break;
}
}
if (_node != null) {
// not all node memories require serialization
_ksb.addNodeMemory(_node);
}
}
}
}
Aggregations