Index: src/test/org/apache/lucene/index/TestIndexReader.java =================================================================== --- src/test/org/apache/lucene/index/TestIndexReader.java (revision 507871) +++ src/test/org/apache/lucene/index/TestIndexReader.java (working copy) @@ -25,6 +25,7 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.store.FSDirectory; +import org.apache.lucene.store.LockObtainFailedException; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.analysis.WhitespaceAnalyzer; import org.apache.lucene.document.Document; @@ -245,6 +246,96 @@ reader.close(); } + // Make sure attempts to make changes after reader is + // closed throws IOException: + public void testChangesAfterClose() throws IOException + { + Directory dir = new RAMDirectory(); + + IndexWriter writer = null; + IndexReader reader = null; + Term searchTerm = new Term("content", "aaa"); + + // add 11 documents with term : aaa + writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true); + for (int i = 0; i < 11; i++) + { + addDoc(writer, searchTerm.text()); + } + writer.close(); + + reader = IndexReader.open(dir); + + // Close reader: + reader.close(); + + // Then, try to make changes: + try { + reader.deleteDocument(4); + fail("deleteDocument after close failed to throw IOException"); + } catch (IOException e) { + // expected + } + + try { + reader.setNorm(5, "aaa", 2.0f); + fail("setNorm after close failed to throw IOException"); + } catch (IOException e) { + // expected + } + + try { + reader.undeleteAll(); + fail("undeleteAll after close failed to throw IOException"); + } catch (IOException e) { + // expected + } + } + + // Make sure we get lock obtain failed exception with 2 writers: + public void testLockObtainFailed() throws IOException + { + Directory dir = new RAMDirectory(); + + IndexWriter writer = null; + IndexReader reader = null; + Term searchTerm = new Term("content", "aaa"); + + // add 11 documents with term : aaa + writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true); + for (int i = 0; i < 11; i++) + { + addDoc(writer, searchTerm.text()); + } + + // Create reader: + reader = IndexReader.open(dir); + + // Try to make changes + try { + reader.deleteDocument(4); + fail("deleteDocument should have hit LockObtainFailedException"); + } catch (LockObtainFailedException e) { + // expected + } + + try { + reader.setNorm(5, "aaa", 2.0f); + fail("setNorm should have hit LockObtainFailedException"); + } catch (LockObtainFailedException e) { + // expected + } + + try { + reader.undeleteAll(); + fail("undeleteAll should have hit LockObtainFailedException"); + } catch (LockObtainFailedException e) { + // expected + } + writer.close(); + reader.close(); + } + // Make sure you can set norms & commit even if a reader // is open against the index: public void testWritingNorms() throws IOException @@ -371,7 +462,7 @@ try { deleted = reader.deleteDocuments(searchTerm); fail("Delete allowed on an index reader with stale segment information"); - } catch (IOException e) { + } catch (StaleReaderException e) { /* success */ } Index: src/java/org/apache/lucene/queryParser/QueryParser.java =================================================================== --- src/java/org/apache/lucene/queryParser/QueryParser.java (revision 507871) +++ src/java/org/apache/lucene/queryParser/QueryParser.java (working copy) @@ -53,7 +53,7 @@ * By default a date is converted into a search term using the deprecated * {@link DateField} for compatibility reasons. * To use the new {@link DateTools} to convert dates, a - * {@link DateTools.Resolution} has to be set. + * {@link org.apache.lucene.document.DateTools.Resolution} has to be set. *
*
* The date resolution that shall be used for RangeQueries can be set
@@ -321,7 +321,7 @@
/**
* Sets the date resolution used by RangeQueries for a specific field.
*
- * @param field field for which the date resolution is to be set
+ * @param fieldName field for which the date resolution is to be set
* @param dateResolution date resolution to set
*/
public void setDateResolution(String fieldName, DateTools.Resolution dateResolution) {
Index: src/java/org/apache/lucene/search/RemoteSearchable.java
===================================================================
--- src/java/org/apache/lucene/search/RemoteSearchable.java (revision 507871)
+++ src/java/org/apache/lucene/search/RemoteSearchable.java (working copy)
@@ -19,6 +19,7 @@
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
+import org.apache.lucene.index.CorruptIndexException;
import java.io.IOException;
import java.rmi.Naming;
@@ -76,7 +77,7 @@
return local.search (weight, filter, n, sort);
}
- public Document doc(int i) throws IOException {
+ public Document doc(int i) throws CorruptIndexException, IOException {
return local.doc(i);
}
Index: src/java/org/apache/lucene/search/Searcher.java
===================================================================
--- src/java/org/apache/lucene/search/Searcher.java (revision 507871)
+++ src/java/org/apache/lucene/search/Searcher.java (working copy)
@@ -19,6 +19,7 @@
import java.io.IOException;
+import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.Term;
import org.apache.lucene.document.Document;
@@ -187,7 +188,7 @@
abstract public int docFreq(Term term) throws IOException;
abstract public int maxDoc() throws IOException;
abstract public TopDocs search(Weight weight, Filter filter, int n) throws IOException;
- abstract public Document doc(int i) throws IOException;
+ abstract public Document doc(int i) throws CorruptIndexException, IOException;
abstract public Query rewrite(Query query) throws IOException;
abstract public Explanation explain(Weight weight, int doc) throws IOException;
abstract public TopFieldDocs search(Weight weight, Filter filter, int n, Sort sort) throws IOException;
Index: src/java/org/apache/lucene/search/Searchable.java
===================================================================
--- src/java/org/apache/lucene/search/Searchable.java (revision 507871)
+++ src/java/org/apache/lucene/search/Searchable.java (working copy)
@@ -20,6 +20,7 @@
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
+import org.apache.lucene.index.CorruptIndexException;
import java.io.IOException; // for javadoc
@@ -92,8 +93,10 @@
/** Expert: Returns the stored fields of document i.
* Called by {@link HitCollector} implementations.
* @see IndexReader#document(int)
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- Document doc(int i) throws IOException;
+ Document doc(int i) throws CorruptIndexException, IOException;
/** Expert: called to re-write queries into primitive queries.
* @throws BooleanQuery.TooManyClauses
Index: src/java/org/apache/lucene/search/MultiSearcher.java
===================================================================
--- src/java/org/apache/lucene/search/MultiSearcher.java (revision 507871)
+++ src/java/org/apache/lucene/search/MultiSearcher.java (working copy)
@@ -25,6 +25,7 @@
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
+import org.apache.lucene.index.CorruptIndexException;
/** Implements search over a set of Searchables.
*
@@ -142,7 +143,7 @@
}
// inherit javadoc
- public Document doc(int n) throws IOException {
+ public Document doc(int n) throws CorruptIndexException, IOException {
int i = subSearcher(n); // find searcher index
return searchables[i].doc(n - starts[i]); // dispatch to searcher
}
Index: src/java/org/apache/lucene/search/Hits.java
===================================================================
--- src/java/org/apache/lucene/search/Hits.java (revision 507871)
+++ src/java/org/apache/lucene/search/Hits.java (working copy)
@@ -22,6 +22,7 @@
import java.util.Iterator;
import org.apache.lucene.document.Document;
+import org.apache.lucene.index.CorruptIndexException;
/** A ranked list of documents, used to hold search results. */
public final class Hits {
@@ -86,9 +87,12 @@
}
/** Returns the stored fields of the nth document in this set.
-
Documents are cached, so that repeated requests for the same element may - return the same Document object. */ - public final Document doc(int n) throws IOException { + *
Documents are cached, so that repeated requests for the same element may
+ * return the same Document object.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
+ */
+ public final Document doc(int n) throws CorruptIndexException, IOException {
HitDoc hitDoc = hitDoc(n);
// Update LRU cache of documents
Index: src/java/org/apache/lucene/search/Hit.java
===================================================================
--- src/java/org/apache/lucene/search/Hit.java (revision 507871)
+++ src/java/org/apache/lucene/search/Hit.java (working copy)
@@ -20,6 +20,7 @@
import java.io.IOException;
import org.apache.lucene.document.Document;
+import org.apache.lucene.index.CorruptIndexException;
/**
* Wrapper used by {@link HitIterator} to provide a lazily loaded hit
@@ -50,8 +51,10 @@
* Returns document for this hit.
*
* @see Hits#doc(int)
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public Document getDocument() throws IOException {
+ public Document getDocument() throws CorruptIndexException, IOException {
if (!resolved) fetchTheHit();
return doc;
}
@@ -74,7 +77,7 @@
return hits.id(hitNumber);
}
- private void fetchTheHit() throws IOException {
+ private void fetchTheHit() throws CorruptIndexException, IOException {
doc = hits.doc(hitNumber);
resolved = true;
}
@@ -85,8 +88,10 @@
* Returns the boost factor for this hit on any field of the underlying document.
*
* @see Document#getBoost()
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public float getBoost() throws IOException {
+ public float getBoost() throws CorruptIndexException, IOException {
return getDocument().getBoost();
}
@@ -97,8 +102,10 @@
* exist, returns null.
*
* @see Document#get(String)
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public String get(String name) throws IOException {
+ public String get(String name) throws CorruptIndexException, IOException {
return getDocument().get(name);
}
Index: src/java/org/apache/lucene/search/IndexSearcher.java
===================================================================
--- src/java/org/apache/lucene/search/IndexSearcher.java (revision 507871)
+++ src/java/org/apache/lucene/search/IndexSearcher.java (working copy)
@@ -24,6 +24,7 @@
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
+import org.apache.lucene.index.CorruptIndexException;
/** Implements search over a single IndexReader.
*
@@ -38,13 +39,19 @@
IndexReader reader;
private boolean closeReader;
- /** Creates a searcher searching the index in the named directory. */
- public IndexSearcher(String path) throws IOException {
+ /** Creates a searcher searching the index in the named directory.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
+ */
+ public IndexSearcher(String path) throws CorruptIndexException, IOException {
this(IndexReader.open(path), true);
}
- /** Creates a searcher searching the index in the provided directory. */
- public IndexSearcher(Directory directory) throws IOException {
+ /** Creates a searcher searching the index in the provided directory.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
+ */
+ public IndexSearcher(Directory directory) throws CorruptIndexException, IOException {
this(IndexReader.open(directory), true);
}
@@ -80,7 +87,7 @@
}
// inherit javadoc
- public Document doc(int i) throws IOException {
+ public Document doc(int i) throws CorruptIndexException, IOException {
return reader.document(i);
}
Index: src/java/org/apache/lucene/index/MultiReader.java
===================================================================
--- src/java/org/apache/lucene/index/MultiReader.java (revision 507871)
+++ src/java/org/apache/lucene/index/MultiReader.java (working copy)
@@ -103,7 +103,8 @@
return maxDoc;
}
- public Document document(int n, FieldSelector fieldSelector) throws IOException {
+ // inherit javadoc
+ public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException {
int i = readerIndex(n); // find segment num
return subReaders[i].document(n - starts[i], fieldSelector); // dispatch to segment reader
}
@@ -115,16 +116,17 @@
public boolean hasDeletions() { return hasDeletions; }
- protected void doDelete(int n) throws IOException {
+ protected void doDelete(int n) throws CorruptIndexException, IOException {
numDocs = -1; // invalidate cache
int i = readerIndex(n); // find segment num
subReaders[i].deleteDocument(n - starts[i]); // dispatch to segment reader
hasDeletions = true;
}
- protected void doUndeleteAll() throws IOException {
+ protected void doUndeleteAll() throws CorruptIndexException, IOException {
for (int i = 0; i < subReaders.length; i++)
subReaders[i].undeleteAll();
+
hasDeletions = false;
numDocs = -1; // invalidate cache
}
@@ -189,7 +191,7 @@
}
protected void doSetNorm(int n, String field, byte value)
- throws IOException {
+ throws CorruptIndexException, IOException {
normsCache.remove(field); // clear cache
int i = readerIndex(n); // find segment num
subReaders[i].setNorm(n-starts[i], field, value); // dispatch
Index: src/java/org/apache/lucene/index/SegmentTermEnum.java
===================================================================
--- src/java/org/apache/lucene/index/SegmentTermEnum.java (revision 507871)
+++ src/java/org/apache/lucene/index/SegmentTermEnum.java (working copy)
@@ -40,7 +40,7 @@
private int formatM1SkipInterval;
SegmentTermEnum(IndexInput i, FieldInfos fis, boolean isi)
- throws IOException {
+ throws CorruptIndexException, IOException {
input = i;
fieldInfos = fis;
isIndex = isi;
@@ -61,7 +61,7 @@
// check that it is a format we can understand
if (format < TermInfosWriter.FORMAT)
- throw new IOException("Unknown format version:" + format);
+ throw new CorruptIndexException("Unknown format version:" + format);
size = input.readLong(); // read the size
Index: src/java/org/apache/lucene/index/FieldsReader.java
===================================================================
--- src/java/org/apache/lucene/index/FieldsReader.java (revision 507871)
+++ src/java/org/apache/lucene/index/FieldsReader.java (working copy)
@@ -79,7 +79,7 @@
return size;
}
- final Document doc(int n, FieldSelector fieldSelector) throws IOException {
+ final Document doc(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException {
indexStream.seek(n * 8L);
long position = indexStream.readLong();
fieldsStream.seek(position);
@@ -199,7 +199,7 @@
doc.add(new FieldForMerge(data, fi, binary, compressed, tokenize));
}
- private void addField(Document doc, FieldInfo fi, boolean binary, boolean compressed, boolean tokenize) throws IOException {
+ private void addField(Document doc, FieldInfo fi, boolean binary, boolean compressed, boolean tokenize) throws CorruptIndexException, IOException {
//we have a binary stored field, and it may be compressed
if (binary) {
@@ -397,7 +397,7 @@
}
private final byte[] uncompress(final byte[] input)
- throws IOException {
+ throws CorruptIndexException, IOException {
Inflater decompressor = new Inflater();
decompressor.setInput(input);
@@ -414,7 +414,7 @@
}
catch (DataFormatException e) {
// this will happen if the field is not compressed
- IOException newException = new IOException("field data are in wrong format: " + e.toString());
+ CorruptIndexException newException = new CorruptIndexException("field data are in wrong format: " + e.toString());
newException.initCause(e);
throw newException;
}
Index: src/java/org/apache/lucene/index/TermInfosReader.java
===================================================================
--- src/java/org/apache/lucene/index/TermInfosReader.java (revision 507871)
+++ src/java/org/apache/lucene/index/TermInfosReader.java (working copy)
@@ -41,7 +41,7 @@
private SegmentTermEnum indexEnum;
TermInfosReader(Directory dir, String seg, FieldInfos fis)
- throws IOException {
+ throws CorruptIndexException, IOException {
directory = dir;
segment = seg;
fieldInfos = fis;
Index: src/java/org/apache/lucene/index/IndexReader.java
===================================================================
--- src/java/org/apache/lucene/index/IndexReader.java (revision 507871)
+++ src/java/org/apache/lucene/index/IndexReader.java (working copy)
@@ -24,6 +24,7 @@
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.Lock;
+import org.apache.lucene.store.LockObtainFailedException;
import java.io.File;
import java.io.FileOutputStream;
@@ -114,6 +115,7 @@
private boolean directoryOwner;
private boolean closeDirectory;
protected IndexFileDeleter deleter;
+ private boolean isClosed;
private SegmentInfos segmentInfos;
private Lock writeLock;
@@ -126,27 +128,36 @@
private SegmentInfos rollbackSegmentInfos;
/** Returns an IndexReader reading the index in an FSDirectory in the named
- path. */
- public static IndexReader open(String path) throws IOException {
+ path.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
+ */
+ public static IndexReader open(String path) throws CorruptIndexException, IOException {
return open(FSDirectory.getDirectory(path), true);
}
/** Returns an IndexReader reading the index in an FSDirectory in the named
- path. */
- public static IndexReader open(File path) throws IOException {
+ path.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
+ */
+ public static IndexReader open(File path) throws CorruptIndexException, IOException {
return open(FSDirectory.getDirectory(path), true);
}
- /** Returns an IndexReader reading the index in the given Directory. */
- public static IndexReader open(final Directory directory) throws IOException {
+ /** Returns an IndexReader reading the index in the given Directory.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
+ */
+ public static IndexReader open(final Directory directory) throws CorruptIndexException, IOException {
return open(directory, false);
}
- private static IndexReader open(final Directory directory, final boolean closeDirectory) throws IOException {
+ private static IndexReader open(final Directory directory, final boolean closeDirectory) throws CorruptIndexException, IOException {
return (IndexReader) new SegmentInfos.FindSegmentsFile(directory) {
- public Object doBody(String segmentFileName) throws IOException {
+ public Object doBody(String segmentFileName) throws CorruptIndexException, IOException {
SegmentInfos infos = new SegmentInfos();
infos.read(directory, segmentFileName);
@@ -186,8 +197,10 @@
* Returns the time the index in the named directory was last modified.
* Do not use this to check whether the reader is still up-to-date, use
* {@link #isCurrent()} instead.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public static long lastModified(String directory) throws IOException {
+ public static long lastModified(String directory) throws CorruptIndexException, IOException {
return lastModified(new File(directory));
}
@@ -195,8 +208,10 @@
* Returns the time the index in the named directory was last modified.
* Do not use this to check whether the reader is still up-to-date, use
* {@link #isCurrent()} instead.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public static long lastModified(File fileDirectory) throws IOException {
+ public static long lastModified(File fileDirectory) throws CorruptIndexException, IOException {
return ((Long) new SegmentInfos.FindSegmentsFile(fileDirectory) {
public Object doBody(String segmentFileName) {
return new Long(FSDirectory.fileModified(fileDirectory, segmentFileName));
@@ -208,8 +223,10 @@
* Returns the time the index in the named directory was last modified.
* Do not use this to check whether the reader is still up-to-date, use
* {@link #isCurrent()} instead.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public static long lastModified(final Directory directory2) throws IOException {
+ public static long lastModified(final Directory directory2) throws CorruptIndexException, IOException {
return ((Long) new SegmentInfos.FindSegmentsFile(directory2) {
public Object doBody(String segmentFileName) throws IOException {
return new Long(directory2.fileModified(segmentFileName));
@@ -224,9 +241,10 @@
*
* @param directory where the index resides.
* @return version number.
- * @throws IOException if segments file cannot be read
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public static long getCurrentVersion(String directory) throws IOException {
+ public static long getCurrentVersion(String directory) throws CorruptIndexException, IOException {
return getCurrentVersion(new File(directory));
}
@@ -237,9 +255,10 @@
*
* @param directory where the index resides.
* @return version number.
- * @throws IOException if segments file cannot be read
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public static long getCurrentVersion(File directory) throws IOException {
+ public static long getCurrentVersion(File directory) throws CorruptIndexException, IOException {
Directory dir = FSDirectory.getDirectory(directory);
long version = getCurrentVersion(dir);
dir.close();
@@ -253,9 +272,10 @@
*
* @param directory where the index resides.
* @return version number.
- * @throws IOException if segments file cannot be read.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public static long getCurrentVersion(Directory directory) throws IOException {
+ public static long getCurrentVersion(Directory directory) throws CorruptIndexException, IOException {
return SegmentInfos.readCurrentVersion(directory);
}
@@ -271,9 +291,10 @@
* If this is not the case you will need to re-open the IndexReader to
* make sure you see the latest changes made to the index.
*
- * @throws IOException
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public boolean isCurrent() throws IOException {
+ public boolean isCurrent() throws CorruptIndexException, IOException {
return SegmentInfos.readCurrentVersion(directory) == segmentInfos.getVersion();
}
@@ -363,8 +384,11 @@
public abstract int maxDoc();
/** Returns the stored fields of the nth
- Document in this index. */
- public Document document(int n) throws IOException{
+ Document in this index.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
+ */
+ public Document document(int n) throws CorruptIndexException, IOException {
return document(n, null);
}
@@ -372,7 +396,7 @@
* Get the {@link org.apache.lucene.document.Document} at the nth position. The {@link org.apache.lucene.document.FieldSelector}
* may be used to determine what {@link org.apache.lucene.document.Field}s to load and how they should be loaded.
*
- * NOTE: If this Reader (more specifically, the underlying {@link FieldsReader} is closed before the lazy {@link org.apache.lucene.document.Field} is
+ * NOTE: If this Reader (more specifically, the underlying FieldsReader is closed before the lazy {@link org.apache.lucene.document.Field} is
* loaded an exception may be thrown. If you want the value of a lazy {@link org.apache.lucene.document.Field} to be available after closing you must
* explicitly load it or fetch the Document again with a new loader.
*
@@ -380,7 +404,8 @@
* @param n Get the document at the nth position
* @param fieldSelector The {@link org.apache.lucene.document.FieldSelector} to use to determine what Fields should be loaded on the Document. May be null, in which case all Fields will be loaded.
* @return The stored fields of the {@link org.apache.lucene.document.Document} at the nth position
- * @throws IOException If there is a problem reading this document
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*
* @see org.apache.lucene.document.Fieldable
* @see org.apache.lucene.document.FieldSelector
@@ -388,7 +413,7 @@
* @see org.apache.lucene.document.LoadFirstFieldSelector
*/
//When we convert to JDK 1.5 make this Setwrite.lock could not
+ * be obtained)
+ * @throws IOException if this reader was closed already
+ * or there is a low-level IO error
*/
public final synchronized void setNorm(int doc, String field, byte value)
- throws IOException{
+ throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException {
if(directoryOwner)
- aquireWriteLock();
+ acquireWriteLock();
hasChanges = true;
doSetNorm(doc, field, value);
}
/** Implements setNorm in subclass.*/
protected abstract void doSetNorm(int doc, String field, byte value)
- throws IOException;
+ throws CorruptIndexException, IOException;
/** Expert: Resets the normalization factor for the named field of the named
* document.
*
* @see #norms(String)
* @see Similarity#decodeNorm(byte)
+ *
+ * @throws StaleReaderException if the index has changed
+ * since this reader was opened
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if this reader was closed already
+ * or there is a low-level IO error
*/
public void setNorm(int doc, String field, float value)
- throws IOException {
+ throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException {
setNorm(doc, field, Similarity.encodeNorm(value));
}
@@ -515,16 +557,24 @@
* Tries to acquire the WriteLock on this directory.
* this method is only valid if this IndexReader is directory owner.
*
- * @throws IOException If WriteLock cannot be acquired.
+ * @throws StaleReaderException if the index has changed
+ * since this reader was opened
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- private void aquireWriteLock() throws IOException {
+ private void acquireWriteLock() throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException {
if (stale)
- throw new IOException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
+ throw new StaleReaderException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
+ if (isClosed)
+ throw new IOException("this reader is closed");
if (writeLock == null) {
Lock writeLock = directory.makeLock(IndexWriter.WRITE_LOCK_NAME);
if (!writeLock.obtain(IndexWriter.WRITE_LOCK_TIMEOUT)) // obtain write lock
- throw new IOException("Index locked for write: " + writeLock);
+ throw new LockObtainFailedException("Index locked for write: " + writeLock);
this.writeLock = writeLock;
// we have to check whether index has changed since this reader was opened.
@@ -533,7 +583,7 @@
stale = true;
this.writeLock.release();
this.writeLock = null;
- throw new IOException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
+ throw new StaleReaderException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations");
}
}
}
@@ -545,10 +595,19 @@
* method will result in an error. The presence of this document may still be
* reflected in the {@link #docFreq} statistic, though
* this will be corrected eventually as the index is further modified.
+ *
+ * @throws StaleReaderException if the index has changed
+ * since this reader was opened
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if this reader was closed already
+ * or there is a low-level IO error
*/
- public final synchronized void deleteDocument(int docNum) throws IOException {
+ public final synchronized void deleteDocument(int docNum) throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException {
if(directoryOwner)
- aquireWriteLock();
+ acquireWriteLock();
hasChanges = true;
doDelete(docNum);
}
@@ -557,7 +616,7 @@
/** Implements deletion of the document numbered docNum.
* Applications should call {@link #deleteDocument(int)} or {@link #deleteDocuments(Term)}.
*/
- protected abstract void doDelete(int docNum) throws IOException;
+ protected abstract void doDelete(int docNum) throws CorruptIndexException, IOException;
/** Deletes all documents that have a given term indexed.
@@ -567,9 +626,18 @@
* passes it to this method.
* See {@link #deleteDocument(int)} for information about when this deletion will
* become effective.
+ *
* @return the number of documents deleted
+ * @throws StaleReaderException if the index has changed
+ * since this reader was opened
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if this reader was closed already
+ * or there is a low-level IO error
*/
- public final int deleteDocuments(Term term) throws IOException {
+ public final int deleteDocuments(Term term) throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException {
TermDocs docs = termDocs(term);
if (docs == null) return 0;
int n = 0;
@@ -584,16 +652,26 @@
return n;
}
- /** Undeletes all documents currently marked as deleted in this index.*/
- public final synchronized void undeleteAll() throws IOException{
+ /** Undeletes all documents currently marked as deleted in this index.
+ *
+ * @throws StaleReaderException if the index has changed
+ * since this reader was opened
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if this reader was closed already
+ * or there is a low-level IO error
+ */
+ public final synchronized void undeleteAll() throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException {
if(directoryOwner)
- aquireWriteLock();
+ acquireWriteLock();
hasChanges = true;
doUndeleteAll();
}
/** Implements actual undeleteAll() in subclass. */
- protected abstract void doUndeleteAll() throws IOException;
+ protected abstract void doUndeleteAll() throws CorruptIndexException, IOException;
/**
* Should internally checkpoint state that will change
@@ -633,10 +711,9 @@
* If an exception is hit, then either no changes or all
* changes will have been committed to the index
* (transactional semantics).
- *
- * @throws IOException
+ * @throws IOException if there is a low-level IO error
*/
- protected final synchronized void commit() throws IOException{
+ protected final synchronized void commit() throws IOException {
if(hasChanges){
if (deleter == null) {
// In the MultiReader case, we share this deleter
@@ -716,12 +793,20 @@
* Closes files associated with this index.
* Also saves any new deletions to disk.
* No other methods should be called after this has been called.
+ * @throws IOException if this reader was closed already
+ * or there is a low-level IO error
*/
public final synchronized void close() throws IOException {
+ if (directoryOwner && isClosed) {
+ throw new IOException("this reader is already closed");
+ }
commit();
doClose();
if(closeDirectory)
directory.close();
+ if (directoryOwner) {
+ isClosed = true;
+ }
}
/** Implements close. */
@@ -753,7 +838,7 @@
* Returns true iff the index in the named directory is
* currently locked.
* @param directory the directory to check for a lock
- * @throws IOException if there is a problem with accessing the index
+ * @throws IOException if there is a low-level IO error
*/
public static boolean isLocked(Directory directory) throws IOException {
return
@@ -764,7 +849,7 @@
* Returns true iff the index in the named directory is
* currently locked.
* @param directory the directory to check for a lock
- * @throws IOException if there is a problem with accessing the index
+ * @throws IOException if there is a low-level IO error
*/
public static boolean isLocked(String directory) throws IOException {
Directory dir = FSDirectory.getDirectory(directory);
Index: src/java/org/apache/lucene/index/FilterIndexReader.java
===================================================================
--- src/java/org/apache/lucene/index/FilterIndexReader.java (revision 507871)
+++ src/java/org/apache/lucene/index/FilterIndexReader.java (working copy)
@@ -103,11 +103,11 @@
public int numDocs() { return in.numDocs(); }
public int maxDoc() { return in.maxDoc(); }
- public Document document(int n, FieldSelector fieldSelector) throws IOException { return in.document(n, fieldSelector); }
+ public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { return in.document(n, fieldSelector); }
public boolean isDeleted(int n) { return in.isDeleted(n); }
public boolean hasDeletions() { return in.hasDeletions(); }
- protected void doUndeleteAll() throws IOException { in.undeleteAll(); }
+ protected void doUndeleteAll() throws CorruptIndexException, IOException {in.undeleteAll();}
public boolean hasNorms(String field) throws IOException {
return in.hasNorms(field);
@@ -117,7 +117,7 @@
public void norms(String f, byte[] bytes, int offset) throws IOException {
in.norms(f, bytes, offset);
}
- protected void doSetNorm(int d, String f, byte b) throws IOException {
+ protected void doSetNorm(int d, String f, byte b) throws CorruptIndexException, IOException {
in.setNorm(d, f, b);
}
@@ -132,7 +132,7 @@
return in.termPositions();
}
- protected void doDelete(int n) throws IOException { in.deleteDocument(n); }
+ protected void doDelete(int n) throws CorruptIndexException, IOException { in.deleteDocument(n); }
protected void doCommit() throws IOException { in.commit(); }
protected void doClose() throws IOException { in.close(); }
@@ -142,5 +142,5 @@
}
public long getVersion() { return in.getVersion(); }
- public boolean isCurrent() throws IOException { return in.isCurrent(); }
+ public boolean isCurrent() throws CorruptIndexException, IOException { return in.isCurrent(); }
}
Index: src/java/org/apache/lucene/index/TermVectorsReader.java
===================================================================
--- src/java/org/apache/lucene/index/TermVectorsReader.java (revision 507871)
+++ src/java/org/apache/lucene/index/TermVectorsReader.java (working copy)
@@ -37,7 +37,7 @@
private int tvfFormat;
TermVectorsReader(Directory d, String segment, FieldInfos fieldInfos)
- throws IOException {
+ throws CorruptIndexException, IOException {
if (d.fileExists(segment + TermVectorsWriter.TVX_EXTENSION)) {
tvx = d.openInput(segment + TermVectorsWriter.TVX_EXTENSION);
checkValidFormat(tvx);
@@ -51,13 +51,13 @@
this.fieldInfos = fieldInfos;
}
- private int checkValidFormat(IndexInput in) throws IOException
+ private int checkValidFormat(IndexInput in) throws CorruptIndexException, IOException
{
int format = in.readInt();
if (format > TermVectorsWriter.FORMAT_VERSION)
{
- throw new IOException("Incompatible format version: " + format + " expected "
- + TermVectorsWriter.FORMAT_VERSION + " or less");
+ throw new CorruptIndexException("Incompatible format version: " + format + " expected "
+ + TermVectorsWriter.FORMAT_VERSION + " or less");
}
return format;
}
Index: src/java/org/apache/lucene/index/SegmentInfos.java
===================================================================
--- src/java/org/apache/lucene/index/SegmentInfos.java (revision 507871)
+++ src/java/org/apache/lucene/index/SegmentInfos.java (working copy)
@@ -173,8 +173,10 @@
*
* @param directory -- directory containing the segments file
* @param segmentFileName -- segment file to load
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public final void read(Directory directory, String segmentFileName) throws IOException {
+ public final void read(Directory directory, String segmentFileName) throws CorruptIndexException, IOException {
boolean success = false;
IndexInput input = directory.openInput(segmentFileName);
@@ -192,7 +194,7 @@
if(format < 0){ // file contains explicit format info
// check that it is a format we can understand
if (format < FORMAT_SINGLE_NORM_FILE)
- throw new IOException("Unknown format version: " + format);
+ throw new CorruptIndexException("Unknown format version: " + format);
version = input.readLong(); // read version
counter = input.readInt(); // read counter
}
@@ -224,14 +226,16 @@
/**
* This version of read uses the retry logic (for lock-less
* commits) to find the right segments file to load.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public final void read(Directory directory) throws IOException {
+ public final void read(Directory directory) throws CorruptIndexException, IOException {
generation = lastGeneration = -1;
new FindSegmentsFile(directory) {
- public Object doBody(String segmentFileName) throws IOException {
+ public Object doBody(String segmentFileName) throws CorruptIndexException, IOException {
read(directory, segmentFileName);
return null;
}
@@ -304,12 +308,14 @@
/**
* Current version number from segments file.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
public static long readCurrentVersion(Directory directory)
- throws IOException {
+ throws CorruptIndexException, IOException {
return ((Long) new FindSegmentsFile(directory) {
- public Object doBody(String segmentFileName) throws IOException {
+ public Object doBody(String segmentFileName) throws CorruptIndexException, IOException {
IndexInput input = directory.openInput(segmentFileName);
@@ -319,7 +325,7 @@
format = input.readInt();
if(format < 0){
if (format < FORMAT_SINGLE_NORM_FILE)
- throw new IOException("Unknown format version: " + format);
+ throw new CorruptIndexException("Unknown format version: " + format);
version = input.readLong(); // read version
}
}
@@ -436,7 +442,7 @@
this.directory = directory;
}
- public Object run() throws IOException {
+ public Object run() throws CorruptIndexException, IOException {
String segmentFileName = null;
long lastGen = -1;
long gen = 0;
@@ -624,5 +630,5 @@
* during the processing that could have been caused by
* a writer committing.
*/
- protected abstract Object doBody(String segmentFileName) throws IOException;}
+ protected abstract Object doBody(String segmentFileName) throws CorruptIndexException, IOException;}
}
Index: src/java/org/apache/lucene/index/TermInfosWriter.java
===================================================================
--- src/java/org/apache/lucene/index/TermInfosWriter.java (revision 507871)
+++ src/java/org/apache/lucene/index/TermInfosWriter.java (working copy)
@@ -91,15 +91,15 @@
Term must be lexicographically greater than all previous Terms added.
TermInfo pointers must be positive and greater than all previous.*/
final void add(Term term, TermInfo ti)
- throws IOException {
+ throws CorruptIndexException, IOException {
if (!isIndex && term.compareTo(lastTerm) <= 0)
- throw new IOException("term out of order (\"" + term +
+ throw new CorruptIndexException("term out of order (\"" + term +
"\".compareTo(\"" + lastTerm + "\") <= 0)");
if (ti.freqPointer < lastTi.freqPointer)
- throw new IOException("freqPointer out of order (" + ti.freqPointer +
+ throw new CorruptIndexException("freqPointer out of order (" + ti.freqPointer +
" < " + lastTi.freqPointer + ")");
if (ti.proxPointer < lastTi.proxPointer)
- throw new IOException("proxPointer out of order (" + ti.proxPointer +
+ throw new CorruptIndexException("proxPointer out of order (" + ti.proxPointer +
" < " + lastTi.proxPointer + ")");
if (!isIndex && size % indexInterval == 0)
Index: src/java/org/apache/lucene/index/SegmentMerger.java
===================================================================
--- src/java/org/apache/lucene/index/SegmentMerger.java (revision 507871)
+++ src/java/org/apache/lucene/index/SegmentMerger.java (working copy)
@@ -87,9 +87,10 @@
/**
* Merges the readers specified by the {@link #add} method into the directory passed to the constructor
* @return The number of documents that were merged
- * @throws IOException
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- final int merge() throws IOException {
+ final int merge() throws CorruptIndexException, IOException {
int value;
value = mergeFields();
@@ -167,9 +168,10 @@
/**
*
* @return The number of documents in all of the readers
- * @throws IOException
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- private final int mergeFields() throws IOException {
+ private final int mergeFields() throws CorruptIndexException, IOException {
fieldInfos = new FieldInfos(); // merge field names
int docCount = 0;
for (int i = 0; i < readers.size(); i++) {
@@ -240,7 +242,7 @@
private int skipInterval;
private SegmentMergeQueue queue = null;
- private final void mergeTerms() throws IOException {
+ private final void mergeTerms() throws CorruptIndexException, IOException {
try {
freqOutput = directory.createOutput(segment + ".frq");
proxOutput = directory.createOutput(segment + ".prx");
@@ -260,7 +262,7 @@
}
}
- private final void mergeTermInfos() throws IOException {
+ private final void mergeTermInfos() throws CorruptIndexException, IOException {
int base = 0;
for (int i = 0; i < readers.size(); i++) {
IndexReader reader = (IndexReader) readers.elementAt(i);
@@ -306,9 +308,11 @@
*
* @param smis array of segments
* @param n number of cells in the array actually occupied
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
private final void mergeTermInfo(SegmentMergeInfo[] smis, int n)
- throws IOException {
+ throws CorruptIndexException, IOException {
long freqPointer = freqOutput.getFilePointer();
long proxPointer = proxOutput.getFilePointer();
@@ -330,9 +334,11 @@
* @param smis array of segments
* @param n number of cells in the array actually occupied
* @return number of documents across all segments where this term was found
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
private final int appendPostings(SegmentMergeInfo[] smis, int n)
- throws IOException {
+ throws CorruptIndexException, IOException {
int lastDoc = 0;
int df = 0; // number of docs w/ term
resetSkip();
@@ -349,7 +355,7 @@
doc += base; // convert to merged space
if (doc < 0 || (df > 0 && doc <= lastDoc))
- throw new IllegalStateException("docs out of order (" + doc +
+ throw new CorruptIndexException("docs out of order (" + doc +
" <= " + lastDoc + " )");
df++;
Index: src/java/org/apache/lucene/index/IndexWriter.java
===================================================================
--- src/java/org/apache/lucene/index/IndexWriter.java (revision 507871)
+++ src/java/org/apache/lucene/index/IndexWriter.java (working copy)
@@ -25,6 +25,7 @@
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.store.Lock;
+import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;
import java.io.File;
@@ -57,7 +58,8 @@
method should be called before the index is closed.
Opening an IndexWriter creates a lock file for the directory in use. Trying to open - another IndexWriter on the same directory will lead to an IOException. The IOException + another IndexWriter on the same directory will lead to a + {@link LockObtainFailedException}. The {@link LockObtainFailedException} is also thrown if an IndexReader on the same directory is used to delete documents from the index.
@@ -227,12 +229,17 @@ * @param createtrue to create the index or overwrite
* the existing one; false to append to the existing
* index
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
* @throws IOException if the directory cannot be read/written to, or
- * if it does not exist, and create is
- * false
+ * if it does not exist and create is
+ * false or if there is any other low-level
+ * IO error
*/
public IndexWriter(String path, Analyzer a, boolean create)
- throws IOException {
+ throws CorruptIndexException, LockObtainFailedException, IOException {
init(path, a, create);
}
@@ -247,12 +254,17 @@
* @param create true to create the index or overwrite
* the existing one; false to append to the existing
* index
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
* @throws IOException if the directory cannot be read/written to, or
- * if it does not exist, and create is
- * false
+ * if it does not exist and create is
+ * false or if there is any other low-level
+ * IO error
*/
public IndexWriter(File path, Analyzer a, boolean create)
- throws IOException {
+ throws CorruptIndexException, LockObtainFailedException, IOException {
init(path, a, create);
}
@@ -267,12 +279,17 @@
* @param create true to create the index or overwrite
* the existing one; false to append to the existing
* index
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
* @throws IOException if the directory cannot be read/written to, or
- * if it does not exist, and create is
- * false
+ * if it does not exist and create is
+ * false or if there is any other low-level
+ * IO error
*/
public IndexWriter(Directory d, Analyzer a, boolean create)
- throws IOException {
+ throws CorruptIndexException, LockObtainFailedException, IOException {
init(d, a, create, false);
}
@@ -284,11 +301,16 @@
*
* @param path the path to the index directory
* @param a the analyzer to use
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
* @throws IOException if the directory cannot be
- * created or read/written to
+ * read/written to or if there is any other low-level
+ * IO error
*/
public IndexWriter(String path, Analyzer a)
- throws IOException {
+ throws CorruptIndexException, LockObtainFailedException, IOException {
if (IndexReader.indexExists(path)) {
init(path, a, false);
} else {
@@ -305,11 +327,16 @@
*
* @param path the path to the index directory
* @param a the analyzer to use
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
* @throws IOException if the directory cannot be
- * created or read/written to
+ * read/written to or if there is any other low-level
+ * IO error
*/
public IndexWriter(File path, Analyzer a)
- throws IOException {
+ throws CorruptIndexException, LockObtainFailedException, IOException {
if (IndexReader.indexExists(path)) {
init(path, a, false);
} else {
@@ -325,11 +352,16 @@
*
* @param d the index directory
* @param a the analyzer to use
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
* @throws IOException if the directory cannot be
- * created or read/written to
+ * read/written to or if there is any other low-level
+ * IO error
*/
public IndexWriter(Directory d, Analyzer a)
- throws IOException {
+ throws CorruptIndexException, LockObtainFailedException, IOException {
if (IndexReader.indexExists(d)) {
init(d, a, false, false);
} else {
@@ -338,22 +370,22 @@
}
private IndexWriter(Directory d, Analyzer a, final boolean create, boolean closeDir)
- throws IOException {
+ throws CorruptIndexException, LockObtainFailedException, IOException {
init(d, a, create, closeDir);
}
private void init(String path, Analyzer a, final boolean create)
- throws IOException {
+ throws CorruptIndexException, LockObtainFailedException, IOException {
init(FSDirectory.getDirectory(path), a, create, true);
}
private void init(File path, Analyzer a, final boolean create)
- throws IOException {
+ throws CorruptIndexException, LockObtainFailedException, IOException {
init(FSDirectory.getDirectory(path), a, create, true);
}
private void init(Directory d, Analyzer a, final boolean create, boolean closeDir)
- throws IOException {
+ throws CorruptIndexException, LockObtainFailedException, IOException {
this.closeDir = closeDir;
directory = d;
analyzer = a;
@@ -365,7 +397,7 @@
Lock writeLock = directory.makeLock(IndexWriter.WRITE_LOCK_NAME);
if (!writeLock.obtain(writeLockTimeout)) // obtain write lock
- throw new IOException("Index locked for write: " + writeLock);
+ throw new LockObtainFailedException("Index locked for write: " + writeLock);
this.writeLock = writeLock; // save it
try {
@@ -583,8 +615,10 @@
*
* after which, you must be certain not to use the writer
* instance anymore.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public synchronized void close() throws IOException {
+ public synchronized void close() throws CorruptIndexException, IOException {
flushRamSegments();
ramDirectory.close();
if (writeLock != null) {
@@ -675,8 +709,11 @@
* segments in the index, which is the worst case for
* temporary space usage) then the maximum free disk space
* required is the same as {@link #optimize}.
+ *
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public void addDocument(Document doc) throws IOException {
+ public void addDocument(Document doc) throws CorruptIndexException, IOException {
addDocument(doc, analyzer);
}
@@ -689,8 +726,11 @@
* See {@link #addDocument(Document)} for details on * index and IndexWriter state after an Exception, and * flushing/merging temporary free space requirements.
+ * + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error */ - public void addDocument(Document doc, Analyzer analyzer) throws IOException { + public void addDocument(Document doc, Analyzer analyzer) throws CorruptIndexException, IOException { SegmentInfo newSegmentInfo = buildSingleDocSegment(doc, analyzer); synchronized (this) { ramSegmentInfos.addElement(newSegmentInfo); @@ -699,7 +739,7 @@ } SegmentInfo buildSingleDocSegment(Document doc, Analyzer analyzer) - throws IOException { + throws CorruptIndexException, IOException { DocumentWriter dw = new DocumentWriter(ramDirectory, analyzer, this); dw.setInfoStream(infoStream); String segmentName = newRamSegmentName(); @@ -710,8 +750,10 @@ /** * Deletes the document(s) containingterm.
* @param term the term to identify the documents to be deleted
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public synchronized void deleteDocuments(Term term) throws IOException {
+ public synchronized void deleteDocuments(Term term) throws CorruptIndexException, IOException {
bufferDeleteTerm(term);
maybeFlushRamSegments();
}
@@ -721,8 +763,10 @@
* terms. All deletes are flushed at the same time.
* @param terms array of terms to identify the documents
* to be deleted
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public synchronized void deleteDocuments(Term[] terms) throws IOException {
+ public synchronized void deleteDocuments(Term[] terms) throws CorruptIndexException, IOException {
for (int i = 0; i < terms.length; i++) {
bufferDeleteTerm(terms[i]);
}
@@ -738,8 +782,10 @@
* @param term the term to identify the document(s) to be
* deleted
* @param doc the document to be added
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public void updateDocument(Term term, Document doc) throws IOException {
+ public void updateDocument(Term term, Document doc) throws CorruptIndexException, IOException {
updateDocument(term, doc, getAnalyzer());
}
@@ -753,9 +799,11 @@
* deleted
* @param doc the document to be added
* @param analyzer the analyzer to use when analyzing the document
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
public void updateDocument(Term term, Document doc, Analyzer analyzer)
- throws IOException {
+ throws CorruptIndexException, IOException {
SegmentInfo newSegmentInfo = buildSingleDocSegment(doc, analyzer);
synchronized (this) {
bufferDeleteTerm(term);
@@ -886,8 +934,10 @@
* using compound file format. This will occur when the
* Exception is hit during conversion of the segment into
* compound format.
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public synchronized void optimize() throws IOException {
+ public synchronized void optimize() throws CorruptIndexException, IOException {
flushRamSegments();
while (segmentInfos.size() > 1 ||
(segmentInfos.size() == 1 &&
@@ -1023,9 +1073,11 @@
* See LUCENE-702 * for details.
+ * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error */ public synchronized void addIndexes(Directory[] dirs) - throws IOException { + throws CorruptIndexException, IOException { optimize(); // start with zero or 1 seg @@ -1079,9 +1131,11 @@ * details on transactional semantics, temporary free * space required in the Directory, and non-CFS segments * on an Exception. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error */ public synchronized void addIndexesNoOptimize(Directory[] dirs) - throws IOException { + throws CorruptIndexException, IOException { // Adding indexes can be viewed as adding a sequence of segments S to // a sequence of segments T. Segments in T follow the invariants but // segments in S may not since they could come from multiple indexes. @@ -1215,9 +1269,11 @@ * details on transactional semantics, temporary free * space required in the Directory, and non-CFS segments * on an Exception. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error */ public synchronized void addIndexes(IndexReader[] readers) - throws IOException { + throws CorruptIndexException, IOException { optimize(); // start with zero or 1 seg @@ -1337,7 +1393,7 @@ throws IOException { } - protected final void maybeFlushRamSegments() throws IOException { + protected final void maybeFlushRamSegments() throws CorruptIndexException, IOException { // A flush is triggered if enough new documents are buffered or // if enough delete terms are buffered if (ramSegmentInfos.size() >= minMergeDocs || numBufferedDeleteTerms >= maxBufferedDeleteTerms) { @@ -1346,7 +1402,7 @@ } /** Expert: Flushes all RAM-resident segments (buffered documents), then may merge segments. */ - private final synchronized void flushRamSegments() throws IOException { + private final synchronized void flushRamSegments() throws CorruptIndexException, IOException { if (ramSegmentInfos.size() > 0 || bufferedDeleteTerms.size() > 0) { mergeSegments(ramSegmentInfos, 0, ramSegmentInfos.size()); maybeMergeSegments(minMergeDocs); @@ -1356,9 +1412,10 @@ /** * Flush all in-memory buffered updates (adds and deletes) * to the Directory. - * @throws IOException + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error */ - public final synchronized void flush() throws IOException { + public final synchronized void flush() throws CorruptIndexException, IOException { flushRamSegments(); } @@ -1377,7 +1434,7 @@ } /** Incremental segment merger. */ - private final void maybeMergeSegments(int startUpperBound) throws IOException { + private final void maybeMergeSegments(int startUpperBound) throws CorruptIndexException, IOException { long lowerBound = -1; long upperBound = startUpperBound; @@ -1442,7 +1499,7 @@ * single segment. */ private final int mergeSegments(SegmentInfos sourceSegments, int minSegment, int end) - throws IOException { + throws CorruptIndexException, IOException { // We may be called solely because there are deletes // pending, in which case doMerge is false: @@ -1631,7 +1688,7 @@ // Called during flush to apply any buffered deletes. If // doMerge is true then a new segment was just created and // flushed from the ram segments. - private final void maybeApplyDeletes(boolean doMerge) throws IOException { + private final void maybeApplyDeletes(boolean doMerge) throws CorruptIndexException, IOException { if (bufferedDeleteTerms.size() > 0) { if (infoStream != null) @@ -1743,7 +1800,7 @@ // apply appropriately so that a delete term is only applied to // the documents buffered before it, not those buffered after it. private final void applyDeletesSelectively(HashMap deleteTerms, - IndexReader reader) throws IOException { + IndexReader reader) throws CorruptIndexException, IOException { Iterator iter = deleteTerms.entrySet().iterator(); while (iter.hasNext()) { Entry entry = (Entry) iter.next(); @@ -1769,7 +1826,7 @@ // Apply buffered delete terms to this reader. private final void applyDeletes(HashMap deleteTerms, IndexReader reader) - throws IOException { + throws CorruptIndexException, IOException { Iterator iter = deleteTerms.entrySet().iterator(); while (iter.hasNext()) { Entry entry = (Entry) iter.next(); Index: src/java/org/apache/lucene/index/CorruptIndexException.java =================================================================== --- src/java/org/apache/lucene/index/CorruptIndexException.java (revision 0) +++ src/java/org/apache/lucene/index/CorruptIndexException.java (revision 0) @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.index; + +import java.io.IOException; + +/** + * This exception is thrown when Lucene detects + * an inconsistency in the index. + */ +public class CorruptIndexException extends IOException { + public CorruptIndexException(String message) { + super(message); + } +} Index: src/java/org/apache/lucene/index/StaleReaderException.java =================================================================== --- src/java/org/apache/lucene/index/StaleReaderException.java (revision 0) +++ src/java/org/apache/lucene/index/StaleReaderException.java (revision 0) @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.index; + +import java.io.IOException; + +/** + * This exception is thrown when an {@link IndexReader} + * tries to make changes to the index (via {@link + * IndexReader#deleteDocument}, {@link + * IndexReader#undeleteAll} or {@link IndexReader#setNorm}) + * but changes have already been committed to the index + * since this reader was instantiated. When this happens + * you must open a new reader on the current index to make + * the changes. + */ +public class StaleReaderException extends IOException { + public StaleReaderException(String message) { + super(message); + } +} Index: src/java/org/apache/lucene/index/DocumentWriter.java =================================================================== --- src/java/org/apache/lucene/index/DocumentWriter.java (revision 507871) +++ src/java/org/apache/lucene/index/DocumentWriter.java (working copy) @@ -68,7 +68,7 @@ } final void addDocument(String segment, Document doc) - throws IOException { + throws CorruptIndexException, IOException { // write field names fieldInfos = new FieldInfos(); fieldInfos.add(doc); @@ -295,7 +295,7 @@ } private final void writePostings(Posting[] postings, String segment) - throws IOException { + throws CorruptIndexException, IOException { IndexOutput freq = null, prox = null; TermInfosWriter tis = null; TermVectorsWriter termVectorWriter = null; Index: src/java/org/apache/lucene/index/ParallelReader.java =================================================================== --- src/java/org/apache/lucene/index/ParallelReader.java (revision 507871) +++ src/java/org/apache/lucene/index/ParallelReader.java (working copy) @@ -124,7 +124,7 @@ } // delete in all readers - protected void doDelete(int n) throws IOException { + protected void doDelete(int n) throws CorruptIndexException, IOException { for (int i = 0; i < readers.size(); i++) { ((IndexReader)readers.get(i)).deleteDocument(n); } @@ -132,7 +132,7 @@ } // undeleteAll in all readers - protected void doUndeleteAll() throws IOException { + protected void doUndeleteAll() throws CorruptIndexException, IOException { for (int i = 0; i < readers.size(); i++) { ((IndexReader)readers.get(i)).undeleteAll(); } @@ -140,7 +140,7 @@ } // append fields from storedFieldReaders - public Document document(int n, FieldSelector fieldSelector) throws IOException { + public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { Document result = new Document(); for (int i = 0; i < storedFieldReaders.size(); i++) { IndexReader reader = (IndexReader)storedFieldReaders.get(i); @@ -204,7 +204,7 @@ } protected void doSetNorm(int n, String field, byte value) - throws IOException { + throws CorruptIndexException, IOException { IndexReader reader = ((IndexReader)fieldToReader.get(field)); if (reader!=null) reader.doSetNorm(n, field, value); Index: src/java/org/apache/lucene/index/SegmentReader.java =================================================================== --- src/java/org/apache/lucene/index/SegmentReader.java (revision 507871) +++ src/java/org/apache/lucene/index/SegmentReader.java (working copy) @@ -117,19 +117,31 @@ protected SegmentReader() { super(null); } - public static SegmentReader get(SegmentInfo si) throws IOException { + /** + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + public static SegmentReader get(SegmentInfo si) throws CorruptIndexException, IOException { return get(si.dir, si, null, false, false); } + /** + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ public static SegmentReader get(SegmentInfos sis, SegmentInfo si, - boolean closeDir) throws IOException { + boolean closeDir) throws CorruptIndexException, IOException { return get(si.dir, si, sis, closeDir, true); } + /** + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ public static SegmentReader get(Directory dir, SegmentInfo si, SegmentInfos sis, boolean closeDir, boolean ownDir) - throws IOException { + throws CorruptIndexException, IOException { SegmentReader instance; try { instance = (SegmentReader)IMPL.newInstance(); @@ -141,7 +153,7 @@ return instance; } - private void initialize(SegmentInfo si) throws IOException { + private void initialize(SegmentInfo si) throws CorruptIndexException, IOException { segment = si.name; this.si = si; @@ -161,7 +173,7 @@ // Verify two sources of "maxDoc" agree: if (fieldsReader.size() != si.docCount) { - throw new IllegalStateException("doc counts differ for segment " + si.name + ": fieldsReader shows " + fieldsReader.size() + " but segmentInfo shows " + si.docCount); + throw new CorruptIndexException("doc counts differ for segment " + si.name + ": fieldsReader shows " + fieldsReader.size() + " but segmentInfo shows " + si.docCount); } tis = new TermInfosReader(cfsDir, segment, fieldInfos); @@ -172,7 +184,7 @@ // Verify # deletes does not exceed maxDoc for this segment: if (deletedDocs.count() > maxDoc()) { - throw new IllegalStateException("number of deletes (" + deletedDocs.count() + ") exceeds max doc (" + maxDoc() + ") for segment " + si.name); + throw new CorruptIndexException("number of deletes (" + deletedDocs.count() + ") exceeds max doc (" + maxDoc() + ") for segment " + si.name); } } @@ -335,7 +347,11 @@ return tis.terms(t); } - public synchronized Document document(int n, FieldSelector fieldSelector) throws IOException { + /** + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + public synchronized Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { if (isDeleted(n)) throw new IllegalArgumentException ("attempt to access a deleted document"); Index: src/java/org/apache/lucene/index/IndexModifier.java =================================================================== --- src/java/org/apache/lucene/index/IndexModifier.java (revision 507871) +++ src/java/org/apache/lucene/index/IndexModifier.java (working copy) @@ -21,6 +21,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; +import org.apache.lucene.store.LockObtainFailedException; import java.io.File; import java.io.IOException; @@ -112,8 +113,13 @@ * @param analyzer the analyzer to use for adding new documents * @param createtrue to create the index or overwrite the existing one;
* false to append to the existing index
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- public IndexModifier(Directory directory, Analyzer analyzer, boolean create) throws IOException {
+ public IndexModifier(Directory directory, Analyzer analyzer, boolean create) throws CorruptIndexException, LockObtainFailedException, IOException {
init(directory, analyzer, create);
}
@@ -124,8 +130,13 @@
* @param analyzer the analyzer to use for adding new documents
* @param create true to create the index or overwrite the existing one;
* false to append to the existing index
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- public IndexModifier(String dirName, Analyzer analyzer, boolean create) throws IOException {
+ public IndexModifier(String dirName, Analyzer analyzer, boolean create) throws CorruptIndexException, LockObtainFailedException, IOException {
Directory dir = FSDirectory.getDirectory(dirName);
init(dir, analyzer, create);
}
@@ -137,17 +148,26 @@
* @param analyzer the analyzer to use for adding new documents
* @param create true to create the index or overwrite the existing one;
* false to append to the existing index
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- public IndexModifier(File file, Analyzer analyzer, boolean create) throws IOException {
+ public IndexModifier(File file, Analyzer analyzer, boolean create) throws CorruptIndexException, LockObtainFailedException, IOException {
Directory dir = FSDirectory.getDirectory(file);
init(dir, analyzer, create);
}
/**
* Initialize an IndexWriter.
- * @throws IOException
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- protected void init(Directory directory, Analyzer analyzer, boolean create) throws IOException {
+ protected void init(Directory directory, Analyzer analyzer, boolean create) throws CorruptIndexException, LockObtainFailedException, IOException {
this.directory = directory;
synchronized(this.directory) {
this.analyzer = analyzer;
@@ -168,9 +188,13 @@
/**
* Close the IndexReader and open an IndexWriter.
- * @throws IOException
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- protected void createIndexWriter() throws IOException {
+ protected void createIndexWriter() throws CorruptIndexException, LockObtainFailedException, IOException {
if (indexWriter == null) {
if (indexReader != null) {
indexReader.close();
@@ -187,9 +211,10 @@
/**
* Close the IndexWriter and open an IndexReader.
- * @throws IOException
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- protected void createIndexReader() throws IOException {
+ protected void createIndexReader() throws CorruptIndexException, IOException {
if (indexReader == null) {
if (indexWriter != null) {
indexWriter.close();
@@ -201,9 +226,13 @@
/**
* Make sure all changes are written to disk.
- * @throws IOException
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- public void flush() throws IOException {
+ public void flush() throws CorruptIndexException, LockObtainFailedException, IOException {
synchronized(directory) {
assureOpen();
if (indexWriter != null) {
@@ -225,8 +254,13 @@
* discarded.
* @see IndexWriter#addDocument(Document, Analyzer)
* @throws IllegalStateException if the index is closed
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- public void addDocument(Document doc, Analyzer docAnalyzer) throws IOException {
+ public void addDocument(Document doc, Analyzer docAnalyzer) throws CorruptIndexException, LockObtainFailedException, IOException {
synchronized(directory) {
assureOpen();
createIndexWriter();
@@ -243,8 +277,13 @@
* discarded.
* @see IndexWriter#addDocument(Document)
* @throws IllegalStateException if the index is closed
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- public void addDocument(Document doc) throws IOException {
+ public void addDocument(Document doc) throws CorruptIndexException, LockObtainFailedException, IOException {
addDocument(doc, null);
}
@@ -257,8 +296,15 @@
* @return the number of documents deleted
* @see IndexReader#deleteDocuments(Term)
* @throws IllegalStateException if the index is closed
+ * @throws StaleReaderException if the index has changed
+ * since this reader was opened
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- public int deleteDocuments(Term term) throws IOException {
+ public int deleteDocuments(Term term) throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException {
synchronized(directory) {
assureOpen();
createIndexReader();
@@ -269,9 +315,15 @@
/**
* Deletes the document numbered docNum.
* @see IndexReader#deleteDocument(int)
+ * @throws StaleReaderException if the index has changed
+ * since this reader was opened
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
* @throws IllegalStateException if the index is closed
*/
- public void deleteDocument(int docNum) throws IOException {
+ public void deleteDocument(int docNum) throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException {
synchronized(directory) {
assureOpen();
createIndexReader();
@@ -302,8 +354,13 @@
* for search.
* @see IndexWriter#optimize()
* @throws IllegalStateException if the index is closed
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- public void optimize() throws IOException {
+ public void optimize() throws CorruptIndexException, LockObtainFailedException, IOException {
synchronized(directory) {
assureOpen();
createIndexWriter();
@@ -329,10 +386,14 @@
}
/**
- * @throws IOException
* @see IndexModifier#setInfoStream(PrintStream)
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- public PrintStream getInfoStream() throws IOException {
+ public PrintStream getInfoStream() throws CorruptIndexException, LockObtainFailedException, IOException {
synchronized(directory) {
assureOpen();
createIndexWriter();
@@ -358,10 +419,14 @@
}
/**
- * @throws IOException
* @see IndexModifier#setUseCompoundFile(boolean)
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- public boolean getUseCompoundFile() throws IOException {
+ public boolean getUseCompoundFile() throws CorruptIndexException, LockObtainFailedException, IOException {
synchronized(directory) {
assureOpen();
createIndexWriter();
@@ -394,10 +459,14 @@
}
/**
- * @throws IOException
* @see IndexModifier#setMaxFieldLength(int)
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- public int getMaxFieldLength() throws IOException {
+ public int getMaxFieldLength() throws CorruptIndexException, LockObtainFailedException, IOException {
synchronized(directory) {
assureOpen();
createIndexWriter();
@@ -429,10 +498,14 @@
}
/**
- * @throws IOException
* @see IndexModifier#setMaxBufferedDocs(int)
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- public int getMaxBufferedDocs() throws IOException {
+ public int getMaxBufferedDocs() throws CorruptIndexException, LockObtainFailedException, IOException {
synchronized(directory) {
assureOpen();
createIndexWriter();
@@ -464,10 +537,14 @@
}
/**
- * @throws IOException
* @see IndexModifier#setMergeFactor(int)
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws LockObtainFailedException if another writer
+ * has this index open (write.lock could not
+ * be obtained)
+ * @throws IOException if there is a low-level IO error
*/
- public int getMergeFactor() throws IOException {
+ public int getMergeFactor() throws CorruptIndexException, LockObtainFailedException, IOException {
synchronized(directory) {
assureOpen();
createIndexWriter();
@@ -479,8 +556,10 @@
* Close this index, writing all pending changes to disk.
*
* @throws IllegalStateException if the index has been closed before already
+ * @throws CorruptIndexException if the index is corrupt
+ * @throws IOException if there is a low-level IO error
*/
- public void close() throws IOException {
+ public void close() throws CorruptIndexException, IOException {
synchronized(directory) {
if (!open)
throw new IllegalStateException("Index is closed already");
Index: src/java/org/apache/lucene/store/Directory.java
===================================================================
--- src/java/org/apache/lucene/store/Directory.java (revision 507871)
+++ src/java/org/apache/lucene/store/Directory.java (working copy)
@@ -94,7 +94,7 @@
* Attempt to clear (forcefully unlock and remove) the
* specified lock. Only call this at a time when you are
* certain this lock is no longer in use.
- * @param lockName name of the lock to be cleared.
+ * @param name name of the lock to be cleared.
*/
public void clearLock(String name) throws IOException {
if (lockFactory != null) {
Index: src/java/org/apache/lucene/store/LockObtainFailedException.java
===================================================================
--- src/java/org/apache/lucene/store/LockObtainFailedException.java (revision 0)
+++ src/java/org/apache/lucene/store/LockObtainFailedException.java (revision 0)
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.store;
+
+import java.io.IOException;
+
+/**
+ * This exception is thrown when the write.lock
+ * could not be acquired. This
+ * happens when a writer tries to open an index
+ * that another writer already has open.
+ * @see Lock#obtain(long).
+ */
+public class LockObtainFailedException extends IOException {
+ public LockObtainFailedException(String message) {
+ super(message);
+ }
+}
Index: src/java/org/apache/lucene/store/Lock.java
===================================================================
--- src/java/org/apache/lucene/store/Lock.java (revision 507871)
+++ src/java/org/apache/lucene/store/Lock.java (working copy)
@@ -53,9 +53,10 @@
* lockWaitTimeout is passed.
* @param lockWaitTimeout length of time to wait in ms
* @return true if lock was obtained
- * @throws IOException if lock wait times out or obtain() throws an IOException
+ * @throws LockObtainFailedException if lock wait times out
+ * @throws IOException if obtain() throws IOException
*/
- public boolean obtain(long lockWaitTimeout) throws IOException {
+ public boolean obtain(long lockWaitTimeout) throws LockObtainFailedException, IOException {
failureReason = null;
boolean locked = obtain();
int maxSleepCount = (int)(lockWaitTimeout / LOCK_POLL_INTERVAL);
@@ -66,7 +67,7 @@
if (failureReason != null) {
reason += ": " + failureReason;
}
- IOException e = new IOException(reason);
+ LockObtainFailedException e = new LockObtainFailedException(reason);
if (failureReason != null) {
e.initCause(failureReason);
}
@@ -108,8 +109,12 @@
/** Calls {@link #doBody} while lock is obtained. Blocks if lock
* cannot be obtained immediately. Retries to obtain lock once per second
* until it is obtained, or until it has tried ten times. Lock is released when
- * {@link #doBody} exits. */
- public Object run() throws IOException {
+ * {@link #doBody} exits.
+ * @throws LockObtainFailedException if lock could not
+ * be obtained
+ * @throws IOException if {@link Lock#obtain} throws IOException
+ */
+ public Object run() throws LockObtainFailedException, IOException {
boolean locked = false;
try {
locked = lock.obtain(lockWaitTimeout);