LUCENE-8508: IndexWriter can set the created version major.

This commit is contained in:
Adrien Grand 2018-11-16 11:36:25 +01:00
parent 3302ed2ac6
commit 5aa6782d87
5 changed files with 79 additions and 2 deletions

View File

@ -204,6 +204,10 @@ New Features
points such as range queries or geo queries.
(Christophe Bismuth via Adrien Grand)
* LUCENE-8508: IndexWriter can now set the created version via
IndexWriterConfig#setIndexCreatedVersionMajor. This is an expert feature.
(Adrien Grand)
======================= Lucene 7.6.0 =======================
Build

View File

@ -782,7 +782,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);

View File

@ -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;
/**
@ -172,6 +173,35 @@ public final class IndexWriterConfig extends LiveIndexWriterConfig {
return openMode;
}
/**
* 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

View File

@ -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

View File

@ -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());
}
}
}
}
}
}
}