LUCENE-1143: clear docStoreOffset when DocumentsWriter aborts

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@613606 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2008-01-20 16:50:58 +00:00
parent 354a3175d5
commit 17fede30c0
4 changed files with 88 additions and 14 deletions

View File

@ -423,6 +423,8 @@ final class DocumentsWriter {
resetPostingsData(); resetPostingsData();
docStoreSegment = null; docStoreSegment = null;
numDocsInStore = 0;
docStoreOffset = 0;
files = null; files = null;
} finally { } finally {

View File

@ -2447,6 +2447,11 @@ public class IndexWriter {
} }
int docStoreOffset = docWriter.getDocStoreOffset(); int docStoreOffset = docWriter.getDocStoreOffset();
// docStoreOffset should only be non-zero when
// autoCommit == false
assert !autoCommit || 0 == docStoreOffset;
boolean docStoreIsCompoundFile = false; boolean docStoreIsCompoundFile = false;
// Check if the doc stores must be separately flushed // Check if the doc stores must be separately flushed

View File

@ -76,10 +76,8 @@ public class TestConcurrentMergeScheduler extends LuceneTestCase {
writer.addDocument(doc); writer.addDocument(doc);
} }
// Even though this won't delete any docs, writer.addDocument(doc);
// IndexWriter's flush will still make a clone for all
// SegmentInfos on hitting the exception:
writer.deleteDocuments(new Term("id", "1000"));
failure.setDoFail(); failure.setDoFail();
try { try {
writer.flush(); writer.flush();

View File

@ -2254,8 +2254,9 @@ public class TestIndexWriter extends LuceneTestCase
int idUpto = 0; int idUpto = 0;
int fullCount = 0; int fullCount = 0;
final long stopTime = System.currentTimeMillis() + 500;
while(true) { while(System.currentTimeMillis() < stopTime) {
try { try {
writer.updateDocument(new Term("id", ""+(idUpto++)), doc); writer.updateDocument(new Term("id", ""+(idUpto++)), doc);
} catch (IOException ioe) { } catch (IOException ioe) {
@ -2435,17 +2436,24 @@ public class TestIndexWriter extends LuceneTestCase
// Throws IOException during FieldsWriter.flushDocument and during DocumentsWriter.abort // Throws IOException during FieldsWriter.flushDocument and during DocumentsWriter.abort
private static class FailOnlyOnAbortOrFlush extends MockRAMDirectory.Failure { private static class FailOnlyOnAbortOrFlush extends MockRAMDirectory.Failure {
private boolean onlyOnce;
public FailOnlyOnAbortOrFlush(boolean onlyOnce) {
this.onlyOnce = true;
}
public void eval(MockRAMDirectory dir) throws IOException { public void eval(MockRAMDirectory dir) throws IOException {
if (doFail) { if (doFail) {
StackTraceElement[] trace = new Exception().getStackTrace(); StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) { for (int i = 0; i < trace.length; i++) {
if ("abort".equals(trace[i].getMethodName()) || if ("abort".equals(trace[i].getMethodName()) ||
"flushDocument".equals(trace[i].getMethodName())) "flushDocument".equals(trace[i].getMethodName())) {
if (onlyOnce)
doFail = false;
throw new IOException("now failing on purpose"); throw new IOException("now failing on purpose");
} }
} }
} }
} }
}
// Runs test, with one thread, using the specific failure // Runs test, with one thread, using the specific failure
// to trigger an IOException // to trigger an IOException
@ -2522,11 +2530,24 @@ public class TestIndexWriter extends LuceneTestCase
assertTrue("hit unexpected Throwable", threads[i].error == null); assertTrue("hit unexpected Throwable", threads[i].error == null);
} }
boolean success = false;
try { try {
writer.close(false); writer.close(false);
success = true;
} catch (IOException ioe) { } catch (IOException ioe) {
} }
if (success) {
IndexReader reader = IndexReader.open(dir);
for(int j=0;j<reader.maxDoc();j++) {
if (!reader.isDeleted(j)) {
reader.document(j);
reader.getTermFreqVectors(j);
}
}
reader.close();
}
dir.close(); dir.close();
} }
} }
@ -2534,57 +2555,105 @@ public class TestIndexWriter extends LuceneTestCase
// LUCENE-1130: make sure initial IOException, and then 2nd // LUCENE-1130: make sure initial IOException, and then 2nd
// IOException during abort(), is OK: // IOException during abort(), is OK:
public void testIOExceptionDuringAbort() throws IOException { public void testIOExceptionDuringAbort() throws IOException {
_testSingleThreadFailure(new FailOnlyOnAbortOrFlush()); _testSingleThreadFailure(new FailOnlyOnAbortOrFlush(false));
}
// LUCENE-1130: make sure initial IOException, and then 2nd
// IOException during abort(), is OK:
public void testIOExceptionDuringAbortOnlyOnce() throws IOException {
_testSingleThreadFailure(new FailOnlyOnAbortOrFlush(true));
} }
// LUCENE-1130: make sure initial IOException, and then 2nd // LUCENE-1130: make sure initial IOException, and then 2nd
// IOException during abort(), with multiple threads, is OK: // IOException during abort(), with multiple threads, is OK:
public void testIOExceptionDuringAbortWithThreads() throws IOException { public void testIOExceptionDuringAbortWithThreads() throws IOException {
_testMultipleThreadsFailure(new FailOnlyOnAbortOrFlush()); _testMultipleThreadsFailure(new FailOnlyOnAbortOrFlush(false));
}
// LUCENE-1130: make sure initial IOException, and then 2nd
// IOException during abort(), with multiple threads, is OK:
public void testIOExceptionDuringAbortWithThreadsOnlyOnce() throws IOException {
_testMultipleThreadsFailure(new FailOnlyOnAbortOrFlush(true));
} }
// Throws IOException during DocumentsWriter.closeDocStore // Throws IOException during DocumentsWriter.closeDocStore
private static class FailOnlyInCloseDocStore extends MockRAMDirectory.Failure { private static class FailOnlyInCloseDocStore extends MockRAMDirectory.Failure {
private boolean onlyOnce;
public FailOnlyInCloseDocStore(boolean onlyOnce) {
this.onlyOnce = true;
}
public void eval(MockRAMDirectory dir) throws IOException { public void eval(MockRAMDirectory dir) throws IOException {
if (doFail) { if (doFail) {
StackTraceElement[] trace = new Exception().getStackTrace(); StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) { for (int i = 0; i < trace.length; i++) {
if ("closeDocStore".equals(trace[i].getMethodName())) if ("closeDocStore".equals(trace[i].getMethodName())) {
if (onlyOnce)
doFail = false;
throw new IOException("now failing on purpose"); throw new IOException("now failing on purpose");
} }
} }
} }
} }
}
// LUCENE-1130: test IOException in closeDocStore // LUCENE-1130: test IOException in closeDocStore
public void testIOExceptionDuringCloseDocStore() throws IOException { public void testIOExceptionDuringCloseDocStore() throws IOException {
_testSingleThreadFailure(new FailOnlyInCloseDocStore()); _testSingleThreadFailure(new FailOnlyInCloseDocStore(false));
}
// LUCENE-1130: test IOException in closeDocStore
public void testIOExceptionDuringCloseDocStoreOnlyOnce() throws IOException {
_testSingleThreadFailure(new FailOnlyInCloseDocStore(true));
} }
// LUCENE-1130: test IOException in closeDocStore, with threads // LUCENE-1130: test IOException in closeDocStore, with threads
public void testIOExceptionDuringCloseDocStoreWithThreads() throws IOException { public void testIOExceptionDuringCloseDocStoreWithThreads() throws IOException {
_testMultipleThreadsFailure(new FailOnlyInCloseDocStore()); _testMultipleThreadsFailure(new FailOnlyInCloseDocStore(false));
}
// LUCENE-1130: test IOException in closeDocStore, with threads
public void testIOExceptionDuringCloseDocStoreWithThreadsOnlyOnce() throws IOException {
_testMultipleThreadsFailure(new FailOnlyInCloseDocStore(true));
} }
// Throws IOException during DocumentsWriter.writeSegment // Throws IOException during DocumentsWriter.writeSegment
private static class FailOnlyInWriteSegment extends MockRAMDirectory.Failure { private static class FailOnlyInWriteSegment extends MockRAMDirectory.Failure {
private boolean onlyOnce;
public FailOnlyInWriteSegment(boolean onlyOnce) {
this.onlyOnce = true;
}
public void eval(MockRAMDirectory dir) throws IOException { public void eval(MockRAMDirectory dir) throws IOException {
if (doFail) { if (doFail) {
StackTraceElement[] trace = new Exception().getStackTrace(); StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) { for (int i = 0; i < trace.length; i++) {
if ("writeSegment".equals(trace[i].getMethodName())) if ("writeSegment".equals(trace[i].getMethodName())) {
if (onlyOnce)
doFail = false;
// new RuntimeException().printStackTrace(System.out);
throw new IOException("now failing on purpose"); throw new IOException("now failing on purpose");
} }
} }
} }
} }
}
// LUCENE-1130: test IOException in writeSegment // LUCENE-1130: test IOException in writeSegment
public void testIOExceptionDuringWriteSegment() throws IOException { public void testIOExceptionDuringWriteSegment() throws IOException {
_testSingleThreadFailure(new FailOnlyInWriteSegment()); _testSingleThreadFailure(new FailOnlyInWriteSegment(false));
}
// LUCENE-1130: test IOException in writeSegment
public void testIOExceptionDuringWriteSegmentOnlyOnce() throws IOException {
_testSingleThreadFailure(new FailOnlyInWriteSegment(true));
} }
// LUCENE-1130: test IOException in writeSegment, with threads // LUCENE-1130: test IOException in writeSegment, with threads
public void testIOExceptionDuringWriteSegmentWithThreads() throws IOException { public void testIOExceptionDuringWriteSegmentWithThreads() throws IOException {
_testMultipleThreadsFailure(new FailOnlyInWriteSegment()); _testMultipleThreadsFailure(new FailOnlyInWriteSegment(false));
}
// LUCENE-1130: test IOException in writeSegment, with threads
public void testIOExceptionDuringWriteSegmentWithThreadsOnlyOnce() throws IOException {
_testMultipleThreadsFailure(new FailOnlyInWriteSegment(true));
} }
} }