add Synchronized to the has_next and next methods

git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@301 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
aaron 2009-04-06 21:17:11 +00:00
parent 97d14abe85
commit af5a443e5a
2 changed files with 98 additions and 66 deletions

View File

@ -50,8 +50,8 @@ public class MergingSamRecordIterator2 implements Iterator<SAMRecord> {
final SAMRecordComparator comparator = getComparator(); final SAMRecordComparator comparator = getComparator();
for (final SAMFileReader reader : samHeaderMerger.getReaders()) { for (final SAMFileReader reader : samHeaderMerger.getReaders()) {
if (this.sortOrder != SAMFileHeader.SortOrder.unsorted && reader.getFileHeader().getSortOrder() != this.sortOrder){ if (this.sortOrder != SAMFileHeader.SortOrder.unsorted && reader.getFileHeader().getSortOrder() != this.sortOrder) {
throw new PicardException("Files are not compatible with sort order: " + this.sortOrder ); throw new PicardException("Files are not compatible with sort order: " + reader.getFileHeader().getSortOrder() + " vrs " + this.sortOrder);
} }
final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, comparator); final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, comparator);
@ -59,18 +59,41 @@ public class MergingSamRecordIterator2 implements Iterator<SAMRecord> {
} }
} }
/**
* Constructs a new merging iterator with the same set of readers and sort order as
* provided by the header merger parameter.
*/
public MergingSamRecordIterator2(MergingSamRecordIterator2 iter) {
this.samHeaderMerger = iter.samHeaderMerger;
this.sortOrder = iter.sortOrder;
initializePQ();
final SAMRecordComparator comparator = getComparator();
for (final SAMFileReader reader : samHeaderMerger.getReaders()) {
if (this.sortOrder != SAMFileHeader.SortOrder.unsorted && reader.getFileHeader().getSortOrder() != this.sortOrder) {
throw new PicardException("Files are not compatible with sort order: " + this.sortOrder);
}
final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, comparator);
addIfNotEmpty(iterator);
}
}
protected void initializePQ() { protected void initializePQ() {
this.pq = new PriorityQueue<ComparableSamRecordIterator>(samHeaderMerger.getReaders().size()); this.pq = new PriorityQueue<ComparableSamRecordIterator>(samHeaderMerger.getReaders().size());
} }
public boolean supportsSeeking() { return true; } public boolean supportsSeeking() {
return true;
}
public void queryOverlapping( final String contig, final int start, final int stop ) { public void queryOverlapping(final String contig, final int start, final int stop) {
initializePQ(); // reinitialize the system initializePQ(); // reinitialize the system
final SAMRecordComparator comparator = getComparator(); final SAMRecordComparator comparator = getComparator();
for (final SAMFileReader reader : samHeaderMerger.getReaders()) { for (final SAMFileReader reader : samHeaderMerger.getReaders()) {
Iterator<SAMRecord> recordIter = reader.queryOverlapping( contig, start, stop); Iterator<SAMRecord> recordIter = reader.queryOverlapping(contig, start, stop);
final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, recordIter, comparator); final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, recordIter, comparator);
addIfNotEmpty(iterator); addIfNotEmpty(iterator);
} }
@ -80,7 +103,7 @@ public class MergingSamRecordIterator2 implements Iterator<SAMRecord> {
initializePQ(); // reinitialize the system initializePQ(); // reinitialize the system
final SAMRecordComparator comparator = getComparator(); final SAMRecordComparator comparator = getComparator();
for (final SAMFileReader reader : samHeaderMerger.getReaders()) { for (final SAMFileReader reader : samHeaderMerger.getReaders()) {
Iterator<SAMRecord> recordIter = reader.query( contig, start, stop, contained); Iterator<SAMRecord> recordIter = reader.query(contig, start, stop, contained);
final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, recordIter, comparator); final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, recordIter, comparator);
addIfNotEmpty(iterator); addIfNotEmpty(iterator);
} }
@ -90,19 +113,19 @@ public class MergingSamRecordIterator2 implements Iterator<SAMRecord> {
initializePQ(); // reinitialize the system initializePQ(); // reinitialize the system
final SAMRecordComparator comparator = getComparator(); final SAMRecordComparator comparator = getComparator();
for (final SAMFileReader reader : samHeaderMerger.getReaders()) { for (final SAMFileReader reader : samHeaderMerger.getReaders()) {
Iterator<SAMRecord> recordIter = reader.queryContained( contig, start, stop ); Iterator<SAMRecord> recordIter = reader.queryContained(contig, start, stop);
final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, recordIter, comparator); final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, recordIter, comparator);
addIfNotEmpty(iterator); addIfNotEmpty(iterator);
} }
} }
/** Returns true if any of the underlying iterators has more records, otherwise false. */ /** Returns true if any of the underlying iterators has more records, otherwise false. */
public boolean hasNext() { public synchronized boolean hasNext() {
return !this.pq.isEmpty(); return !this.pq.isEmpty();
} }
/** Returns the next record from the top most iterator during merging. */ /** Returns the next record from the top most iterator during merging. */
public SAMRecord next() { public synchronized SAMRecord next() {
final ComparableSamRecordIterator iterator = this.pq.poll(); final ComparableSamRecordIterator iterator = this.pq.poll();
final SAMRecord record = iterator.next(); final SAMRecord record = iterator.next();
addIfNotEmpty(iterator); addIfNotEmpty(iterator);
@ -131,8 +154,7 @@ public class MergingSamRecordIterator2 implements Iterator<SAMRecord> {
//System.out.printf("Adding %s %s %d%n", iterator.peek().getReadName(), iterator.peek().getReferenceName(), iterator.peek().getAlignmentStart()); //System.out.printf("Adding %s %s %d%n", iterator.peek().getReadName(), iterator.peek().getReferenceName(), iterator.peek().getAlignmentStart());
if (iterator.hasNext()) { if (iterator.hasNext()) {
pq.offer(iterator); pq.offer(iterator);
} } else {
else {
iterator.close(); iterator.close();
} }
} }
@ -196,7 +218,7 @@ class ComparableSamRecordIterator extends PeekableIterator<SAMRecord> implements
* able to compare itself to other ComparableSAMRecordIterator instances using * able to compare itself to other ComparableSAMRecordIterator instances using
* the supplied comparator for ordering SAMRecords. * the supplied comparator for ordering SAMRecords.
* *
* @param sam the SAM file to read records from * @param sam the SAM file to read records from
* @param comparator the Comparator to use to provide ordering fo SAMRecords * @param comparator the Comparator to use to provide ordering fo SAMRecords
*/ */
public ComparableSamRecordIterator(final SAMFileReader sam, final Comparator<SAMRecord> comparator) { public ComparableSamRecordIterator(final SAMFileReader sam, final Comparator<SAMRecord> comparator) {

View File

@ -1,17 +1,14 @@
package org.broadinstitute.sting.gatk.iterators; package org.broadinstitute.sting.gatk.iterators;
import edu.mit.broad.picard.reference.ReferenceSequenceFile;
import edu.mit.broad.picard.reference.ReferenceSequence; import edu.mit.broad.picard.reference.ReferenceSequence;
import net.sf.samtools.util.StringUtil;
import net.sf.samtools.util.RuntimeIOException; import net.sf.samtools.util.RuntimeIOException;
import net.sf.samtools.util.StringUtil;
import org.apache.log4j.Logger;
import org.broadinstitute.sting.utils.FastaSequenceFile2;
import org.broadinstitute.sting.utils.GenomeLoc;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.io.IOException;
import org.broadinstitute.sting.utils.GenomeLoc;
import org.broadinstitute.sting.utils.FastaSequenceFile2;
import org.apache.log4j.Logger;
/** /**
* Created by IntelliJ IDEA. * Created by IntelliJ IDEA.
@ -32,61 +29,74 @@ public class ReferenceIterator implements Iterator<ReferenceIterator> {
//private ReferenceSequence nextContig = null; //private ReferenceSequence nextContig = null;
private long offset = -1; private long offset = -1;
public ReferenceIterator( FastaSequenceFile2 refFile ) { public ReferenceIterator(FastaSequenceFile2 refFile) {
this.refFile = refFile; this.refFile = refFile;
} }
/**
* our log, which we want to capture anything from this class /** our log, which we want to capture anything from this class */
*/
private static Logger logger = Logger.getLogger(ReferenceIterator.class); private static Logger logger = Logger.getLogger(ReferenceIterator.class);
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
// //
// Accessing data // Accessing data
// //
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
public byte getBaseAsByte() { return currentContig.getBases()[(int)offset]; } public byte getBaseAsByte() {
public String getBaseAsString() { return currentContig.getBases()[(int) offset];
assert offset > -1 : currentContig.getName() + " index is " + offset; }
//assert offset < currentContig.getBases().();
public String getBaseAsString() {
return StringUtil.bytesToString(currentContig.getBases(), (int)offset, 1); assert offset > -1 : currentContig.getName() + " index is " + offset;
//assert offset < currentContig.getBases().();
return StringUtil.bytesToString(currentContig.getBases(), (int) offset, 1);
}
public char getBaseAsChar() {
return getBaseAsString().charAt(0);
}
public ReferenceSequence getCurrentContig() {
return currentContig;
}
public long getPosition() {
return offset + 1;
}
public GenomeLoc getLocation() {
return new GenomeLoc(getCurrentContig().getName(), getPosition());
} }
public char getBaseAsChar() { return getBaseAsString().charAt(0); }
public ReferenceSequence getCurrentContig() { return currentContig; }
public long getPosition() { return offset + 1; }
public GenomeLoc getLocation() { return new GenomeLoc( getCurrentContig().getName(), getPosition() ); }
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
// //
// Iterator routines // Iterator routines
// //
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
public boolean hasNext() { public synchronized boolean hasNext() {
if ( currentContig == null || offset + 1 < currentContig.length() ) { if (currentContig == null || offset + 1 < currentContig.length()) {
return true; return true;
} } else {
else {
return readNextContig(); return readNextContig();
} }
} }
public ReferenceIterator next() { public synchronized ReferenceIterator next() {
if ( currentContig != null ) { if (currentContig != null) {
if ( DEBUG ) logger.debug(String.format(" -> %s:%d %d%n", currentContig.getName(), offset, currentContig.length())); if (DEBUG)
logger.debug(String.format(" -> %s:%d %d%n", currentContig.getName(), offset, currentContig.length()));
} }
offset++; // move on to the next position offset++; // move on to the next position
if ( currentContig == null || offset >= currentContig.length() ) { if (currentContig == null || offset >= currentContig.length()) {
// We need to update the contig // We need to update the contig
if ( readNextContig() ){ if (readNextContig()) {
// We sucessfully loaded the next contig, recursively call next // We sucessfully loaded the next contig, recursively call next
return next(); return next();
} } else {
else {
throw new NoSuchElementException(); throw new NoSuchElementException();
} }
} } else {
else {
// We're good to go -- we're in the current contig // We're good to go -- we're in the current contig
return this; return this;
} }
@ -115,25 +125,24 @@ public class ReferenceIterator implements Iterator<ReferenceIterator> {
/** /**
* Helper routine that doesn't move the contigs around, it just checks that everything is kosher in the seek * Helper routine that doesn't move the contigs around, it just checks that everything is kosher in the seek
* within this chromosome * within this chromosome
*
* @param seekContigName name for printing pursues, asserted to be the current contig name * @param seekContigName name for printing pursues, asserted to be the current contig name
* @param seekOffset where we want to be in this contig * @param seekOffset where we want to be in this contig
* @return this setup to be at seekoffset within seekContigName * @return this setup to be at seekoffset within seekContigName
*/ */
private ReferenceIterator seekForwardOffsetOnSameContig(final String seekContigName, final long seekOffset) { private ReferenceIterator seekForwardOffsetOnSameContig(final String seekContigName, final long seekOffset) {
assert seekContigName.equals(currentContig.getName()) : String.format("only works on this contig, but the current %s and sought %s contigs are different!", currentContig.getName(), seekContigName); assert seekContigName.equals(currentContig.getName()) : String.format("only works on this contig, but the current %s and sought %s contigs are different!", currentContig.getName(), seekContigName);
// we're somewhere on this contig // we're somewhere on this contig
if ( seekOffset < offset ) { if (seekOffset < offset) {
// bad boy -- can't go backward safely // bad boy -- can't go backward safely
throw new IllegalArgumentException(String.format("Invalid seek %s => %s, which is usually due to out of order reads%n", throw new IllegalArgumentException(String.format("Invalid seek %s => %s, which is usually due to out of order reads%n",
new GenomeLoc(currentContig.getName(), offset), new GenomeLoc(currentContig.getName(), seekOffset))); new GenomeLoc(currentContig.getName(), offset), new GenomeLoc(currentContig.getName(), seekOffset)));
} } else if (seekOffset >= currentContig.length()) {
else if ( seekOffset >= currentContig.length() ) {
// bad boy -- can't go beyond the contig length // bad boy -- can't go beyond the contig length
throw new IllegalArgumentException(String.format("Invalid seek to %s, which is beyond the end of the contig%n", throw new IllegalArgumentException(String.format("Invalid seek to %s, which is beyond the end of the contig%n",
new GenomeLoc(currentContig.getName(), seekOffset+1))); new GenomeLoc(currentContig.getName(), seekOffset + 1)));
} } else {
else {
offset = seekOffset - 1; offset = seekOffset - 1;
return next(); return next();
} }
@ -145,23 +154,24 @@ public class ReferenceIterator implements Iterator<ReferenceIterator> {
assert seekOffset >= 0 : "seekOffset < 0: " + seekOffset; assert seekOffset >= 0 : "seekOffset < 0: " + seekOffset;
// jumps us forward in the sequence to the contig / pos // jumps us forward in the sequence to the contig / pos
if ( currentContig == null ) if (currentContig == null)
next(); next();
if ( DEBUG ) logger.debug(String.format(" -> Seeking to %s %d from %s %d%n", seekContigName, seekOffset, currentContig.getName(), offset)); if (DEBUG)
logger.debug(String.format(" -> Seeking to %s %d from %s %d%n", seekContigName, seekOffset, currentContig.getName(), offset));
int cmpContigs = GenomeLoc.compareContigs(seekContigName, currentContig.getName()); int cmpContigs = GenomeLoc.compareContigs(seekContigName, currentContig.getName());
if ( cmpContigs == -1 && false ) { // todo: fixed if (cmpContigs == -1 && false) { // todo: fixed
// The contig we are looking for is before the currentContig -- it's an error // The contig we are looking for is before the currentContig -- it's an error
throw new IllegalArgumentException(String.format("Invalid seek %s => %s, which is usually due to out of order reads%n", throw new IllegalArgumentException(String.format("Invalid seek %s => %s, which is usually due to out of order reads%n",
new GenomeLoc(currentContig.getName(), offset), new GenomeLoc(currentContig.getName(), seekOffset))); new GenomeLoc(currentContig.getName(), offset), new GenomeLoc(currentContig.getName(), seekOffset)));
} } else if (cmpContigs == 1) {
else if ( cmpContigs == 1 ) {
// we need to jump forward // we need to jump forward
if ( DEBUG ) logger.debug(String.format(" -> Seeking in the fasta file to %s from %s%n", seekContigName, currentContig.getName())); if (DEBUG)
logger.debug(String.format(" -> Seeking in the fasta file to %s from %s%n", seekContigName, currentContig.getName()));
if ( ! refFile.seekToContig(seekContigName) ) { // ok, do the seek if (!refFile.seekToContig(seekContigName)) { // ok, do the seek
// a false result indicates a failure, throw a somewhat cryptic call // a false result indicates a failure, throw a somewhat cryptic call
throw new RuntimeIOException(String.format("Unexpected seek failure from %s to %s%n", throw new RuntimeIOException(String.format("Unexpected seek failure from %s to %s%n",
new GenomeLoc(currentContig.getName(), offset), new GenomeLoc(currentContig.getName(), seekOffset))); new GenomeLoc(currentContig.getName(), offset), new GenomeLoc(currentContig.getName(), seekOffset)));
@ -171,7 +181,7 @@ public class ReferenceIterator implements Iterator<ReferenceIterator> {
} }
// at this point, the current contig is seekContigName, so just do a bit more error checking and be done // at this point, the current contig is seekContigName, so just do a bit more error checking and be done
return seekForwardOffsetOnSameContig( seekContigName, seekOffset ); return seekForwardOffsetOnSameContig(seekContigName, seekOffset);
} }