From af5a443e5aba985a89a3507ea924a0035aefa2a5 Mon Sep 17 00:00:00 2001 From: aaron Date: Mon, 6 Apr 2009 21:17:11 +0000 Subject: [PATCH] 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 --- .../iterators/MergingSamRecordIterator2.java | 46 +++++-- .../gatk/iterators/ReferenceIterator.java | 118 ++++++++++-------- 2 files changed, 98 insertions(+), 66 deletions(-) diff --git a/java/src/org/broadinstitute/sting/gatk/iterators/MergingSamRecordIterator2.java b/java/src/org/broadinstitute/sting/gatk/iterators/MergingSamRecordIterator2.java index db89da9e1..fcf467676 100644 --- a/java/src/org/broadinstitute/sting/gatk/iterators/MergingSamRecordIterator2.java +++ b/java/src/org/broadinstitute/sting/gatk/iterators/MergingSamRecordIterator2.java @@ -50,8 +50,8 @@ public class MergingSamRecordIterator2 implements Iterator { 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 ); + if (this.sortOrder != SAMFileHeader.SortOrder.unsorted && reader.getFileHeader().getSortOrder() != 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); @@ -59,18 +59,41 @@ public class MergingSamRecordIterator2 implements Iterator { } } + /** + * 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() { this.pq = new PriorityQueue(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 final SAMRecordComparator comparator = getComparator(); for (final SAMFileReader reader : samHeaderMerger.getReaders()) { - Iterator recordIter = reader.queryOverlapping( contig, start, stop); + Iterator recordIter = reader.queryOverlapping(contig, start, stop); final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, recordIter, comparator); addIfNotEmpty(iterator); } @@ -80,7 +103,7 @@ public class MergingSamRecordIterator2 implements Iterator { initializePQ(); // reinitialize the system final SAMRecordComparator comparator = getComparator(); for (final SAMFileReader reader : samHeaderMerger.getReaders()) { - Iterator recordIter = reader.query( contig, start, stop, contained); + Iterator recordIter = reader.query(contig, start, stop, contained); final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, recordIter, comparator); addIfNotEmpty(iterator); } @@ -90,19 +113,19 @@ public class MergingSamRecordIterator2 implements Iterator { initializePQ(); // reinitialize the system final SAMRecordComparator comparator = getComparator(); for (final SAMFileReader reader : samHeaderMerger.getReaders()) { - Iterator recordIter = reader.queryContained( contig, start, stop ); + Iterator recordIter = reader.queryContained(contig, start, stop); final ComparableSamRecordIterator iterator = new ComparableSamRecordIterator(reader, recordIter, comparator); addIfNotEmpty(iterator); } } /** Returns true if any of the underlying iterators has more records, otherwise false. */ - public boolean hasNext() { + public synchronized boolean hasNext() { return !this.pq.isEmpty(); } /** 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 SAMRecord record = iterator.next(); addIfNotEmpty(iterator); @@ -131,8 +154,7 @@ public class MergingSamRecordIterator2 implements Iterator { //System.out.printf("Adding %s %s %d%n", iterator.peek().getReadName(), iterator.peek().getReferenceName(), iterator.peek().getAlignmentStart()); if (iterator.hasNext()) { pq.offer(iterator); - } - else { + } else { iterator.close(); } } @@ -196,7 +218,7 @@ class ComparableSamRecordIterator extends PeekableIterator implements * able to compare itself to other ComparableSAMRecordIterator instances using * 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 */ public ComparableSamRecordIterator(final SAMFileReader sam, final Comparator comparator) { diff --git a/java/src/org/broadinstitute/sting/gatk/iterators/ReferenceIterator.java b/java/src/org/broadinstitute/sting/gatk/iterators/ReferenceIterator.java index 7f0b7a42e..fcb708e23 100755 --- a/java/src/org/broadinstitute/sting/gatk/iterators/ReferenceIterator.java +++ b/java/src/org/broadinstitute/sting/gatk/iterators/ReferenceIterator.java @@ -1,17 +1,14 @@ package org.broadinstitute.sting.gatk.iterators; -import edu.mit.broad.picard.reference.ReferenceSequenceFile; import edu.mit.broad.picard.reference.ReferenceSequence; -import net.sf.samtools.util.StringUtil; 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.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. @@ -32,61 +29,74 @@ public class ReferenceIterator implements Iterator { //private ReferenceSequence nextContig = null; private long offset = -1; - public ReferenceIterator( FastaSequenceFile2 refFile ) { + public ReferenceIterator(FastaSequenceFile2 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); + // -------------------------------------------------------------------------------------------------------------- // // Accessing data // // -------------------------------------------------------------------------------------------------------------- - public byte getBaseAsByte() { return currentContig.getBases()[(int)offset]; } - public String getBaseAsString() { - assert offset > -1 : currentContig.getName() + " index is " + offset; - //assert offset < currentContig.getBases().(); - - return StringUtil.bytesToString(currentContig.getBases(), (int)offset, 1); + public byte getBaseAsByte() { + return currentContig.getBases()[(int) offset]; } - 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 String getBaseAsString() { + 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()); + } + // -------------------------------------------------------------------------------------------------------------- // // Iterator routines // // -------------------------------------------------------------------------------------------------------------- - public boolean hasNext() { - if ( currentContig == null || offset + 1 < currentContig.length() ) { + public synchronized boolean hasNext() { + if (currentContig == null || offset + 1 < currentContig.length()) { return true; - } - else { + } else { return readNextContig(); } } - public ReferenceIterator next() { - if ( currentContig != null ) { - if ( DEBUG ) logger.debug(String.format(" -> %s:%d %d%n", currentContig.getName(), offset, currentContig.length())); + public synchronized ReferenceIterator next() { + if (currentContig != null) { + if (DEBUG) + logger.debug(String.format(" -> %s:%d %d%n", currentContig.getName(), offset, currentContig.length())); } 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 - if ( readNextContig() ){ + if (readNextContig()) { // We sucessfully loaded the next contig, recursively call next return next(); - } - else { + } else { throw new NoSuchElementException(); } - } - else { + } else { // We're good to go -- we're in the current contig return this; } @@ -96,7 +106,7 @@ public class ReferenceIterator implements Iterator { throw new UnsupportedOperationException(); } - + // -------------------------------------------------------------------------------------------------------------- // // Jumping forward @@ -104,7 +114,7 @@ public class ReferenceIterator implements Iterator { // -------------------------------------------------------------------------------------------------------------- public ReferenceIterator seekForward(final GenomeLoc loc) { assert loc != null : "seekForward location is null"; - + return seekForwardOffset(loc.getContig(), loc.getStart() - 1); } @@ -115,25 +125,24 @@ public class ReferenceIterator implements Iterator { /** * Helper routine that doesn't move the contigs around, it just checks that everything is kosher in the seek * within this chromosome + * * @param seekContigName name for printing pursues, asserted to be the current contig name - * @param seekOffset where we want to be in this contig - * @return this setup to be at seekoffset within seekContigName + * @param seekOffset where we want to be in this contig + * @return this setup to be at seekoffset within seekContigName */ 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); // we're somewhere on this contig - if ( seekOffset < offset ) { + if (seekOffset < offset) { // 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", 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 throw new IllegalArgumentException(String.format("Invalid seek to %s, which is beyond the end of the contig%n", - new GenomeLoc(currentContig.getName(), seekOffset+1))); - } - else { + new GenomeLoc(currentContig.getName(), seekOffset + 1))); + } else { offset = seekOffset - 1; return next(); } @@ -145,23 +154,24 @@ public class ReferenceIterator implements Iterator { assert seekOffset >= 0 : "seekOffset < 0: " + seekOffset; // jumps us forward in the sequence to the contig / pos - if ( currentContig == null ) + if (currentContig == null) 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()); - 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 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))); - } - else if ( cmpContigs == 1 ) { + } else if (cmpContigs == 1) { // 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 throw new RuntimeIOException(String.format("Unexpected seek failure from %s to %s%n", new GenomeLoc(currentContig.getName(), offset), new GenomeLoc(currentContig.getName(), seekOffset))); @@ -171,7 +181,7 @@ public class ReferenceIterator implements Iterator { } // 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); } @@ -189,7 +199,7 @@ public class ReferenceIterator implements Iterator { /** * Simple forwarding method to the refFile itself - * + * * @return */ public String nextContigName() {