private static TupleSets<LeftTuple> getTargetStagedLeftTuples( NetworkNode node, InternalWorkingMemory wm, SegmentMemory smem) { if (node == smem.getTipNode()) { // we are about to process the segment tip, allow it to merge insert/update/delete clashes if (smem.isEmpty()) { SegmentUtilities.createChildSegments( wm, smem, ((LeftTupleSource) node).getSinkPropagator()); } return smem.getFirst().getStagedLeftTuples().takeAll(); } else { return null; } }
public void innerEval( LeftInputAdapterNode liaNode, PathMemory pmem, NetworkNode node, long bit, Memory nodeMem, SegmentMemory[] smems, int smemIndex, TupleSets<LeftTuple> trgTuples, InternalWorkingMemory wm, LinkedList<StackEntry> stack, boolean processRian, RuleExecutor executor) { TupleSets<LeftTuple> srcTuples; SegmentMemory smem = smems[smemIndex]; TupleSets<LeftTuple> stagedLeftTuples = null; while (true) { srcTuples = trgTuples; // previous target, is now the source 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); } // this is needed for subnetworks that feed into a parent network that has no right // inputs, // and may not yet be initialized if (smem.isEmpty() && !NodeTypeEnums.isTerminalNode(smem.getTipNode())) { SegmentUtilities.createChildSegments( wm, 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); } bit = bit << 1; // shift to check the next node node = ((LeftTupleSource) node).getSinkPropagator().getFirstLeftTupleSink(); nodeMem = nodeMem.getNext(); } } if (NodeTypeEnums.isTerminalNode(node)) { TerminalNode rtn = (TerminalNode) node; if (node.getType() == NodeTypeEnums.QueryTerminalNode) { pQtNode.doNode((QueryTerminalNode) rtn, wm, srcTuples, stack); } else { pRtNode.doNode(rtn, wm, srcTuples, executor); } break; } else if (NodeTypeEnums.RightInputAdaterNode == node.getType()) { doRiaNode2(wm, srcTuples, (RightInputAdapterNode) node); break; } stagedLeftTuples = getTargetStagedLeftTuples(node, wm, smem); LeftTupleSinkNode sink = ((LeftTupleSource) node).getSinkPropagator().getFirstLeftTupleSink(); trgTuples = evalNode( liaNode, pmem, node, bit, nodeMem, smems, smemIndex, wm, stack, processRian, executor, srcTuples, smem, stagedLeftTuples, sink); if (trgTuples == null) { break; // Queries exists and has been placed StackEntry, and there are no current trgTuples // to process } 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. smem.getFirst().getStagedLeftTuples().addAll(stagedLeftTuples); // must put back all the LTs // end of SegmentMemory, so we know that stagedLeftTuples is not null SegmentPropagator.propagate(smem, trgTuples, wm); 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(); } processRian = true; // make sure it's reset, so ria nodes are processed } if (stagedLeftTuples != null && !stagedLeftTuples.isEmpty()) { smem.getFirst().getStagedLeftTuples().addAll(stagedLeftTuples); // must put back all the LTs } }