Index: lucene/CHANGES.txt =================================================================== --- lucene/CHANGES.txt (revision 1140705) +++ lucene/CHANGES.txt (working copy) @@ -10,6 +10,10 @@ * LUCENE-3251: Directory#copy failed to close target output if opening the source stream failed. (Simon Willnauer) +* LUCENE-3255: If segments_N file is all zeros (due to file + corruption), don't read that to mean the index is empty. (Gregory + Tarr, Mark Harwood, Simon Willnauer, Mike McCandless) + Optimizations * LUCENE-3201, LUCENE-3218: CompoundFileSystem code has been consolidated Index: lucene/src/test/org/apache/lucene/index/TestAllZerosSegmentsFile.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestAllZerosSegmentsFile.java (revision 0) +++ lucene/src/test/org/apache/lucene/index/TestAllZerosSegmentsFile.java (revision 0) @@ -0,0 +1,47 @@ +package org.apache.lucene.index; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.lucene.document.Document; +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.IndexOutput; +import org.apache.lucene.util.LuceneTestCase; + +public class TestAllZerosSegmentsFile extends LuceneTestCase { + + public void test() throws Exception { + Directory dir = newDirectory(); + RandomIndexWriter w = new RandomIndexWriter(random, dir); + w.addDocument(new Document()); + w.close(); + + String nextSegmentsFile = IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS, + "", + SegmentInfos.getCurrentSegmentGeneration(dir)+1); + IndexOutput out = dir.createOutput(nextSegmentsFile); + for(int idx=0;idx<8;idx++) { + out.writeByte((byte) 0); + } + out.close(); + + IndexReader r= IndexReader.open(dir,true); + assertEquals(r.numDocs(), 1); + r.close(); + dir.close(); + } +} Property changes on: lucene/src/test/org/apache/lucene/index/TestAllZerosSegmentsFile.java ___________________________________________________________________ Added: svn:eol-style + native Index: lucene/src/java/org/apache/lucene/index/SegmentInfos.java =================================================================== --- lucene/src/java/org/apache/lucene/index/SegmentInfos.java (revision 1140705) +++ lucene/src/java/org/apache/lucene/index/SegmentInfos.java (working copy) @@ -101,6 +101,9 @@ /* This must always point to the most recent file format. */ public static final int CURRENT_FORMAT = FORMAT_3_1; + + public static final int FORMAT_MINIMUM = FORMAT; + public static final int FORMAT_MAXIMUM = CURRENT_FORMAT; public int counter = 0; // used to name new segments /** @@ -267,16 +270,17 @@ try { int format = input.readInt(); - if(format < 0){ // file contains explicit format info - // check that it is a format we can understand - if (format < CURRENT_FORMAT) - throw new CorruptIndexException("Unknown format version: " + format); - version = input.readLong(); // read version - counter = input.readInt(); // read counter + // check that it is a format we can understand + if (format > FORMAT_MINIMUM) { + throw new IndexFormatTooOldException(segmentFileName, format, + FORMAT_MINIMUM, FORMAT_MAXIMUM); } - else{ // file is in old format without explicit format info - counter = format; + if (format < FORMAT_MAXIMUM) { + throw new IndexFormatTooNewException(segmentFileName, format, + FORMAT_MINIMUM, FORMAT_MAXIMUM); } + version = input.readLong(); // read version + counter = input.readInt(); // read counter for (int i = input.readInt(); i > 0; i--) { // read segmentInfos SegmentInfo si = new SegmentInfo(directory, format, input);