while (tupleSource.getType() != NodeTypeEnums.LeftInputAdapterNode &&
SegmentUtilities.parentInSameSegment(tupleSource, null)) {
tupleSource = tupleSource.getLeftTupleSource();
}
LeftTupleSource segmentRoot = tupleSource;
smem = ((ReteooRuleBase)wm.getRuleBase()).getSegmentFromPrototype(wm, segmentRoot);
if ( smem != null ) {
// there is a prototype for this segment memory
for (NetworkNode node : smem.getNodesInSegment()) {
wm.getNodeMemory((MemoryFactory) node).setSegmentMemory(smem);
}
updateRiaAndTerminalMemory(segmentRoot, segmentRoot, smem, wm);
return smem;
}
List<PathMemory> pmems = new ArrayList<PathMemory>();
if (initRtn ) {
initialiseRtnMemory(segmentRoot, wm, pmems);
}
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;
boolean updateNodeBit = true; // nodes after a branch CE can notify, but they cannot impact linking
while (true) {
if ( tupleSource.isStreamMode() && smem.getTupleQueue() == null ) {
// need to make sure there is one Queue, for the rule, when a stream mode node is found.
if ( pmems.isEmpty() ) {
// pmems is empty, if initialiseRtnMemory was not previously called
initialiseRtnMemory(segmentRoot, wm, pmems);
}
smem.setTupleQueue( pmems.get(0).getQueue() );
}
if (NodeTypeEnums.isBetaNode(tupleSource)) {
allLinkedTestMask = processBetaNode(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.TimerConditionNode:
processTimerNode((TimerNode) tupleSource, wm, smem);
break;
case NodeTypeEnums.QueryElementNode:
processQueryNode((QueryElementNode) tupleSource, wm, segmentRoot, smem);
break;
}
}
nodePosMask = nodePosMask << 1;
if (tupleSource.getSinkPropagator().size() == 1) {
LeftTupleSinkNode sink = (LeftTupleSinkNode) 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) {
smem.getNodeMemories().add(((RiaNodeMemory)memory).getRiaPathMemory());
} else if (NodeTypeEnums.isTerminalNode(sink)) {
smem.getNodeMemories().add((PathMemory)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) {
if (!SegmentUtilities.parentInSameSegment(pathRoot, null)) {
// for each new found segment, increase the mask bit position
ruleSegmentPosMask = ruleSegmentPosMask << 1;
counter++;
}
pathRoot = pathRoot.getLeftTupleSource();
}
smem.setSegmentPosMaskBit(ruleSegmentPosMask);
smem.setPos(counter);
if (smem.getRootNode().getType() != NodeTypeEnums.LeftInputAdapterNode &&