Index: src/test/org/apache/lucene/index/TestAddIndexesNoOptimize.java =================================================================== --- src/test/org/apache/lucene/index/TestAddIndexesNoOptimize.java (revision 650838) +++ src/test/org/apache/lucene/index/TestAddIndexesNoOptimize.java (working copy) @@ -26,6 +26,7 @@ import org.apache.lucene.document.Field; import org.apache.lucene.store.Directory; import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.store.MockRAMDirectory; import org.apache.lucene.search.PhraseQuery; @@ -432,9 +433,8 @@ private void addDocs(IndexWriter writer, int numDocs) throws IOException { for (int i = 0; i < numDocs; i++) { Document doc = new Document(); - doc - .add(new Field("content", "aaa", Field.Store.NO, - Field.Index.TOKENIZED)); + doc.add(new Field("content", "aaa", Field.Store.NO, + Field.Index.TOKENIZED)); writer.addDocument(doc); } } @@ -442,9 +442,8 @@ private void addDocs2(IndexWriter writer, int numDocs) throws IOException { for (int i = 0; i < numDocs; i++) { Document doc = new Document(); - doc - .add(new Field("content", "bbb", Field.Store.NO, - Field.Index.TOKENIZED)); + doc.add(new Field("content", "bbb", Field.Store.NO, + Field.Index.TOKENIZED)); writer.addDocument(doc); } } @@ -495,4 +494,47 @@ assertEquals(3, writer.getSegmentCount()); writer.close(); } + + // LUCENE-1270 + public void testHangOnClose() throws IOException { + + Directory dir = new MockRAMDirectory(); + IndexWriter writer = new IndexWriter(dir, false, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED); + writer.setMergePolicy(new LogByteSizeMergePolicy()); + writer.setMaxBufferedDocs(5); + writer.setUseCompoundFile(false); + writer.setMergeFactor(100); + + Document doc = new Document(); + doc.add(new Field("content", "aaa bbb ccc ddd eee fff ggg hhh iii", Field.Store.YES, + Field.Index.TOKENIZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); + for(int i=0;i<60;i++) + writer.addDocument(doc); + writer.setMaxBufferedDocs(200); + Document doc2 = new Document(); + doc2.add(new Field("content", "aaa bbb ccc ddd eee fff ggg hhh iii", Field.Store.YES, + Field.Index.NO)); + doc2.add(new Field("content", "aaa bbb ccc ddd eee fff ggg hhh iii", Field.Store.YES, + Field.Index.NO)); + doc2.add(new Field("content", "aaa bbb ccc ddd eee fff ggg hhh iii", Field.Store.YES, + Field.Index.NO)); + doc2.add(new Field("content", "aaa bbb ccc ddd eee fff ggg hhh iii", Field.Store.YES, + Field.Index.NO)); + for(int i=0;i<10;i++) + writer.addDocument(doc2); + writer.close(); + + Directory dir2 = new MockRAMDirectory(); + writer = new IndexWriter(dir2, false, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED); + LogByteSizeMergePolicy lmp = new LogByteSizeMergePolicy(); + lmp.setMinMergeMB(0.0001); + writer.setMergePolicy(lmp); + writer.setMergeFactor(4); + writer.setUseCompoundFile(false); + writer.setMergeScheduler(new SerialMergeScheduler()); + writer.addIndexesNoOptimize(new Directory[] {dir}); + writer.close(); + dir.close(); + dir2.close(); + } } Index: src/java/org/apache/lucene/index/IndexWriter.java =================================================================== --- src/java/org/apache/lucene/index/IndexWriter.java (revision 650838) +++ src/java/org/apache/lucene/index/IndexWriter.java (working copy) @@ -1658,6 +1658,11 @@ // going to wait for merges: flush(waitForMerges, true, true); + if (waitForMerges) + // Give merge scheduler last chance to run, in case + // any pending merges are waiting: + mergeScheduler.merge(this); + mergePolicy.close(); finishMerges(waitForMerges); @@ -2889,6 +2894,9 @@ * then copy them over. Currently this is only used by * addIndexesNoOptimize(). */ private void copyExternalSegments() throws CorruptIndexException, IOException { + + boolean any = false; + while(true) { SegmentInfo info = null; MergePolicy.OneMerge merge = null; @@ -2907,6 +2915,7 @@ if (registerMerge(merge)) { pendingMerges.remove(merge); runningMerges.add(merge); + any = true; merge(merge); } else // This means there is a bug in the @@ -2923,6 +2932,11 @@ // No more external segments break; } + + if (any) + // Sometimes, on copying an external segment over, + // more merges may become necessary: + mergeScheduler.merge(this); } /** Merges the provided indexes into this index.