Index: modules/facet/src/test/org/apache/lucene/util/SlowRAMDirectory.java =================================================================== --- modules/facet/src/test/org/apache/lucene/util/SlowRAMDirectory.java (revision 1197218) +++ modules/facet/src/test/org/apache/lucene/util/SlowRAMDirectory.java (working copy) @@ -1,14 +1,5 @@ package org.apache.lucene.util; -import java.io.IOException; -import java.util.Random; - -import org.apache.lucene.store.IOContext; -import org.apache.lucene.store.IndexInput; -import org.apache.lucene.store.IndexOutput; -import org.apache.lucene.store.RAMDirectory; -import org.apache.lucene.util.ThreadInterruptedException; - /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -26,6 +17,14 @@ * limitations under the License. */ +import java.io.IOException; +import java.util.Random; + +import org.apache.lucene.store.IOContext; +import org.apache.lucene.store.IndexInput; +import org.apache.lucene.store.IndexOutput; +import org.apache.lucene.store.RAMDirectory; + /** * Test utility - slow directory */ @@ -84,6 +83,7 @@ private int numRead = 0; public SlowIndexInput(IndexInput ii) { + super("SlowIndexInput(" + ii + ")"); this.ii = ii; } Index: lucene/contrib/misc/src/java/org/apache/lucene/store/WindowsDirectory.java =================================================================== --- lucene/contrib/misc/src/java/org/apache/lucene/store/WindowsDirectory.java (revision 1197218) +++ lucene/contrib/misc/src/java/org/apache/lucene/store/WindowsDirectory.java (working copy) @@ -19,6 +19,7 @@ import java.io.File; import java.io.IOException; +import java.io.EOFException; import org.apache.lucene.store.Directory; // javadoc import org.apache.lucene.store.NativeFSLockFactory; // javadoc @@ -80,7 +81,7 @@ boolean isOpen; public WindowsIndexInput(File file, int bufferSize) throws IOException { - super(bufferSize); + super("WindowsIndexInput(path=\"" + file.getPath() + "\")", bufferSize); fd = WindowsDirectory.open(file.getPath()); length = WindowsDirectory.length(fd); isOpen = true; @@ -88,8 +89,16 @@ @Override protected void readInternal(byte[] b, int offset, int length) throws IOException { - if (WindowsDirectory.read(fd, b, offset, length, getFilePointer()) != length) - throw new IOException("Read past EOF"); + int bytesRead; + try { + bytesRead = WindowsDirectory.read(fd, b, offset, length, getFilePointer()); + } catch (IOException ioe) { + throw new IOException(ioe.getMessage() + ": " + this, ioe); + } + + if (bytesRead != length) { + throw new EOFException("Read past EOF: " + this); + } } @Override Index: lucene/contrib/misc/src/java/org/apache/lucene/store/DirectIOLinuxDirectory.java =================================================================== --- lucene/contrib/misc/src/java/org/apache/lucene/store/DirectIOLinuxDirectory.java (revision 1197218) +++ lucene/contrib/misc/src/java/org/apache/lucene/store/DirectIOLinuxDirectory.java (working copy) @@ -245,6 +245,7 @@ public DirectIOLinuxIndexInput(File path, int bufferSize) throws IOException { // TODO make use of IOContext + super("DirectIOLinuxIndexInput(path=\"" + path.getPath() + "\")"); FileDescriptor fd = NativePosixUtil.open_direct(path.toString(), true); fis = new FileInputStream(fd); channel = fis.getChannel(); @@ -259,6 +260,7 @@ // for clone public DirectIOLinuxIndexInput(DirectIOLinuxIndexInput other) throws IOException { + super(other.toString()); this.fis = null; channel = other.channel; this.bufferSize = other.bufferSize; @@ -308,7 +310,7 @@ try { return channel.size(); } catch (IOException ioe) { - throw new RuntimeException(ioe); + throw new RuntimeException("IOException during length(): " + this, ioe); } } @@ -331,9 +333,14 @@ bufferPos = 0; assert (filePos & ALIGN_NOT_MASK) == filePos : "filePos=" + filePos + " anded=" + (filePos & ALIGN_NOT_MASK); //System.out.println("X refill filePos=" + filePos); - int n = channel.read(buffer, filePos); + int n; + try { + n = channel.read(buffer, filePos); + } catch (IOException ioe) { + throw new IOException(ioe.getMessage() + ": " + this, ioe); + } if (n < 0) { - throw new IOException("eof"); + throw new IOException("eof: " + this); } buffer.rewind(); } @@ -365,7 +372,7 @@ try { return new DirectIOLinuxIndexInput(this); } catch (IOException ioe) { - throw new RuntimeException(ioe); + throw new RuntimeException("IOException during clone: " + this, ioe); } } } Index: lucene/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java (revision 1197218) +++ lucene/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java (working copy) @@ -122,7 +122,7 @@ "31.optimized.nocfs", }; - /** This test checks that *only* IndexFormatTooOldExceptions are throws when you open and operate on too old indexes! */ + /** This test checks that *only* IndexFormatTooOldExceptions are thrown when you open and operate on too old indexes! */ public void testUnsupportedOldIndexes() throws Exception { for(int i=0;i FORMAT_MINIMUM) { - throw new IndexFormatTooOldException(fileName, format, FORMAT_MINIMUM, FORMAT_CURRENT); + throw new IndexFormatTooOldException(input, format, FORMAT_MINIMUM, FORMAT_CURRENT); } if (format < FORMAT_CURRENT) { - throw new IndexFormatTooNewException(fileName, format, FORMAT_MINIMUM, FORMAT_CURRENT); + throw new IndexFormatTooNewException(input, format, FORMAT_MINIMUM, FORMAT_CURRENT); } final int size = input.readVInt(); //read in the size Index: lucene/src/java/org/apache/lucene/index/IndexFormatTooOldException.java =================================================================== --- lucene/src/java/org/apache/lucene/index/IndexFormatTooOldException.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/index/IndexFormatTooOldException.java (working copy) @@ -17,21 +17,37 @@ package org.apache.lucene.index; +import org.apache.lucene.store.DataInput; +import org.apache.lucene.store.IndexInput; + /** * This exception is thrown when Lucene detects * an index that is too old for this Lucene version */ public class IndexFormatTooOldException extends CorruptIndexException { - public IndexFormatTooOldException(String filename, String version) { - super("Format version is not supported" + (filename!=null ? (" in file '" + filename + "'") : "") + - ": " + version + ". This version of Lucene only supports indexes created with release 3.0 and later."); + /** @lucene.internal */ + public IndexFormatTooOldException(String resourceDesc, String version) { + super("Format version is not supported (resource: " + resourceDesc + "): " + + version + ". This version of Lucene only supports indexes created with release 3.0 and later."); + assert resourceDesc != null; } + + /** @lucene.internal */ + public IndexFormatTooOldException(DataInput in, String version) { + this(in.toString(), version); + } - public IndexFormatTooOldException(String filename, int version, int minVersion, int maxVersion) { - super("Format version is not supported" + (filename!=null ? (" in file '" + filename + "'") : "") + - ": " + version + " (needs to be between " + minVersion + " and " + maxVersion + + /** @lucene.internal */ + public IndexFormatTooOldException(String resourceDesc, int version, int minVersion, int maxVersion) { + super("Format version is not supported (resource: " + resourceDesc + "): " + + version + " (needs to be between " + minVersion + " and " + maxVersion + "). This version of Lucene only supports indexes created with release 3.0 and later."); + assert resourceDesc != null; } + /** @lucene.internal */ + public IndexFormatTooOldException(DataInput in, int version, int minVersion, int maxVersion) { + this(in.toString(), version, minVersion, maxVersion); + } } Index: lucene/src/java/org/apache/lucene/index/IndexFormatTooNewException.java =================================================================== --- lucene/src/java/org/apache/lucene/index/IndexFormatTooNewException.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/index/IndexFormatTooNewException.java (working copy) @@ -17,15 +17,24 @@ package org.apache.lucene.index; +import org.apache.lucene.store.DataInput; + /** * This exception is thrown when Lucene detects * an index that is newer than this Lucene version. */ public class IndexFormatTooNewException extends CorruptIndexException { - public IndexFormatTooNewException(String filename, int version, int minVersion, int maxVersion) { - super("Format version is not supported" + (filename!=null ? (" in file '" + filename + "'") : "") + - ": " + version + " (needs to be between " + minVersion + " and " + maxVersion + ")"); + /** @lucene.internal */ + public IndexFormatTooNewException(String resourceDesc, int version, int minVersion, int maxVersion) { + super("Format version is not supported (resource: " + resourceDesc + "): " + + version + " (needs to be between " + minVersion + " and " + maxVersion + ")"); + assert resourceDesc != null; } + /** @lucene.internal */ + public IndexFormatTooNewException(DataInput in, int version, int minVersion, int maxVersion) { + this(in.toString(), version, minVersion, maxVersion); + } + } Index: lucene/src/java/org/apache/lucene/index/TermVectorsReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/TermVectorsReader.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/index/TermVectorsReader.java (working copy) @@ -17,12 +17,9 @@ * limitations under the License. */ -import org.apache.lucene.index.MergePolicy.OneMerge; -import org.apache.lucene.store.BufferedIndexInput; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexInput; -import org.apache.lucene.store.IOContext.Context; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; @@ -186,9 +183,9 @@ { int format = in.readInt(); if (format < FORMAT_MINIMUM) - throw new IndexFormatTooOldException(fn, format, FORMAT_MINIMUM, FORMAT_CURRENT); + throw new IndexFormatTooOldException(in, format, FORMAT_MINIMUM, FORMAT_CURRENT); if (format > FORMAT_CURRENT) - throw new IndexFormatTooNewException(fn, format, FORMAT_MINIMUM, FORMAT_CURRENT); + throw new IndexFormatTooNewException(in, format, FORMAT_MINIMUM, FORMAT_CURRENT); return format; } Index: lucene/src/java/org/apache/lucene/index/codecs/preflex/SegmentTermEnum.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/preflex/SegmentTermEnum.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/index/codecs/preflex/SegmentTermEnum.java (working copy) @@ -18,12 +18,13 @@ */ import java.io.IOException; -import org.apache.lucene.store.IndexInput; + +import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.FieldInfos; +import org.apache.lucene.index.IndexFormatTooNewException; +import org.apache.lucene.index.IndexFormatTooOldException; import org.apache.lucene.index.Term; -import org.apache.lucene.index.CorruptIndexException; -import org.apache.lucene.index.IndexFormatTooOldException; -import org.apache.lucene.index.IndexFormatTooNewException; +import org.apache.lucene.store.IndexInput; /** * @deprecated (4.0) No longer used with flex indexing, except for @@ -85,9 +86,9 @@ // check that it is a format we can understand if (format > FORMAT_MINIMUM) - throw new IndexFormatTooOldException(null, format, FORMAT_MINIMUM, FORMAT_CURRENT); + throw new IndexFormatTooOldException(input, format, FORMAT_MINIMUM, FORMAT_CURRENT); if (format < FORMAT_CURRENT) - throw new IndexFormatTooNewException(null, format, FORMAT_MINIMUM, FORMAT_CURRENT); + throw new IndexFormatTooNewException(input, format, FORMAT_MINIMUM, FORMAT_CURRENT); size = input.readLong(); // read the size Index: lucene/src/java/org/apache/lucene/index/codecs/MultiLevelSkipListReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/MultiLevelSkipListReader.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/index/codecs/MultiLevelSkipListReader.java (working copy) @@ -255,6 +255,7 @@ private int pos; SkipBuffer(IndexInput input, int length) throws IOException { + super("SkipBuffer on " + input); data = new byte[length]; pointer = input.getFilePointer(); input.readBytes(data, 0, length); Index: lucene/src/java/org/apache/lucene/index/codecs/DefaultSegmentInfosReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/DefaultSegmentInfosReader.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/index/codecs/DefaultSegmentInfosReader.java (working copy) @@ -48,10 +48,10 @@ // check that it is a format we can understand if (format > DefaultSegmentInfosWriter.FORMAT_MINIMUM) - throw new IndexFormatTooOldException(segmentsFileName, format, + throw new IndexFormatTooOldException(input, format, DefaultSegmentInfosWriter.FORMAT_MINIMUM, DefaultSegmentInfosWriter.FORMAT_CURRENT); if (format < DefaultSegmentInfosWriter.FORMAT_CURRENT) - throw new IndexFormatTooNewException(segmentsFileName, format, + throw new IndexFormatTooNewException(input, format, DefaultSegmentInfosWriter.FORMAT_MINIMUM, DefaultSegmentInfosWriter.FORMAT_CURRENT); infos.version = input.readLong(); // read version @@ -92,7 +92,7 @@ // If it's a 3x index touched by 3.1+ code, then segments record their // version, whether they are 2.x ones or not. We detect that and throw // appropriate exception. - throw new IndexFormatTooOldException(si.name, si.getVersion()); + throw new IndexFormatTooOldException(input, si.getVersion()); } infos.add(si); } Index: lucene/src/java/org/apache/lucene/index/codecs/DefaultFieldsReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/codecs/DefaultFieldsReader.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/index/codecs/DefaultFieldsReader.java (working copy) @@ -88,9 +88,9 @@ try { int format = idxStream.readInt(); if (format < DefaultFieldsWriter.FORMAT_MINIMUM) - throw new IndexFormatTooOldException(indexStreamFN, format, DefaultFieldsWriter.FORMAT_MINIMUM, DefaultFieldsWriter.FORMAT_CURRENT); + throw new IndexFormatTooOldException(idxStream, format, DefaultFieldsWriter.FORMAT_MINIMUM, DefaultFieldsWriter.FORMAT_CURRENT); if (format > DefaultFieldsWriter.FORMAT_CURRENT) - throw new IndexFormatTooNewException(indexStreamFN, format, DefaultFieldsWriter.FORMAT_MINIMUM, DefaultFieldsWriter.FORMAT_CURRENT); + throw new IndexFormatTooNewException(idxStream, format, DefaultFieldsWriter.FORMAT_MINIMUM, DefaultFieldsWriter.FORMAT_CURRENT); } finally { idxStream.close(); } @@ -128,9 +128,9 @@ format = cloneableIndexStream.readInt(); if (format < DefaultFieldsWriter.FORMAT_MINIMUM) - throw new IndexFormatTooOldException(indexStreamFN, format, DefaultFieldsWriter.FORMAT_MINIMUM, DefaultFieldsWriter.FORMAT_CURRENT); + throw new IndexFormatTooOldException(cloneableIndexStream, format, DefaultFieldsWriter.FORMAT_MINIMUM, DefaultFieldsWriter.FORMAT_CURRENT); if (format > DefaultFieldsWriter.FORMAT_CURRENT) - throw new IndexFormatTooNewException(indexStreamFN, format, DefaultFieldsWriter.FORMAT_MINIMUM, DefaultFieldsWriter.FORMAT_CURRENT); + throw new IndexFormatTooNewException(cloneableIndexStream, format, DefaultFieldsWriter.FORMAT_MINIMUM, DefaultFieldsWriter.FORMAT_CURRENT); fieldsStream = (IndexInput) cloneableFieldsStream.clone(); @@ -271,33 +271,4 @@ return fieldsStream; } - - /** - * Skip the field. We still have to read some of the information about the field, but can skip past the actual content. - * This will have the most payoff on large fields. - */ - private void skipField(int numeric) throws IOException { - final int numBytes; - switch(numeric) { - case 0: - numBytes = fieldsStream.readVInt(); - break; - case DefaultFieldsWriter.FIELD_IS_NUMERIC_INT: - case DefaultFieldsWriter.FIELD_IS_NUMERIC_FLOAT: - numBytes = 4; - break; - case DefaultFieldsWriter.FIELD_IS_NUMERIC_LONG: - case DefaultFieldsWriter.FIELD_IS_NUMERIC_DOUBLE: - numBytes = 8; - break; - default: - throw new FieldReaderException("Invalid numeric type: " + Integer.toHexString(numeric)); - } - - skipFieldBytes(numBytes); - } - - private void skipFieldBytes(int toRead) throws IOException { - fieldsStream.seek(fieldsStream.getFilePointer() + toRead); - } } Index: lucene/src/java/org/apache/lucene/store/NIOFSDirectory.java =================================================================== --- lucene/src/java/org/apache/lucene/store/NIOFSDirectory.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/store/NIOFSDirectory.java (working copy) @@ -83,8 +83,8 @@ public IndexInputSlicer createSlicer(final String name, final IOContext context) throws IOException { ensureOpen(); - final File file = new File(getDirectory(), name); - final Descriptor descriptor = new Descriptor(file, "r"); + final File path = new File(getDirectory(), name); + final Descriptor descriptor = new Descriptor(path, "r"); return new Directory.IndexInputSlicer() { @Override @@ -93,14 +93,14 @@ } @Override - public IndexInput openSlice(long offset, long length) throws IOException { - return new NIOFSIndexInput(descriptor, descriptor.getChannel(), offset, + public IndexInput openSlice(String sliceDescription, long offset, long length) throws IOException { + return new NIOFSIndexInput(sliceDescription, path, descriptor, descriptor.getChannel(), offset, length, BufferedIndexInput.bufferSize(context), getReadChunkSize()); } @Override public IndexInput openFullSlice() throws IOException { - return openSlice(0, descriptor.length); + return openSlice("full-slice", 0, descriptor.length); } }; } @@ -115,12 +115,12 @@ final FileChannel channel; public NIOFSIndexInput(File path, IOContext context, int chunkSize) throws IOException { - super(path, context, chunkSize); + super("NIOFSIndexInput(path=\"" + path + "\")", path, context, chunkSize); channel = file.getChannel(); } - public NIOFSIndexInput(Descriptor file, FileChannel fc, long off, long length, int bufferSize, int chunkSize) throws IOException { - super(file, off, length, bufferSize, chunkSize); + public NIOFSIndexInput(String sliceDescription, File path, Descriptor file, FileChannel fc, long off, long length, int bufferSize, int chunkSize) throws IOException { + super("NIOFSIndexInput(" + sliceDescription + " in path=\"" + path + "\" slice=" + off + ":" + (off+length) + ")", file, off, length, bufferSize, chunkSize); channel = fc; isClone = true; } @@ -181,7 +181,7 @@ long pos = getFilePointer() + off; if (pos + len > end) { - throw new IOException("read past EOF"); + throw new IOException("read past EOF: " + this); } try { @@ -209,6 +209,8 @@ + "with a value smaller than the current chunk size (" + chunkSize + ")"); outOfMemoryError.initCause(e); throw outOfMemoryError; + } catch (IOException ioe) { + throw new IOException(ioe.getMessage() + ": " + this, ioe); } } } Index: lucene/src/java/org/apache/lucene/store/CompoundFileDirectory.java =================================================================== --- lucene/src/java/org/apache/lucene/store/CompoundFileDirectory.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/store/CompoundFileDirectory.java (working copy) @@ -213,7 +213,7 @@ if (entry == null) { throw new IOException("No sub-file with id " + id + " found (fileName=" + name + " files: " + entries.keySet() + ")"); } - return handle.openSlice(entry.offset, entry.length); + return handle.openSlice(name, entry.offset, entry.length); } /** Returns an array of strings, one for each file in the directory. */ @@ -313,13 +313,13 @@ } @Override - public IndexInput openSlice(long offset, long length) throws IOException { - return handle.openSlice(entry.offset + offset, length); + public IndexInput openSlice(String sliceDescription, long offset, long length) throws IOException { + return handle.openSlice(sliceDescription, entry.offset + offset, length); } @Override public IndexInput openFullSlice() throws IOException { - return openSlice(0, entry.length); + return openSlice("full-slice", 0, entry.length); } }; } Index: lucene/src/java/org/apache/lucene/store/MMapDirectory.java =================================================================== --- lucene/src/java/org/apache/lucene/store/MMapDirectory.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/store/MMapDirectory.java (working copy) @@ -213,7 +213,7 @@ File f = new File(getDirectory(), name); RandomAccessFile raf = new RandomAccessFile(f, "r"); try { - return new MMapIndexInput(raf, 0, raf.length(), chunkSizePower); + return new MMapIndexInput("MMapIndexInput(path=\"" + f + "\")", raf, 0, raf.length(), chunkSizePower); } finally { raf.close(); } @@ -221,7 +221,7 @@ public IndexInputSlicer createSlicer(final String name, final IOContext context) throws IOException { ensureOpen(); - File f = new File(getDirectory(), name); + final File f = new File(getDirectory(), name); final RandomAccessFile raf = new RandomAccessFile(f, "r"); return new IndexInputSlicer() { @Override @@ -230,13 +230,13 @@ } @Override - public IndexInput openSlice(long offset, long length) throws IOException { - return new MMapIndexInput(raf, offset, length, chunkSizePower); + public IndexInput openSlice(String sliceDescription, long offset, long length) throws IOException { + return new MMapIndexInput("MMapIndexInput(" + sliceDescription + " in path=\"" + f + "\" slice=" + offset + ":" + (offset+length) + ")", raf, offset, length, chunkSizePower); } @Override public IndexInput openFullSlice() throws IOException { - return openSlice(0, raf.length()); + return openSlice("full-slice", 0, raf.length()); } }; } @@ -256,8 +256,9 @@ private ByteBuffer curBuf; // redundant for speed: buffers[curBufIndex] private boolean isClone = false; - - MMapIndexInput(RandomAccessFile raf, long offset, long length, int chunkSizePower) throws IOException { + + MMapIndexInput(String resourceDescription, RandomAccessFile raf, long offset, long length, int chunkSizePower) throws IOException { + super(resourceDescription); this.length = length; this.chunkSizePower = chunkSizePower; this.chunkSize = 1L << chunkSizePower; @@ -296,8 +297,9 @@ } catch (BufferUnderflowException e) { do { curBufIndex++; - if (curBufIndex >= buffers.length) - throw new IOException("read past EOF"); + if (curBufIndex >= buffers.length) { + throw new IOException("read past EOF: " + this); + } curBuf = buffers[curBufIndex]; curBuf.position(0); } while (!curBuf.hasRemaining()); @@ -316,8 +318,9 @@ len -= curAvail; offset += curAvail; curBufIndex++; - if (curBufIndex >= buffers.length) - throw new IOException("read past EOF"); + if (curBufIndex >= buffers.length) { + throw new IOException("read past EOF: " + this); + } curBuf = buffers[curBufIndex]; curBuf.position(0); curAvail = curBuf.remaining(); @@ -369,13 +372,15 @@ this.curBufIndex = bi; this.curBuf = b; } catch (ArrayIndexOutOfBoundsException aioobe) { - if (pos < 0L) - throw new IllegalArgumentException("Seeking to negative position"); + if (pos < 0L) { + throw new IllegalArgumentException("Seeking to negative position: " + this); + } throw new IOException("seek past EOF"); } catch (IllegalArgumentException iae) { - if (pos < 0L) - throw new IllegalArgumentException("Seeking to negative position"); - throw new IOException("seek past EOF"); + if (pos < 0L) { + throw new IllegalArgumentException("Seeking to negative position: " + this); + } + throw new IOException("seek past EOF: " + this); } } @@ -386,8 +391,9 @@ @Override public Object clone() { - if (buffers == null) - throw new AlreadyClosedException("MMapIndexInput already closed"); + if (buffers == null) { + throw new AlreadyClosedException("MMapIndexInput already closed: " + this); + } final MMapIndexInput clone = (MMapIndexInput)super.clone(); clone.isClone = true; clone.buffers = new ByteBuffer[buffers.length]; @@ -399,7 +405,7 @@ try { clone.seek(getFilePointer()); } catch(IOException ioe) { - throw new RuntimeException("Should never happen", ioe); + throw new RuntimeException("Should never happen: " + this, ioe); } return clone; } Index: lucene/src/java/org/apache/lucene/store/IndexInput.java =================================================================== --- lucene/src/java/org/apache/lucene/store/IndexInput.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/store/IndexInput.java (working copy) @@ -26,6 +26,18 @@ */ public abstract class IndexInput extends DataInput implements Cloneable,Closeable { + private final String resourceDescription; + + /** resourceDescription should be a non-null, opaque string + * describing this resource; it's returned from + * {@link #toString}. */ + protected IndexInput(String resourceDescription) { + if (resourceDescription == null) { + throw new IllegalArgumentException("resourceDescription must not be null"); + } + this.resourceDescription = resourceDescription; + } + /** Closes the stream to further operations. */ public abstract void close() throws IOException; @@ -66,5 +78,9 @@ numBytes -= toCopy; } } - + + @Override + public String toString() { + return resourceDescription; + } } Index: lucene/src/java/org/apache/lucene/store/BufferedIndexInput.java =================================================================== --- lucene/src/java/org/apache/lucene/store/BufferedIndexInput.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/store/BufferedIndexInput.java (working copy) @@ -51,14 +51,17 @@ return buffer[bufferPosition++]; } - public BufferedIndexInput() {} - - public BufferedIndexInput(IOContext context) { - this(bufferSize(context)); + public BufferedIndexInput(String resourceDesc) { + this(resourceDesc, BUFFER_SIZE); } + public BufferedIndexInput(String resourceDesc, IOContext context) { + this(resourceDesc, bufferSize(context)); + } + /** Inits BufferedIndexInput with a specific bufferSize */ - public BufferedIndexInput(int bufferSize) { + public BufferedIndexInput(String resourceDesc, int bufferSize) { + super(resourceDesc); checkBufferSize(bufferSize); this.bufferSize = bufferSize; } Index: lucene/src/java/org/apache/lucene/store/RAMDirectory.java =================================================================== --- lucene/src/java/org/apache/lucene/store/RAMDirectory.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/store/RAMDirectory.java (working copy) @@ -183,7 +183,7 @@ if (file == null) { throw new FileNotFoundException(name); } - return new RAMInputStream(file); + return new RAMInputStream(name, file); } /** Closes the store to future operations, releasing associated memory. */ Index: lucene/src/java/org/apache/lucene/store/Directory.java =================================================================== --- lucene/src/java/org/apache/lucene/store/Directory.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/store/Directory.java (working copy) @@ -225,8 +225,8 @@ return new IndexInputSlicer() { private final IndexInput base = Directory.this.openInput(name, context); @Override - public IndexInput openSlice(long offset, long length) { - return new SlicedIndexInput(base, offset, length); + public IndexInput openSlice(String sliceDescription, long offset, long length) { + return new SlicedIndexInput("SlicedIndexInput(" + sliceDescription + " in " + base + ")", base, offset, length); } @Override public void close() throws IOException { @@ -258,7 +258,7 @@ /** * Returns an {@link IndexInput} slice starting at the given offset with the given length. */ - public abstract IndexInput openSlice(long offset, long length) throws IOException; + public abstract IndexInput openSlice(String sliceDescription, long offset, long length) throws IOException; /** * Returns an {@link IndexInput} slice starting at offset 0 with a @@ -275,12 +275,12 @@ long fileOffset; long length; - SlicedIndexInput(final IndexInput base, final long fileOffset, final long length) { - this(base, fileOffset, length, BufferedIndexInput.BUFFER_SIZE); + SlicedIndexInput(final String sliceDescription, final IndexInput base, final long fileOffset, final long length) { + this(sliceDescription, base, fileOffset, length, BufferedIndexInput.BUFFER_SIZE); } - SlicedIndexInput(final IndexInput base, final long fileOffset, final long length, int readBufferSize) { - super(readBufferSize); + SlicedIndexInput(final String sliceDescription, final IndexInput base, final long fileOffset, final long length, int readBufferSize) { + super("SlicedIndexInput(" + sliceDescription + " in " + base + " slice=" + fileOffset + ":" + (fileOffset+length) + ")", readBufferSize); this.base = (IndexInput) base.clone(); this.fileOffset = fileOffset; this.length = length; Index: lucene/src/java/org/apache/lucene/store/SimpleFSDirectory.java =================================================================== --- lucene/src/java/org/apache/lucene/store/SimpleFSDirectory.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/store/SimpleFSDirectory.java (working copy) @@ -55,10 +55,9 @@ @Override public IndexInput openInput(String name, IOContext context) throws IOException { ensureOpen(); - return new SimpleFSIndexInput(new File(directory, name), context, getReadChunkSize()); + final File path = new File(directory, name); + return new SimpleFSIndexInput("SimpleFSIndexInput(path=\"" + path.getPath() + "\")", path, context, getReadChunkSize()); } - - public IndexInputSlicer createSlicer(final String name, final IOContext context) throws IOException { @@ -73,19 +72,18 @@ } @Override - public IndexInput openSlice(long offset, long length) throws IOException { - return new SimpleFSIndexInput(descriptor, offset, + public IndexInput openSlice(String sliceDescription, long offset, long length) throws IOException { + return new SimpleFSIndexInput("SimpleFSIndexInput(" + sliceDescription + " in path=\"" + file.getPath() + "\" slice=" + offset + ":" + (offset+length) + ")", descriptor, offset, length, BufferedIndexInput.bufferSize(context), getReadChunkSize()); } @Override public IndexInput openFullSlice() throws IOException { - return openSlice(0, descriptor.length); + return openSlice("full-slice", 0, descriptor.length); } }; } - protected static class SimpleFSIndexInput extends BufferedIndexInput { protected static class Descriptor extends RandomAccessFile { @@ -117,16 +115,16 @@ protected final long off; protected final long end; - public SimpleFSIndexInput(File path, IOContext context, int chunkSize) throws IOException { - super(context); + public SimpleFSIndexInput(String resourceDesc, File path, IOContext context, int chunkSize) throws IOException { + super(resourceDesc, context); this.file = new Descriptor(path, "r"); this.chunkSize = chunkSize; this.off = 0L; this.end = file.length; } - public SimpleFSIndexInput(Descriptor file, long off, long length, int bufferSize, int chunkSize) throws IOException { - super(bufferSize); + public SimpleFSIndexInput(String resourceDesc, Descriptor file, long off, long length, int bufferSize, int chunkSize) throws IOException { + super(resourceDesc, bufferSize); this.file = file; this.chunkSize = chunkSize; this.off = off; @@ -147,7 +145,7 @@ int total = 0; if (position + len > end) { - throw new IOException("read past EOF"); + throw new IOException("read past EOF: " + this); } try { @@ -172,6 +170,8 @@ + "with a value smaller than the current chunk size (" + chunkSize + ")"); outOfMemoryError.initCause(e); throw outOfMemoryError; + } catch (IOException ioe) { + throw new IOException(ioe.getMessage() + ": " + this, ioe); } } } Index: lucene/src/java/org/apache/lucene/store/ChecksumIndexInput.java =================================================================== --- lucene/src/java/org/apache/lucene/store/ChecksumIndexInput.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/store/ChecksumIndexInput.java (working copy) @@ -31,6 +31,7 @@ Checksum digest; public ChecksumIndexInput(IndexInput main) { + super("ChecksumIndexInput(" + main + ")"); this.main = main; digest = new CRC32(); } Index: lucene/src/java/org/apache/lucene/store/RAMInputStream.java =================================================================== --- lucene/src/java/org/apache/lucene/store/RAMInputStream.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/store/RAMInputStream.java (working copy) @@ -18,6 +18,7 @@ */ import java.io.IOException; +import java.io.EOFException; /** A memory-resident {@link IndexInput} implementation. * @@ -35,11 +36,12 @@ private long bufferStart; private int bufferLength; - public RAMInputStream(RAMFile f) throws IOException { + public RAMInputStream(String name, RAMFile f) throws IOException { + super("RAMInputStream(name=" + name + ")"); file = f; length = file.length; if (length/BUFFER_SIZE >= Integer.MAX_VALUE) { - throw new IOException("Too large RAMFile! "+length); + throw new IOException("RAMInputStream too large length=" + length + ": " + name); } // make sure that we switch to the @@ -88,9 +90,9 @@ bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex; if (currentBufferIndex >= file.numBuffers()) { // end of file reached, no more buffers left - if (enforceEOF) - throw new IOException("Read past EOF"); - else { + if (enforceEOF) { + throw new EOFException("Read past EOF: " + this); + } else { // Force EOF if a read takes place at this position currentBufferIndex--; bufferPosition = BUFFER_SIZE; Index: lucene/src/java/org/apache/lucene/util/CodecUtil.java =================================================================== --- lucene/src/java/org/apache/lucene/util/CodecUtil.java (revision 1197218) +++ lucene/src/java/org/apache/lucene/util/CodecUtil.java (working copy) @@ -18,14 +18,15 @@ */ -import org.apache.lucene.store.DataInput; -import org.apache.lucene.store.DataOutput; +import java.io.IOException; + import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.IndexFormatTooNewException; import org.apache.lucene.index.IndexFormatTooOldException; +import org.apache.lucene.store.DataInput; +import org.apache.lucene.store.DataOutput; +import org.apache.lucene.store.IndexInput; -import java.io.IOException; - /** * @lucene.experimental */ @@ -58,20 +59,20 @@ // Safety to guard against reading a bogus string: final int actualHeader = in.readInt(); if (actualHeader != CODEC_MAGIC) { - throw new CorruptIndexException("codec header mismatch: actual header=" + actualHeader + " vs expected header=" + CODEC_MAGIC); + throw new CorruptIndexException("codec header mismatch: actual header=" + actualHeader + " vs expected header=" + CODEC_MAGIC + "; resource=" + in); } final String actualCodec = in.readString(); if (!actualCodec.equals(codec)) { - throw new CorruptIndexException("codec mismatch: actual codec=" + actualCodec + " vs expected codec=" + codec); + throw new CorruptIndexException("codec mismatch: actual codec=" + actualCodec + " vs expected codec=" + codec + "; input=" + in); } final int actualVersion = in.readInt(); if (actualVersion < minVersion) { - throw new IndexFormatTooOldException(null, actualVersion, minVersion, maxVersion); + throw new IndexFormatTooOldException(in, actualVersion, minVersion, maxVersion); } if (actualVersion > maxVersion) { - throw new IndexFormatTooNewException(null, actualVersion, minVersion, maxVersion); + throw new IndexFormatTooNewException(in, actualVersion, minVersion, maxVersion); } return actualVersion; Index: lucene/src/test-framework/org/apache/lucene/index/MockIndexInput.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/index/MockIndexInput.java (revision 1197218) +++ lucene/src/test-framework/org/apache/lucene/index/MockIndexInput.java (working copy) @@ -25,6 +25,7 @@ private long length; public MockIndexInput(byte[] bytes) { + super("MockIndexInput", BufferedIndexInput.BUFFER_SIZE); buffer = bytes; length = bytes.length; } Index: lucene/src/test-framework/org/apache/lucene/store/MockDirectoryWrapper.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/store/MockDirectoryWrapper.java (revision 1197218) +++ lucene/src/test-framework/org/apache/lucene/store/MockDirectoryWrapper.java (working copy) @@ -687,9 +687,9 @@ } @Override - public IndexInput openSlice(long offset, long length) throws IOException { + public IndexInput openSlice(String sliceDescription, long offset, long length) throws IOException { maybeYield(); - IndexInput ii = new MockIndexInputWrapper(MockDirectoryWrapper.this, name, delegateHandle.openSlice(offset, length)); + IndexInput ii = new MockIndexInputWrapper(MockDirectoryWrapper.this, name, delegateHandle.openSlice(sliceDescription, offset, length)); addFileHandle(ii, name, Handle.Input); return ii; } Index: lucene/src/test-framework/org/apache/lucene/store/MockIndexInputWrapper.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/store/MockIndexInputWrapper.java (revision 1197218) +++ lucene/src/test-framework/org/apache/lucene/store/MockIndexInputWrapper.java (working copy) @@ -34,6 +34,7 @@ /** Construct an empty output buffer. */ public MockIndexInputWrapper(MockDirectoryWrapper dir, String name, IndexInput delegate) { + super("MockIndexInputWrapper(name=" + name + " delegate=" + delegate + ")"); this.name = name; this.dir = dir; this.delegate = delegate;