blob: c09ae36b70eeff8f5010f5564d46b5063adea3fe [file] [log] [blame]
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());
+ }
+ }
+ }
+ }
+ }
+ }
+
}