Base-packed reader cleanup.

git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@1847 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
hanna 2009-10-15 01:26:23 +00:00
parent 316b30ee56
commit 8dca236958
1 changed files with 36 additions and 19 deletions

View File

@ -5,6 +5,7 @@ import org.broadinstitute.sting.utils.StingException;
import java.io.*; import java.io.*;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/** /**
* Reads a packed version of the input stream. * Reads a packed version of the input stream.
@ -21,30 +22,45 @@ public class BasePackedInputStream<T> {
/** /**
* Ultimate source for packed bases. * Ultimate source for packed bases.
*/ */
private final InputStream targetInputStream; private final FileInputStream targetInputStream;
/**
* Channel source for packed bases.
*/
private final FileChannel targetInputChannel;
/** /**
* A fixed-size buffer for word-packed data. * A fixed-size buffer for word-packed data.
*/ */
private final ByteBuffer buffer; private final ByteOrder byteOrder;
/**
* How many bases are in a given packed word.
*/
private final int basesPerPackedWord = PackUtils.bitsInType(Integer.class)/PackUtils.BITS_PER_BASE;
/**
* How many bytes in an integer?
*/
private final int bytesPerInteger = PackUtils.bitsInType(Integer.class)/PackUtils.BITS_PER_BYTE;
public BasePackedInputStream( Class<T> type, File inputFile, ByteOrder byteOrder ) throws FileNotFoundException { public BasePackedInputStream( Class<T> type, File inputFile, ByteOrder byteOrder ) throws FileNotFoundException {
this(type,new BufferedInputStream(new FileInputStream(inputFile)),byteOrder); this(type,new FileInputStream(inputFile),byteOrder);
} }
public BasePackedInputStream( Class<T> type, InputStream inputStream, ByteOrder byteOrder ) { public BasePackedInputStream( Class<T> type, FileInputStream inputStream, ByteOrder byteOrder ) {
if( type != Integer.class ) if( type != Integer.class )
throw new StingException("Only bases packed into 32-bit words are currently supported by this input stream. Type specified: " + type.getName()); throw new StingException("Only bases packed into 32-bit words are currently supported by this input stream. Type specified: " + type.getName());
this.targetInputStream = inputStream;
this.type = type; this.type = type;
this.buffer = ByteBuffer.allocate(PackUtils.bitsInType(type)/ PackUtils.BITS_PER_BYTE).order(byteOrder); this.targetInputStream = inputStream;
this.targetInputChannel = inputStream.getChannel();
this.byteOrder = byteOrder;
} }
/** /**
* Read the entire contents of the input stream. * Read the entire contents of the input stream.
* @param bwt array into which bases should be read. * @param bwt array into which bases should be read.
* @return a byte array of the given length.
* @throws IOException if an I/O error occurs. * @throws IOException if an I/O error occurs.
*/ */
public void read(byte[] bwt) throws IOException { public void read(byte[] bwt) throws IOException {
@ -58,18 +74,19 @@ public class BasePackedInputStream<T> {
* @param length number of bases to read from the stream. * @param length number of bases to read from the stream.
* @throws IOException if an I/O error occurs. * @throws IOException if an I/O error occurs.
*/ */
public void read( byte[] bwt, int offset, int length ) throws IOException { public void read(byte[] bwt, int offset, int length) throws IOException {
int packedWord = 0; int bufferWidth = ((bwt.length+basesPerPackedWord-1)/basesPerPackedWord)*bytesPerInteger;
final int basesPerEntry = PackUtils.bitsInType(Integer.class)/PackUtils.BITS_PER_BASE; ByteBuffer buffer = ByteBuffer.allocate(bufferWidth).order(byteOrder);
for( int i = 0; i < length; i++ ) { targetInputChannel.read(buffer);
if( i % basesPerEntry == 0 ) { targetInputChannel.position(targetInputChannel.position()+buffer.remaining());
buffer.rewind(); buffer.flip();
targetInputStream.read(buffer.array());
packedWord = buffer.getInt();
}
int position = basesPerEntry - i % basesPerEntry - 1; int packedWord = 0;
bwt[i+offset] = PackUtils.unpackBase((byte)((packedWord >> position*PackUtils.BITS_PER_BASE) & 0x3)); int i = 0;
while(i < length) {
if(i % basesPerPackedWord == 0) packedWord = buffer.getInt();
int position = basesPerPackedWord - i%basesPerPackedWord - 1;
bwt[offset+i++] = PackUtils.unpackBase((byte)((packedWord >> position*PackUtils.BITS_PER_BASE) & 0x3));
} }
} }
} }