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.store.FSDirectory;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.document.Document;
import java.text.NumberFormat;
import java.io.PrintStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
/**
* Basic tool to check the health of an index and write a
* new segments file that removes reference to problematic
* segments. There are many more checks that this tool
* could do but does not yet, eg: reconstructing a segments
* file by looking for all loadable segments (if no segments
* file is found), removing specifically specified segments,
* listing files that exist but are not referenced, etc.
*/
public class CheckIndex {
public static PrintStream out = System.out;
private static class MySegmentTermDocs extends SegmentTermDocs {
int delCount;
MySegmentTermDocs(SegmentReader p) {
super(p);
}
public void seek(Term term) throws IOException {
super.seek(term);
delCount = 0;
}
protected void skippingDoc() throws IOException {
delCount++;
}
}
/** Returns true if index is clean, else false.*/
public static boolean check(Directory dir, boolean doFix) throws IOException {
NumberFormat nf = NumberFormat.getInstance();
SegmentInfos sis = new SegmentInfos();
try {
sis.read(dir);
} catch (Throwable t) {
out.println("ERROR: could not read any segments file in directory");
t.printStackTrace(out);
return false;
}
final int numSegments = sis.size();
final String segmentsFileName = sis.getCurrentSegmentFileName();
IndexInput input = null;
try {
input = dir.openInput(segmentsFileName);
} catch (Throwable t) {
out.println("ERROR: could not open segments file in directory");
t.printStackTrace(out);
return false;
}
int format = 0;
try {
format = input.readInt();
} catch (Throwable t) {
out.println("ERROR: could not read segment file version in directory");
t.printStackTrace(out);
return false;
} finally {
if (input != null)
input.close();
}
String sFormat = "";
boolean skip = false;
if (format == SegmentInfos.FORMAT)
sFormat = "FORMAT [Lucene Pre-2.1]";
if (format == SegmentInfos.FORMAT_LOCKLESS)
sFormat = "FORMAT_LOCKLESS [Lucene 2.1]";
else if (format == SegmentInfos.FORMAT_SINGLE_NORM_FILE)
sFormat = "FORMAT_SINGLE_NORM_FILE [Lucene 2.2]";
else if (format == SegmentInfos.FORMAT_SHARED_DOC_STORE)
sFormat = "FORMAT_SHARED_DOC_STORE [Lucene 2.3]";
else if (format < SegmentInfos.FORMAT_SHARED_DOC_STORE) {
sFormat = "int=" + format + " [newer version of Lucene than this tool]";
skip = true;
} else {
sFormat = format + " [Lucene 1.3 or prior]";
}
out.println("Segments file=" + segmentsFileName + " numSegments=" + numSegments + " version=" + sFormat);
if (skip) {
out.println("\nERROR: this index appears to be created by a newer version of Lucene than this tool was compiled on; please re-compile this tool on the matching version of Lucene; exiting");
return false;
}
SegmentInfos newSIS = (SegmentInfos) sis.clone();
newSIS.clear();
boolean changed = false;
int totLoseDocCount = 0;
int numBadSegments = 0;
for(int i=0;i
Ads help maintain this website.