/** * Foreground thread blocking operation that retrieves the next read-ahead buffer. * Lazy initiation of read-ahead is performed if required. * @return next decompressed block in input stream */ private DecompressedBlock nextBlockSync() { ensureReadAhead(); DecompressedBlock nextBlock; try { nextBlock = mResult.take(); } catch (InterruptedException e) { return new DecompressedBlock(0, 0, e); } ensureReadAhead(); return nextBlock; } private class AsyncBlockCompressedInputStreamRunnable implements Runnable {
@Override protected void prepareForSeek() { flushReadAhead(); super.prepareForSeek(); }
@Override protected DecompressedBlock nextBlock(byte[] bufferAvailableForReuse) { if (bufferAvailableForReuse != null) { freeBuffers.offer(bufferAvailableForReuse); } return nextBlockSync(); }
/** * Prepare to read BAM from a file (seekable) * @param file source of bytes. * @param indexFile BAM index file * @param eagerDecode if true, decode all BAM fields as reading rather than lazily. * @param useAsynchronousIO if true, use asynchronous I/O * @param validationStringency Controls how to handle invalidate reads or header lines. * @param samRecordFactory SAM record factory * @param inflaterFactory InflaterFactory used by BlockCompressedInputStream * @throws IOException */ BAMFileReader(final File file, final File indexFile, final boolean eagerDecode, final boolean useAsynchronousIO, final ValidationStringency validationStringency, final SAMRecordFactory samRecordFactory, final InflaterFactory inflaterFactory) throws IOException { this(useAsynchronousIO ? new AsyncBlockCompressedInputStream(file, inflaterFactory) : new BlockCompressedInputStream(file, inflaterFactory), indexFile!=null ? indexFile : SamFiles.findIndex(file), eagerDecode, useAsynchronousIO, file.getAbsolutePath(), validationStringency, samRecordFactory); if (mIndexFile != null && mIndexFile.lastModified() < file.lastModified()) { System.err.println("WARNING: BAM index file " + mIndexFile.getAbsolutePath() + " is older than BAM " + file.getAbsolutePath()); } // Provide better error message when there is an error reading. mStream.setInputFileName(file.getAbsolutePath()); }
/** * Ensures that a read-ahead task for this stream exists in the thread pool. */ private void ensureReadAhead() { if (running.tryAcquire()) { tryQueueTask(); } } /**
/** * Thread pool operation that fills the read-ahead queue */ @Override public void run() { final DecompressedBlock decompressed = processNextBlock(freeBuffers.poll()); if (!mResult.offer(decompressed)) { // offer should never block since we never queue a task when the results buffer is full running.release(); // safety release to ensure foreground close() does not block indefinitely throw new IllegalStateException("Decompression buffer full"); } tryQueueTask(); } }
@Override public Tuple<CompressionBlock, Integer> performReadAhead(int bufferBudget) throws IOException { byte[] compressedBuffer = mFreeCompressedBlockBuffers.poll(); if (compressedBuffer == null) { compressedBuffer = new byte[BlockCompressedStreamConstants.MAX_COMPRESSED_BLOCK_SIZE]; } CompressionBlock block = readNextBlock(compressedBuffer); if (block != null) { // since the buffer we allocate is BlockCompressedStreamConstants.MAX_COMPRESSED_BLOCK_SIZE // we use this as the consumed size as opposed to the actual size block.getBlockCompressedSize() return new Tuple<>(block, BlockCompressedStreamConstants.MAX_COMPRESSED_BLOCK_SIZE); } return null; }
/** * Prepare to read BAM from a file (seekable) * @param file source of bytes. * @param indexFile BAM index file * @param eagerDecode if true, decode all BAM fields as reading rather than lazily. * @param useAsynchronousIO if true, use asynchronous I/O * @param validationStringency Controls how to handle invalidate reads or header lines. * @param samRecordFactory SAM record factory * @param inflaterFactory InflaterFactory used by BlockCompressedInputStream * @throws IOException */ BAMFileReader(final File file, final File indexFile, final boolean eagerDecode, final boolean useAsynchronousIO, final ValidationStringency validationStringency, final SAMRecordFactory samRecordFactory, final InflaterFactory inflaterFactory) throws IOException { this(useAsynchronousIO ? new AsyncBlockCompressedInputStream(file, inflaterFactory) : new BlockCompressedInputStream(file, inflaterFactory), indexFile!=null ? indexFile : SamFiles.findIndex(file), eagerDecode, useAsynchronousIO, file.getAbsolutePath(), validationStringency, samRecordFactory); if (mIndexFile != null && mIndexFile.lastModified() < file.lastModified()) { System.err.println("WARNING: BAM index file " + mIndexFile.getAbsolutePath() + " is older than BAM " + file.getAbsolutePath()); } // Provide better error message when there is an error reading. mStream.setInputFileName(file.getAbsolutePath()); }
/** * Ensures that a read-ahead task for this stream exists in the thread pool. */ private void ensureReadAhead() { if (running.tryAcquire()) { tryQueueTask(); } } /**
/** * Thread pool operation that fills the read-ahead queue */ @Override public void run() { final DecompressedBlock decompressed = processNextBlock(freeBuffers.poll()); if (!mResult.offer(decompressed)) { // offer should never block since we never queue a task when the results buffer is full running.release(); // safety release to ensure foreground close() does not block indefinitely throw new IllegalStateException("Decompression buffer full"); } tryQueueTask(); } }
/** * Prepare to read BAM from a file (seekable) * @param file source of bytes. * @param indexFile BAM index file * @param eagerDecode if true, decode all BAM fields as reading rather than lazily. * @param useAsynchronousIO if true, use asynchronous I/O * @param validationStringency Controls how to handle invalidate reads or header lines. * @param samRecordFactory SAM record factory * @param inflaterFactory InflaterFactory used by BlockCompressedInputStream * @throws IOException */ BAMFileReader(final File file, final File indexFile, final boolean eagerDecode, final boolean useAsynchronousIO, final ValidationStringency validationStringency, final SAMRecordFactory samRecordFactory, final InflaterFactory inflaterFactory) throws IOException { this(useAsynchronousIO ? new AsyncBlockCompressedInputStream(file, inflaterFactory) : new BlockCompressedInputStream(file, inflaterFactory), indexFile!=null ? indexFile : SamFiles.findIndex(file), eagerDecode, useAsynchronousIO, file.getAbsolutePath(), validationStringency, samRecordFactory); if (mIndexFile != null && mIndexFile.lastModified() < file.lastModified()) { System.err.println("WARNING: BAM index file " + mIndexFile.getAbsolutePath() + " is older than BAM " + file.getAbsolutePath()); } // Provide better error message when there is an error reading. mStream.setInputFileName(file.getAbsolutePath()); }
@Override protected void prepareForSeek() { flushReadAhead(); super.prepareForSeek(); }
/** * Foreground thread blocking operation that retrieves the next read-ahead buffer. * Lazy initiation of read-ahead is performed if required. * @return next decompressed block in input stream */ private DecompressedBlock nextBlockSync() { ensureReadAhead(); DecompressedBlock nextBlock; try { nextBlock = mResult.take(); } catch (InterruptedException e) { return new DecompressedBlock(0, 0, e); } ensureReadAhead(); return nextBlock; } private class AsyncBlockCompressedInputStreamRunnable implements Runnable {
@Override protected DecompressedBlock nextBlock(byte[] bufferAvailableForReuse) { if (bufferAvailableForReuse != null) { freeBuffers.offer(bufferAvailableForReuse); } return nextBlockSync(); }
/** * Prepare to read BAM from a stream (seekable) * @param strm source of bytes * @param indexStream BAM index stream * @param eagerDecode if true, decode all BAM fields as reading rather than lazily. * @param useAsynchronousIO if true, use asynchronous I/O * @param validationStringency Controls how to handle invalidate reads or header lines. * @param samRecordFactory SAM record factory * @param inflaterFactory InflaterFactory used by BlockCompressedInputStream * @throws IOException */ BAMFileReader(final SeekableStream strm, final SeekableStream indexStream, final boolean eagerDecode, final boolean useAsynchronousIO, final ValidationStringency validationStringency, final SAMRecordFactory samRecordFactory, final InflaterFactory inflaterFactory) throws IOException { this(useAsynchronousIO ? new AsyncBlockCompressedInputStream(strm, inflaterFactory) : new BlockCompressedInputStream(strm, inflaterFactory), indexStream, eagerDecode, useAsynchronousIO, strm.getSource(), validationStringency, samRecordFactory); }
@Override public void close() throws IOException { // Suppress interrupts while we close. final boolean isInterrupted = Thread.interrupted(); mAbort = true; try { flushReadAhead(); super.close(); } finally { if (isInterrupted) Thread.currentThread().interrupt(); } } /**
ensureReadAhead(); return; } else {
/** * Prepare to read BAM from a stream (seekable) * @param strm source of bytes * @param indexFile BAM index file * @param eagerDecode if true, decode all BAM fields as reading rather than lazily. * @param useAsynchronousIO if true, use asynchronous I/O * @param validationStringency Controls how to handle invalidate reads or header lines. * @param samRecordFactory SAM record factory * @param inflaterFactory InflaterFactory used by BlockCompressedInputStream * @throws IOException */ BAMFileReader(final SeekableStream strm, final File indexFile, final boolean eagerDecode, final boolean useAsynchronousIO, final ValidationStringency validationStringency, final SAMRecordFactory samRecordFactory, final InflaterFactory inflaterFactory) throws IOException { this(useAsynchronousIO ? new AsyncBlockCompressedInputStream(strm, inflaterFactory) : new BlockCompressedInputStream(strm, inflaterFactory), indexFile, eagerDecode, useAsynchronousIO, strm.getSource(), validationStringency, samRecordFactory); }
@Override public void close() throws IOException { // Suppress interrupts while we close. final boolean isInterrupted = Thread.interrupted(); mAbort = true; try { flushReadAhead(); super.close(); } finally { if (isInterrupted) Thread.currentThread().interrupt(); } } /**
ensureReadAhead(); return; } else {