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

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