Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 890721) +++ CHANGES.txt (working copy) @@ -53,6 +53,9 @@ * LUCENE-2142: FieldCacheImpl.getStringIndex no longer throws an exception when term count exceeds doc count. (Mike McCandless) + +* LUCENE-2158: At high indexing rates, NRT reader could temporarily + lose deletions. (Mike McCandless) New features Index: src/test/org/apache/lucene/index/TestIndexWriterReader.java =================================================================== --- src/test/org/apache/lucene/index/TestIndexWriterReader.java (revision 890721) +++ src/test/org/apache/lucene/index/TestIndexWriterReader.java (working copy) @@ -866,4 +866,34 @@ r.close(); dir.close(); } + + public void testDeletesNumDocs() throws Throwable { + Directory dir = new MockRAMDirectory(); + final IndexWriter w = new IndexWriter(dir, new WhitespaceAnalyzer(), + IndexWriter.MaxFieldLength.LIMITED); + Document doc = new Document(); + doc.add(new Field("field", "a b c", Field.Store.NO, Field.Index.ANALYZED)); + Field id = new Field("id", "", Field.Store.NO, Field.Index.NOT_ANALYZED); + doc.add(id); + id.setValue("0"); + w.addDocument(doc); + id.setValue("1"); + w.addDocument(doc); + IndexReader r = w.getReader(); + assertEquals(2, r.numDocs()); + r.close(); + + w.deleteDocuments(new Term("id", "0")); + r = w.getReader(); + assertEquals(1, r.numDocs()); + r.close(); + + w.deleteDocuments(new Term("id", "1")); + r = w.getReader(); + assertEquals(0, r.numDocs()); + r.close(); + + w.close(); + dir.close(); + } } Index: src/java/org/apache/lucene/index/IndexWriter.java =================================================================== --- src/java/org/apache/lucene/index/IndexWriter.java (revision 890721) +++ src/java/org/apache/lucene/index/IndexWriter.java (working copy) @@ -395,12 +395,13 @@ // this method is called: poolReaders = true; - flush(true, true, true); + flush(true, true, false); // Prevent segmentInfos from changing while opening the // reader; in theory we could do similar retry logic, // just like we do when loading segments_N synchronized(this) { + applyDeletes(); return new ReadOnlyDirectoryReader(this, segmentInfos, termInfosIndexDivisor); } } @@ -3654,7 +3655,6 @@ } if (flushDeletes) { - flushDeletesCount++; applyDeletes(); } @@ -4423,6 +4423,7 @@ // Apply buffered deletes to all segments. private final synchronized boolean applyDeletes() throws CorruptIndexException, IOException { assert testPoint("startApplyDeletes"); + flushDeletesCount++; SegmentInfos rollback = (SegmentInfos) segmentInfos.clone(); boolean success = false; boolean changed;