Tribble/Tabix index path support #810
Merged
lbergelson
merged 9 commits into
samtools:master
from
magicDGS:dgs_tribble_path_support
Mar 10, 2017
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
4303b61
Some clean up
magicDGS f293192
Path support for tribble/tabix index
magicDGS 97084dd
Address some comments
magicDGS ce693cd
Breaks compatibility
magicDGS b12c9fa
Fix tabix index
magicDGS f2eda11
Address minor comments
magicDGS 572958a
Add test for write index into a Path
magicDGS 4d7dda3
Add a couple of missing ctor for Path
magicDGS a6ff57e
Small test to check if writing/ctor from a Path
magicDGS
Jump to file or symbol
Failed to load files and symbols.
| @@ -18,15 +18,19 @@ | ||
| package htsjdk.tribble.index; | ||
| +import htsjdk.samtools.util.IOUtil; | ||
| +import htsjdk.samtools.util.Log; | ||
| +import htsjdk.samtools.util.RuntimeIOException; | ||
| import htsjdk.tribble.Tribble; | ||
| import htsjdk.tribble.TribbleException; | ||
| import htsjdk.tribble.util.LittleEndianInputStream; | ||
| import htsjdk.tribble.util.LittleEndianOutputStream; | ||
| import java.io.BufferedOutputStream; | ||
| import java.io.File; | ||
| -import java.io.FileOutputStream; | ||
| import java.io.IOException; | ||
| +import java.nio.file.Files; | ||
| +import java.nio.file.Path; | ||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.LinkedHashMap; | ||
| @@ -67,11 +71,12 @@ | ||
| private final static long NO_TS = -1L; | ||
| protected int version; // Our version value | ||
| - protected File indexedFile = null; // The file we've created this index for | ||
| + protected Path indexedPath = null; // The file we've created this index for | ||
magicDGS
Contributor
|
||
| protected long indexedFileSize = NO_FILE_SIZE; // The size of the indexed file | ||
| protected long indexedFileTS = NO_TS; // The timestamp | ||
| protected String indexedFileMD5 = NO_MD5; // The MD5 value, generally not filled in (expensive to calc) | ||
| protected int flags; | ||
| + protected final Log logger = Log.getInstance(this.getClass()); | ||
| public boolean hasFileSize() { | ||
| return indexedFileSize != NO_FILE_SIZE; | ||
| @@ -116,8 +121,8 @@ public boolean equalsIgnoreProperties(final Object obj) { | ||
| return false; | ||
| } | ||
| - if (indexedFile != other.indexedFile && (indexedFile == null || !indexedFile.equals(other.indexedFile))) { | ||
| - System.err.printf("equals indexedFile: this %s != other %s%n", indexedFile, other.indexedFile); | ||
| + if (indexedPath != other.indexedPath && (indexedPath == null || !indexedPath.equals(other.indexedPath))) { | ||
| + System.err.printf("equals indexedPath: this %s != other %s%n", indexedPath, other.indexedPath); | ||
| return false; | ||
| } | ||
| @@ -159,18 +164,27 @@ public AbstractIndex() { | ||
| * @param featureFile the feature file to create an index from | ||
| */ | ||
| public AbstractIndex(final String featureFile) { | ||
| - this(new File(featureFile)); | ||
| + this(); | ||
| + try { | ||
| + this.indexedPath = IOUtil.getPath(featureFile).toAbsolutePath(); | ||
| + } catch (IOException e) { | ||
| + throw new IllegalArgumentException("IO error: " + e.getMessage(), e); | ||
| + } | ||
| } | ||
| public AbstractIndex(final File featureFile) { | ||
| + this(featureFile.toPath()); | ||
| + } | ||
| + | ||
| + public AbstractIndex(final Path featurePath) { | ||
| this(); | ||
| - this.indexedFile = featureFile; | ||
| + this.indexedPath = featurePath.toAbsolutePath(); | ||
| } | ||
| public AbstractIndex(final AbstractIndex parent) { | ||
| this(); | ||
| this.version = parent.version; | ||
| - this.indexedFile = parent.indexedFile; | ||
| + this.indexedPath = parent.indexedPath; | ||
| this.indexedFileSize = parent.indexedFileSize; | ||
| this.indexedFileTS = parent.indexedFileTS; | ||
| this.indexedFileMD5 = parent.indexedFileMD5; | ||
| @@ -200,8 +214,18 @@ public boolean isCurrentVersion() { | ||
| return version == VERSION; | ||
| } | ||
| + /** | ||
| + * Gets the indexed file. | ||
| + * @throws UnsupportedOperationException if the path cannot be represented as a file. | ||
| + * @deprecated on 03/2017. Use {@link #getIndexedPath()} instead. | ||
| + */ | ||
| + @Deprecated | ||
| public File getIndexedFile() { | ||
| - return indexedFile; | ||
| + return getIndexedPath().toFile(); | ||
| + } | ||
| + | ||
| + public Path getIndexedPath() { | ||
| + return indexedPath; | ||
| } | ||
| public long getIndexedFileSize() { | ||
| @@ -234,10 +258,14 @@ public boolean containsChromosome(final String chr) { | ||
| } | ||
| public void finalizeIndex() { | ||
| - // these two functions must be called now because the file may be being written during on the fly indexing | ||
| - if (indexedFile != null) { | ||
| - this.indexedFileSize = indexedFile.length(); | ||
| - this.indexedFileTS = indexedFile.lastModified(); | ||
| + try { | ||
| + // these two functions must be called now because the file may be being written during on the fly indexing | ||
| + if (indexedPath != null) { | ||
| + this.indexedFileSize = Files.size(indexedPath); | ||
| + this.indexedFileTS = Files.getLastModifiedTime(indexedPath).toMillis(); | ||
| + } | ||
| + } catch (IOException e) { | ||
| + throw new RuntimeIOException(e); | ||
| } | ||
| } | ||
| @@ -251,7 +279,7 @@ private void writeHeader(final LittleEndianOutputStream dos) throws IOException | ||
| dos.writeInt(MAGIC_NUMBER); | ||
| dos.writeInt(getType()); | ||
| dos.writeInt(version); | ||
| - dos.writeString(indexedFile.getAbsolutePath()); | ||
| + dos.writeString(indexedPath.toUri().toString()); | ||
| dos.writeLong(indexedFileSize); | ||
| dos.writeLong(indexedFileTS); | ||
| dos.writeString(indexedFileMD5); | ||
| @@ -274,7 +302,7 @@ private void writeHeader(final LittleEndianOutputStream dos) throws IOException | ||
| private void readHeader(final LittleEndianInputStream dis) throws IOException { | ||
| version = dis.readInt(); | ||
| - indexedFile = new File(dis.readString()); | ||
| + indexedPath = IOUtil.getPath(dis.readString()); | ||
| indexedFileSize = dis.readLong(); | ||
| indexedFileTS = dis.readLong(); | ||
| indexedFileMD5 = dis.readString(); | ||
| @@ -349,18 +377,22 @@ public void write(final LittleEndianOutputStream stream) throws IOException { | ||
| } | ||
| @Override | ||
| - public void write(final File idxFile) throws IOException { | ||
| - try(final LittleEndianOutputStream idxStream = new LittleEndianOutputStream(new BufferedOutputStream(new FileOutputStream(idxFile)))) { | ||
| + public void write(final Path idxPath) throws IOException { | ||
| + try(final LittleEndianOutputStream idxStream = new LittleEndianOutputStream(new BufferedOutputStream(Files.newOutputStream(idxPath)))) { | ||
| write(idxStream); | ||
| } | ||
| } | ||
| @Override | ||
| - public void writeBasedOnFeatureFile(final File featureFile) throws IOException { | ||
| - if (!featureFile.isFile()) return; | ||
| - write(Tribble.indexFile(featureFile)); | ||
| + public void writeBasedOnFeaturePath(final Path featurePath) throws IOException { | ||
| + if (!Files.isRegularFile(featurePath)) { | ||
| + logger.warn("Index not written into ", featurePath); | ||
| + return; | ||
| + } | ||
| + write(Tribble.indexPath(featurePath)); | ||
| } | ||
| + | ||
| public void read(final LittleEndianInputStream dis) throws IOException { | ||
| try { | ||
| readHeader(dis); | ||
| @@ -386,7 +418,7 @@ public void read(final LittleEndianInputStream dis) throws IOException { | ||
| } | ||
| protected void printIndexInfo() { | ||
| - System.out.println(String.format("Index for %s with %d indices", indexedFile, chrIndices.size())); | ||
| + System.out.println(String.format("Index for %s with %d indices", indexedPath, chrIndices.size())); | ||
| final BlockStats stats = getBlockStats(true); | ||
| System.out.println(String.format(" total blocks %d", stats.total)); | ||
| System.out.println(String.format(" total empty blocks %d", stats.empty)); | ||
Oops, something went wrong.
This is technically a breaking change. I'm going to say it's fine though. I don't believe there are any subclasses of AbstractIndex in the wild that we're going to be breaking.