protected void advanceSubIterator() { try { if (mCurrentOffset < mOffsets.size()) { if (mOffsets.start(mCurrentOffset) != mPreviousVirtualOffsetStart) { // Diagnostic.developerLog("After region " + mCurrentOffset + " " + mCurrentRegion + ", // opening new reader at offset " + // VirtualOffsets.offsetToString(mOffsets.start(mCurrentOffset)) + " for region " + // mOffsets.region(mCurrentOffset)); mReader.seek(mOffsets.start(mCurrentOffset)); mBuffered = false; // } else { // Diagnostic.developerLog("After region " + mCurrentOffset + " " + mCurrentRegion + ", // re-using existing reader for region " + mOffsets.region(mCurrentOffset)); } mCurrentRegion = mOffsets.region(mCurrentOffset); final int newTemplate = mSequenceLookup.get(mCurrentRegion.getSequenceName()); if (newTemplate != mCurrentTemplate) { mPreviousAlignmentStart = Integer.MIN_VALUE; } mPreviousVirtualOffsetStart = mOffsets.start(mCurrentOffset); mCurrentTemplate = newTemplate; } mCurrentOffset++; } catch (IOException e) { throw new RuntimeIOException(e.getMessage(), e); } }
private void populateNext(boolean force) throws IOException { final int previousStart = mNextAlignmentStart; final int previousTemplateId = mNextTemplateId; mNextRecord = null; if (force) { advanceSubIterator(); } while (mCurrentOffset <= mOffsets.size()) { if (!mBuffered && !mReader .hasNext()) { // Only happens when stream is exhausted, so effectively just closes // things out. advanceSubIterator(); } else { if (mBuffered) { mBuffered = false; } else { mReader.next(); } final String refName = mReader.getReferenceName(); final Integer refId = mSequenceLookup.get( refName); // Note that we cannot rely on mReader.getReferenceId in this scenario, // as that is built up incrementally if (refId == null) { throw new IOException( "Tabixed input contained a sequence name not found in the corresponding index: " + refName); } if (refId > mCurrentTemplate) { // current offset has exceeded region and block overlapped next // template mBuffered = true; advanceSubIterator(); } else { if (refId < mCurrentTemplate) { // Current block may occasionally return records from the // previous template if the block overlaps // Diagnostic.developerLog("Ignoring record from earlier template at " + // mReader.getReferenceName() + ":" + (mReader.getStartPosition() + 1) + " (" + refId // + "<" + mCurrentTemplate + ")"); continue; } final int alignmentStart = mReader.getStartPosition(); final int alignmentEnd = alignmentStart + mReader.getLengthOnReference(); if (alignmentEnd <= mCurrentRegion.getStart()) { // before region // Diagnostic.developerLog("Ignoring record from earlier than start at " + // mReader.getReferenceName() + ":" + (mReader.getStartPosition() + 1)); continue; } if (alignmentStart <= mPreviousAlignmentStart) { // this record would have been already returned by an // earlier region // Diagnostic.developerLog("Ignoring record from earlier block at " + // mReader.getReferenceName() + ":" + (alignmentStart + 1)); mDoubleFetched++; if (mDoubleFetched % 100000 == 0) { Diagnostic.developerLog( "Many double-fetched records noticed at " + mReader.getReferenceName() + ":" + (alignmentStart + 1) + " in region " + mCurrentRegion + " (skipping through to " + mPreviousAlignmentStart + ")"); } continue; } if (alignmentStart >= mCurrentRegion .getEnd()) { // past current region, advance the iterator and record the // furtherest we got if (previousStart != Integer.MIN_VALUE && previousTemplateId == mCurrentTemplate) { mPreviousAlignmentStart = previousStart; } else { mPreviousAlignmentStart = Integer.MIN_VALUE; } mBuffered = true; advanceSubIterator(); continue; } mNextRecord = mReader.getRecord(); mNextTemplateId = mCurrentTemplate; mNextAlignmentStart = alignmentStart; break; } } } }