LUCENE-3660: release write lock if IW hits a non-ioexception from IR.indexExists

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1222367 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2011-12-22 17:36:24 +00:00
parent 6a6d33257e
commit 53fef3a0ac
2 changed files with 50 additions and 14 deletions

View File

@ -862,22 +862,23 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
if (!writeLock.obtain(conf.getWriteLockTimeout())) // obtain write lock
throw new LockObtainFailedException("Index locked for write: " + writeLock);
OpenMode mode = conf.getOpenMode();
boolean create;
if (mode == OpenMode.CREATE) {
create = true;
} else if (mode == OpenMode.APPEND) {
create = false;
} else {
// CREATE_OR_APPEND - create only if an index does not exist
create = !IndexReader.indexExists(directory);
}
boolean success = false;
// If index is too old, reading the segments will throw
// IndexFormatTooOldException.
segmentInfos = new SegmentInfos();
try {
OpenMode mode = conf.getOpenMode();
boolean create;
if (mode == OpenMode.CREATE) {
create = true;
} else if (mode == OpenMode.APPEND) {
create = false;
} else {
// CREATE_OR_APPEND - create only if an index does not exist
create = !IndexReader.indexExists(directory);
}
// If index is too old, reading the segments will throw
// IndexFormatTooOldException.
segmentInfos = new SegmentInfos();
if (create) {
// Try to read first. This is to allow create
// against an index that's currently open for

View File

@ -37,6 +37,7 @@ import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IOContext;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.store.MockDirectoryWrapper;
@ -1459,4 +1460,38 @@ public class TestIndexWriterExceptions extends LuceneTestCase {
r.close();
dir.close();
}
static class UOEDirectory extends RAMDirectory {
boolean doFail = false;
@Override
public IndexInput openInput(String name, IOContext context) throws IOException {
if (doFail && name.startsWith("segments_")) {
StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if ("indexExists".equals(trace[i].getMethodName())) {
throw new UnsupportedOperationException("expected UOE");
}
}
}
return super.openInput(name, context);
}
}
public void testExceptionOnCtor() throws Exception {
UOEDirectory uoe = new UOEDirectory();
Directory d = new MockDirectoryWrapper(random, uoe);
IndexWriter iw = new IndexWriter(d, newIndexWriterConfig(TEST_VERSION_CURRENT, null));
iw.addDocument(new Document());
iw.close();
uoe.doFail = true;
try {
new IndexWriter(d, newIndexWriterConfig(TEST_VERSION_CURRENT, null));
fail("should have gotten a UOE");
} catch (UnsupportedOperationException expected) {
}
uoe.doFail = false;
d.close();
}
}