| diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java |
| index 5affd85..93672f4 100644 |
| --- a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java |
| +++ b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java |
| @@ -781,7 +781,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable, |
| // against an index that's currently open for |
| // searching. In this case we write the next |
| // segments_N file with no segments: |
| - final SegmentInfos sis = new SegmentInfos(Version.LATEST.major); |
| + final SegmentInfos sis = new SegmentInfos(config.getIndexCreatedVersionMajor()); |
| if (indexExists) { |
| final SegmentInfos previous = SegmentInfos.readLatestCommit(directory); |
| sis.updateGenerationVersionAndCounter(previous); |
| diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexWriterConfig.java b/lucene/core/src/java/org/apache/lucene/index/IndexWriterConfig.java |
| index d657d52..a72aeab 100644 |
| --- a/lucene/core/src/java/org/apache/lucene/index/IndexWriterConfig.java |
| +++ b/lucene/core/src/java/org/apache/lucene/index/IndexWriterConfig.java |
| @@ -33,6 +33,7 @@ import org.apache.lucene.search.similarities.Similarity; |
| import org.apache.lucene.util.InfoStream; |
| import org.apache.lucene.util.PrintStreamInfoStream; |
| import org.apache.lucene.util.SetOnce.AlreadySetException; |
| +import org.apache.lucene.util.Version; |
| import org.apache.lucene.util.SetOnce; |
| |
| /** |
| @@ -173,6 +174,35 @@ public final class IndexWriterConfig extends LiveIndexWriterConfig { |
| } |
| |
| /** |
| + * Expert: set the compatibility version to use for this index. In case the |
| + * index is created, it will use the given major version for compatibility. |
| + * It is sometimes useful to set the previous major version for compatibility |
| + * due to the fact that {@link IndexWriter#addIndexes} only accepts indices |
| + * that have been written with the same major version as the current index. |
| + * If the index already exists, then this value is ignored. |
| + * Default value is the {@link Version#major major} of the |
| + * {@link Version#LATEST latest version}. |
| + * <p><b>NOTE</b>: Changing the creation version reduces backward |
| + * compatibility guarantees. For instance an index created with Lucene 8 with |
| + * a compatibility version of 7 can't be read with Lucene 9 due to the fact |
| + * that Lucene only supports reading indices created with the current or |
| + * previous major release. |
| + * @param indexCreatedVersionMajor the major version to use for compatibility |
| + */ |
| + public IndexWriterConfig setIndexCreatedVersionMajor(int indexCreatedVersionMajor) { |
| + if (indexCreatedVersionMajor > Version.LATEST.major) { |
| + throw new IllegalArgumentException("indexCreatedVersionMajor may not be in the future: current major version is " + |
| + Version.LATEST.major + ", but got: " + indexCreatedVersionMajor); |
| + } |
| + if (indexCreatedVersionMajor < Version.LATEST.major - 1) { |
| + throw new IllegalArgumentException("indexCreatedVersionMajor may not be less than the minimum supported version: " + |
| + (Version.LATEST.major-1) + ", but got: " + indexCreatedVersionMajor); |
| + } |
| + this.createdVersionMajor = indexCreatedVersionMajor; |
| + return this; |
| + } |
| + |
| + /** |
| * Expert: allows an optional {@link IndexDeletionPolicy} implementation to be |
| * specified. You can use this to control when prior commits are deleted from |
| * the index. The default policy is {@link KeepOnlyLastCommitDeletionPolicy} |
| diff --git a/lucene/core/src/java/org/apache/lucene/index/LiveIndexWriterConfig.java b/lucene/core/src/java/org/apache/lucene/index/LiveIndexWriterConfig.java |
| index 016e880..259a020 100644 |
| --- a/lucene/core/src/java/org/apache/lucene/index/LiveIndexWriterConfig.java |
| +++ b/lucene/core/src/java/org/apache/lucene/index/LiveIndexWriterConfig.java |
| @@ -29,6 +29,7 @@ import org.apache.lucene.search.IndexSearcher; |
| import org.apache.lucene.search.Sort; |
| import org.apache.lucene.search.similarities.Similarity; |
| import org.apache.lucene.util.InfoStream; |
| +import org.apache.lucene.util.Version; |
| |
| /** |
| * Holds all the configuration used by {@link IndexWriter} with few setters for |
| @@ -57,6 +58,9 @@ public class LiveIndexWriterConfig { |
| * with. */ |
| protected volatile OpenMode openMode; |
| |
| + /** Compatibility version to use for this index. */ |
| + protected int createdVersionMajor = Version.LATEST.major; |
| + |
| /** {@link Similarity} to use when encoding norms. */ |
| protected volatile Similarity similarity; |
| |
| @@ -285,7 +289,15 @@ public class LiveIndexWriterConfig { |
| public OpenMode getOpenMode() { |
| return openMode; |
| } |
| - |
| + |
| + /** |
| + * Return the compatibility version to use for this index. |
| + * @see IndexWriterConfig#setIndexCreatedVersionMajor |
| + */ |
| + public int getIndexCreatedVersionMajor() { |
| + return createdVersionMajor; |
| + } |
| + |
| /** |
| * Returns the {@link IndexDeletionPolicy} specified in |
| * {@link IndexWriterConfig#setIndexDeletionPolicy(IndexDeletionPolicy)} or |
| diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java |
| index 08b3dc1..20d3532 100644 |
| --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java |
| +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java |
| @@ -3601,4 +3601,35 @@ public class TestIndexWriter extends LuceneTestCase { |
| } |
| } |
| } |
| + |
| + public void testSetIndexCreatedVersion() throws IOException { |
| + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, |
| + () -> new IndexWriterConfig().setIndexCreatedVersionMajor(Version.LATEST.major+1)); |
| + assertEquals("indexCreatedVersionMajor may not be in the future: current major version is " + |
| + Version.LATEST.major + ", but got: " + (Version.LATEST.major+1), e.getMessage()); |
| + e = expectThrows(IllegalArgumentException.class, |
| + () -> new IndexWriterConfig().setIndexCreatedVersionMajor(Version.LATEST.major-2)); |
| + assertEquals("indexCreatedVersionMajor may not be less than the minimum supported version: " + |
| + (Version.LATEST.major-1) + ", but got: " + (Version.LATEST.major-2), e.getMessage()); |
| + |
| + for (int previousMajor = Version.LATEST.major - 1; previousMajor <= Version.LATEST.major; previousMajor++) { |
| + for (int newMajor = Version.LATEST.major - 1; newMajor <= Version.LATEST.major; newMajor++) { |
| + for (OpenMode openMode : OpenMode.values()) { |
| + try (Directory dir = newDirectory()) { |
| + try (IndexWriter w = new IndexWriter(dir, newIndexWriterConfig().setIndexCreatedVersionMajor(previousMajor))) {} |
| + SegmentInfos infos = SegmentInfos.readLatestCommit(dir); |
| + assertEquals(previousMajor, infos.getIndexCreatedVersionMajor()); |
| + try (IndexWriter w = new IndexWriter(dir, newIndexWriterConfig().setOpenMode(openMode).setIndexCreatedVersionMajor(newMajor))) {} |
| + infos = SegmentInfos.readLatestCommit(dir); |
| + if (openMode == OpenMode.CREATE) { |
| + assertEquals(newMajor, infos.getIndexCreatedVersionMajor()); |
| + } else { |
| + assertEquals(previousMajor, infos.getIndexCreatedVersionMajor()); |
| + } |
| + } |
| + } |
| + } |
| + } |
| + } |
| + |
| } |