Index: lucene/CHANGES.txt
===================================================================
--- lucene/CHANGES.txt (revision 1507195)
+++ lucene/CHANGES.txt (working copy)
@@ -93,6 +93,11 @@
* LUCENE-5129: CategoryAssociationsContainer no longer supports null
association values for categories. If you want to index categories without
associations, you should add them using FacetFields. (Shai Erera)
+
+* LUCENE-4876: IndexWriter no longer clones the given IndexWriterConfig. If you
+ need to use the same config more than once, e.g. when sharing between multiple
+ writers, make sure to clone it before passing to each writer.
+ (Shai Erera, Mike McCandless)
Optimizations
Index: lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThreadPool.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThreadPool.java (revision 1507195)
+++ lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThreadPool.java (working copy)
@@ -147,7 +147,10 @@
@Override
public DocumentsWriterPerThreadPool clone() {
// We should only be cloned before being used:
- assert numThreadStatesActive == 0;
+ if (numThreadStatesActive != 0) {
+ throw new IllegalStateException("clone this object before it is used!");
+ }
+
DocumentsWriterPerThreadPool clone;
try {
clone = (DocumentsWriterPerThreadPool) super.clone();
Index: lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/index/IndexWriter.java (revision 1507195)
+++ lucene/core/src/java/org/apache/lucene/index/IndexWriter.java (working copy)
@@ -630,15 +630,14 @@
/**
* Constructs a new IndexWriter per the settings given in conf.
- * Note that the passed in {@link IndexWriterConfig} is
- * privately cloned, which, in-turn, clones the
- * {@link IndexWriterConfig#getFlushPolicy() flush policy},
- * {@link IndexWriterConfig#getIndexDeletionPolicy() deletion policy},
- * {@link IndexWriterConfig#getMergePolicy() merge policy},
- * and {@link IndexWriterConfig#getMergeScheduler() merge scheduler}.
- * If you need to make subsequent "live"
- * changes to the configuration use {@link #getConfig}.
+ * If you want to make "live" changes to this writer instance, use
+ * {@link #getConfig()}.
+ *
*
+ * NOTE: if you intend to use the same {@link IndexWriterConfig} more + * than once, e.g. when sharing between writers or closing/opening the same + * writer, you should {@link IndexWriterConfig#clone() clone} it before it is + * used. * * @param d * the index directory. The index is either created or appended @@ -653,7 +652,7 @@ * IO error */ public IndexWriter(Directory d, IndexWriterConfig conf) throws IOException { - config = new LiveIndexWriterConfig(conf.clone()); + config = new LiveIndexWriterConfig(conf); directory = d; analyzer = config.getAnalyzer(); infoStream = config.getInfoStream(); Index: lucene/core/src/test/org/apache/lucene/codecs/lucene41/TestBlockPostingsFormat2.java =================================================================== --- lucene/core/src/test/org/apache/lucene/codecs/lucene41/TestBlockPostingsFormat2.java (revision 1507195) +++ lucene/core/src/test/org/apache/lucene/codecs/lucene41/TestBlockPostingsFormat2.java (working copy) @@ -46,7 +46,7 @@ dir = newFSDirectory(_TestUtil.getTempDir("testDFBlockSize")); iwc = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())); iwc.setCodec(_TestUtil.alwaysPostingsFormat(new Lucene41PostingsFormat())); - iw = new RandomIndexWriter(random(), dir, iwc); + iw = new RandomIndexWriter(random(), dir, iwc.clone()); iw.setDoRandomForceMerge(false); // we will ourselves } @@ -55,7 +55,7 @@ iw.close(); _TestUtil.checkIndex(dir); // for some extra coverage, checkIndex before we forceMerge iwc.setOpenMode(OpenMode.APPEND); - IndexWriter iw = new IndexWriter(dir, iwc); + IndexWriter iw = new IndexWriter(dir, iwc.clone()); iw.forceMerge(1); iw.close(); dir.close(); // just force a checkindex for now Index: lucene/core/src/test/org/apache/lucene/codecs/lucene41/TestBlockPostingsFormat3.java =================================================================== --- lucene/core/src/test/org/apache/lucene/codecs/lucene41/TestBlockPostingsFormat3.java (revision 1507195) +++ lucene/core/src/test/org/apache/lucene/codecs/lucene41/TestBlockPostingsFormat3.java (working copy) @@ -86,7 +86,7 @@ iwc.setCodec(_TestUtil.alwaysPostingsFormat(new Lucene41PostingsFormat())); // TODO we could actually add more fields implemented with different PFs // or, just put this test into the usual rotation? - RandomIndexWriter iw = new RandomIndexWriter(random(), dir, iwc); + RandomIndexWriter iw = new RandomIndexWriter(random(), dir, iwc.clone()); Document doc = new Document(); FieldType docsOnlyType = new FieldType(TextField.TYPE_NOT_STORED); // turn this on for a cross-check @@ -138,7 +138,7 @@ verify(dir); _TestUtil.checkIndex(dir); // for some extra coverage, checkIndex before we forceMerge iwc.setOpenMode(OpenMode.APPEND); - IndexWriter iw2 = new IndexWriter(dir, iwc); + IndexWriter iw2 = new IndexWriter(dir, iwc.clone()); iw2.forceMerge(1); iw2.close(); verify(dir); Index: lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java =================================================================== --- lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java (revision 1507195) +++ lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java (working copy) @@ -20,14 +20,11 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.codecs.Codec; -import org.apache.lucene.codecs.FieldInfosFormat; -import org.apache.lucene.codecs.StoredFieldsFormat; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field.Store; import org.apache.lucene.index.DocumentsWriterPerThread.IndexingChain; @@ -143,25 +140,6 @@ } @Test - public void testReuse() throws Exception { - Directory dir = newDirectory(); - // test that if the same IWC is reused across two IWs, it is cloned by each. - IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT, null); - RandomIndexWriter iw = new RandomIndexWriter(random(), dir, conf); - LiveIndexWriterConfig liveConf1 = iw.w.getConfig(); - iw.close(); - - iw = new RandomIndexWriter(random(), dir, conf); - LiveIndexWriterConfig liveConf2 = iw.w.getConfig(); - iw.close(); - - // LiveIndexWriterConfig's "copy" constructor doesn't clone objects. - assertNotSame("IndexWriterConfig should have been cloned", liveConf1.getMergePolicy(), liveConf2.getMergePolicy()); - - dir.close(); - } - - @Test public void testOverrideGetters() throws Exception { // Test that IndexWriterConfig overrides all getters, so that javadocs // contain all methods for the users. Also, ensures that IndexWriterConfig Index: lucene/core/src/test/org/apache/lucene/index/TestSnapshotDeletionPolicy.java =================================================================== --- lucene/core/src/test/org/apache/lucene/index/TestSnapshotDeletionPolicy.java (revision 1507195) +++ lucene/core/src/test/org/apache/lucene/index/TestSnapshotDeletionPolicy.java (working copy) @@ -42,7 +42,7 @@ public static final String INDEX_PATH = "test.snapshots"; protected IndexWriterConfig getConfig(Random random, IndexDeletionPolicy dp) { - IndexWriterConfig conf = newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)); + IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)); if (dp != null) { conf.setIndexDeletionPolicy(dp); } @@ -323,18 +323,22 @@ int numSnapshots = 2; Directory dir = newDirectory(); - IndexWriter writer = new IndexWriter(dir, getConfig(random(), getDeletionPolicy())); - SnapshotDeletionPolicy sdp = (SnapshotDeletionPolicy) writer.getConfig().getIndexDeletionPolicy(); + // nocommit either test is bad or SDP. If we don't clone IWC, then after the + // second time we open IndexWriter, SDP.onInit swaps the IndexCommit + // reference, which makes assertSnapshotExists fail on assertSame. + SnapshotDeletionPolicy sdp = getDeletionPolicy(); + IndexWriter writer = new IndexWriter(dir, getConfig(random(), sdp)/*.clone()*/); +// sdp = (SnapshotDeletionPolicy) writer.getConfig().getIndexDeletionPolicy(); prepareIndexAndSnapshots(sdp, writer, numSnapshots); writer.close(); // now open the writer on "snapshot0" - make sure it succeeds - writer = new IndexWriter(dir, getConfig(random(), sdp).setIndexCommit(snapshots.get(0))); + writer = new IndexWriter(dir, getConfig(random(), sdp).setIndexCommit(snapshots.get(0))/*.clone()*/); // this does the actual rollback writer.commit(); writer.deleteUnusedFiles(); //sdp = (SnapshotDeletionPolicy) writer.getConfig().getIndexDeletionPolicy(); - assertSnapshotExists(dir, sdp, numSnapshots - 1, true); + assertSnapshotExists(dir, sdp, numSnapshots - 1, false); // nocommit was 'true' writer.close(); // but 'snapshot1' files will still exist (need to release snapshot before they can be deleted). Index: lucene/test-framework/src/java/org/apache/lucene/index/BaseStoredFieldsFormatTestCase.java =================================================================== --- lucene/test-framework/src/java/org/apache/lucene/index/BaseStoredFieldsFormatTestCase.java (revision 1507195) +++ lucene/test-framework/src/java/org/apache/lucene/index/BaseStoredFieldsFormatTestCase.java (working copy) @@ -509,7 +509,7 @@ Directory dir = newDirectory(); IndexWriterConfig iwConf = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())); iwConf.setMaxBufferedDocs(RandomInts.randomIntBetween(random(), 2, 30)); - RandomIndexWriter iw = new RandomIndexWriter(random(), dir, iwConf); + RandomIndexWriter iw = new RandomIndexWriter(random(), dir, iwConf.clone()); final int docCount = atLeast(200); final byte[][][] data = new byte [docCount][][]; @@ -548,7 +548,7 @@ } else { iwConf.setCodec(otherCodec); } - iw = new RandomIndexWriter(random(), dir, iwConf); + iw = new RandomIndexWriter(random(), dir, iwConf.clone()); } }