diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50LiveDocsFormat.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50LiveDocsFormat.java
index 612bb9b1779..55b0844b49f 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50LiveDocsFormat.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50LiveDocsFormat.java
@@ -22,6 +22,7 @@ import java.util.Collection;
import org.apache.lucene.codecs.CodecUtil;
import org.apache.lucene.codecs.LiveDocsFormat;
+import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexFileNames;
import org.apache.lucene.index.SegmentCommitInfo;
import org.apache.lucene.store.ChecksumIndexInput;
@@ -40,9 +41,10 @@ import org.apache.lucene.util.MutableBits;
* deletions.
* Although per-segment, this file is maintained exterior to compound segment
* files.
- * Deletions (.liv) --> SegmentHeader,Bits
+ * Deletions (.liv) --> SegmentHeader,Generation,Bits
*
* - SegmentHeader --> {@link CodecUtil#writeSegmentHeader SegmentHeader}
+ * - Generation --> {@link DataOutput#writeLong Int64}
*
- Bits --> <{@link DataOutput#writeLong Int64}> LongCount
*
*/
@@ -73,12 +75,17 @@ public class Lucene50LiveDocsFormat extends LiveDocsFormat {
@Override
public Bits readLiveDocs(Directory dir, SegmentCommitInfo info, IOContext context) throws IOException {
- String name = IndexFileNames.fileNameFromGeneration(info.info.name, EXTENSION, info.getDelGen());
+ long gen = info.getDelGen();
+ String name = IndexFileNames.fileNameFromGeneration(info.info.name, EXTENSION, gen);
final int length = info.info.getDocCount();
try (ChecksumIndexInput input = dir.openChecksumInput(name, context)) {
Throwable priorE = null;
try {
CodecUtil.checkSegmentHeader(input, CODEC_NAME, VERSION_START, VERSION_CURRENT, info.info.getId());
+ long filegen = input.readLong();
+ if (gen != filegen) {
+ throw new CorruptIndexException("file mismatch, expected generation=" + gen + ", got=" + filegen, input);
+ }
long data[] = new long[FixedBitSet.bits2words(length)];
for (int i = 0; i < data.length; i++) {
data[i] = input.readLong();
@@ -95,10 +102,12 @@ public class Lucene50LiveDocsFormat extends LiveDocsFormat {
@Override
public void writeLiveDocs(MutableBits bits, Directory dir, SegmentCommitInfo info, int newDelCount, IOContext context) throws IOException {
- String name = IndexFileNames.fileNameFromGeneration(info.info.name, EXTENSION, info.getNextDelGen());
+ long gen = info.getNextDelGen();
+ String name = IndexFileNames.fileNameFromGeneration(info.info.name, EXTENSION, gen);
long data[] = ((FixedBitSet) bits).getBits();
try (IndexOutput output = dir.createOutput(name, context)) {
CodecUtil.writeSegmentHeader(output, CODEC_NAME, VERSION_CURRENT, info.info.getId());
+ output.writeLong(gen);
for (int i = 0; i < data.length; i++) {
output.writeLong(data[i]);
}
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SegmentInfoWriter.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SegmentInfoWriter.java
index ab407d9221c..70e66ea86e0 100755
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SegmentInfoWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene50/Lucene50SegmentInfoWriter.java
@@ -18,6 +18,7 @@ package org.apache.lucene.codecs.lucene50;
*/
import java.io.IOException;
+import java.util.Set;
import org.apache.lucene.codecs.CodecUtil;
import org.apache.lucene.codecs.SegmentInfoWriter;
@@ -28,6 +29,7 @@ import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IOContext;
import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.util.StringHelper;
import org.apache.lucene.util.Version;
/**
@@ -48,10 +50,8 @@ public class Lucene50SegmentInfoWriter extends SegmentInfoWriter {
final String fileName = IndexFileNames.segmentFileName(si.name, "", Lucene50SegmentInfoFormat.SI_EXTENSION);
si.addFile(fileName);
- final IndexOutput output = dir.createOutput(fileName, ioContext);
-
boolean success = false;
- try {
+ try (IndexOutput output = dir.createOutput(fileName, ioContext)) {
CodecUtil.writeHeader(output, Lucene50SegmentInfoFormat.CODEC_NAME, Lucene50SegmentInfoFormat.VERSION_CURRENT);
Version version = si.getVersion();
if (version.major < 5) {
@@ -63,18 +63,24 @@ public class Lucene50SegmentInfoWriter extends SegmentInfoWriter {
output.writeByte((byte) (si.getUseCompoundFile() ? SegmentInfo.YES : SegmentInfo.NO));
output.writeStringStringMap(si.getDiagnostics());
- output.writeStringSet(si.files());
+ Set files = si.files();
+ for (String file : files) {
+ if (!IndexFileNames.parseSegmentName(file).equals(si.name)) {
+ throw new IllegalArgumentException("invalid files: expected segment=" + si.name + ", got=" + files);
+ }
+ }
+ output.writeStringSet(files);
byte[] id = si.getId();
+ if (id.length != StringHelper.ID_LENGTH) {
+ throw new IllegalArgumentException("invalid id, got=" + StringHelper.idToString(id));
+ }
output.writeBytes(id, 0, id.length);
CodecUtil.writeFooter(output);
success = true;
} finally {
if (!success) {
- IOUtils.closeWhileHandlingException(output);
// TODO: are we doing this outside of the tracking wrapper? why must SIWriter cleanup like this?
IOUtils.deleteFilesIgnoringExceptions(si.dir, fileName);
- } else {
- output.close();
}
}
}