diff --git a/src/java/org/apache/lucene/index/DocumentsWriter.java b/src/java/org/apache/lucene/index/DocumentsWriter.java index d6ea2948fdb..b0782e78a0b 100644 --- a/src/java/org/apache/lucene/index/DocumentsWriter.java +++ b/src/java/org/apache/lucene/index/DocumentsWriter.java @@ -722,6 +722,7 @@ final class DocumentsWriter { void init(Document doc, int docID) throws IOException, AbortException { assert !isIdle; + assert writer.testPoint("DocumentsWriter.ThreadState.init start"); this.docID = docID; docBoost = doc.getBoost(); @@ -2440,18 +2441,6 @@ final class DocumentsWriter { if (segment == null) segment = writer.newSegmentName(); - numDocsInRAM++; - - // We must at this point commit to flushing to ensure we - // always get N docs when we flush by doc count, even if - // > 1 thread is adding documents: - if (!flushPending && maxBufferedDocs != IndexWriter.DISABLE_AUTO_FLUSH - && numDocsInRAM >= maxBufferedDocs) { - flushPending = true; - state.doFlushAfter = true; - } else - state.doFlushAfter = false; - state.isIdle = false; try { @@ -2460,11 +2449,21 @@ final class DocumentsWriter { state.init(doc, nextDocID); if (delTerm != null) { addDeleteTerm(delTerm, state.docID); - if (!state.doFlushAfter) - state.doFlushAfter = timeToFlushDeletes(); + state.doFlushAfter = timeToFlushDeletes(); } - // Only increment nextDocID on successful init + // Only increment nextDocID & numDocsInRAM on successful init nextDocID++; + numDocsInRAM++; + + // We must at this point commit to flushing to ensure we + // always get N docs when we flush by doc count, even if + // > 1 thread is adding documents: + if (!flushPending && maxBufferedDocs != IndexWriter.DISABLE_AUTO_FLUSH + && numDocsInRAM >= maxBufferedDocs) { + flushPending = true; + state.doFlushAfter = true; + } + success = true; } finally { if (!success) { diff --git a/src/java/org/apache/lucene/index/IndexWriter.java b/src/java/org/apache/lucene/index/IndexWriter.java index 4a5bdc880cc..01d688dc587 100644 --- a/src/java/org/apache/lucene/index/IndexWriter.java +++ b/src/java/org/apache/lucene/index/IndexWriter.java @@ -4243,4 +4243,10 @@ public class IndexWriter { public static final MaxFieldLength LIMITED = new MaxFieldLength("LIMITED", DEFAULT_MAX_FIELD_LENGTH); } + + // Used only by assert for testing. Current points: + // "DocumentsWriter.ThreadState.init start" + boolean testPoint(String name) { + return true; + } } diff --git a/src/test/org/apache/lucene/index/TestIndexWriter.java b/src/test/org/apache/lucene/index/TestIndexWriter.java index 9c8b3d80221..2fa5d7b2c69 100644 --- a/src/test/org/apache/lucene/index/TestIndexWriter.java +++ b/src/test/org/apache/lucene/index/TestIndexWriter.java @@ -3123,4 +3123,39 @@ public class TestIndexWriter extends LuceneTestCase writer.addDocument(doc); writer.close(); } + + // LUCENE-1198 + public class MockIndexWriter extends IndexWriter { + + public MockIndexWriter(Directory dir, boolean autoCommit, Analyzer a, boolean create, MaxFieldLength mfl) throws IOException { + super(dir, autoCommit, a, create, mfl); + } + + boolean doFail; + + boolean testPoint(String name) { + if (doFail && name.equals("DocumentsWriter.ThreadState.init start")) + throw new RuntimeException("intentionally failing"); + return true; + } + } + + public void testExceptionDocumentsWriterInit() throws IOException { + MockRAMDirectory dir = new MockRAMDirectory(); + MockIndexWriter w = new MockIndexWriter(dir, false, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.UNLIMITED); + Document doc = new Document(); + doc.add(new Field("field", "a field", Field.Store.YES, + Field.Index.TOKENIZED)); + w.addDocument(doc); + w.doFail = true; + try { + w.addDocument(doc); + fail("did not hit exception"); + } catch (RuntimeException re) { + // expected + } + w.close(); + _TestUtil.checkIndex(dir); + dir.close(); + } } diff --git a/src/test/org/apache/lucene/util/_TestUtil.java b/src/test/org/apache/lucene/util/_TestUtil.java index eeeda40175c..81fe8f8fce8 100644 --- a/src/test/org/apache/lucene/util/_TestUtil.java +++ b/src/test/org/apache/lucene/util/_TestUtil.java @@ -22,6 +22,10 @@ import java.io.IOException; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.MergeScheduler; import org.apache.lucene.index.ConcurrentMergeScheduler; +import org.apache.lucene.index.CheckIndex; +import org.apache.lucene.store.Directory; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; public class _TestUtil { @@ -49,4 +53,16 @@ public class _TestUtil { if (ms instanceof ConcurrentMergeScheduler) ((ConcurrentMergeScheduler) ms).sync(); } + + public static boolean checkIndex(Directory dir) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); + CheckIndex.out = new PrintStream(bos); + if (!CheckIndex.check(dir, false, null)) { + System.out.println("CheckIndex failed"); + System.out.println(bos.toString()); + return false; + } else + return true; + } + }