mirror of https://github.com/apache/lucene.git
LUCENE-1354: Provide programmatic access to CheckIndex
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@693508 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
dadaebc290
commit
2bb9ab2246
|
@ -269,6 +269,8 @@ New features
|
||||||
|
|
||||||
18. LUCENE-1001: Provide access to Payloads via Spans. All existing Span Query implementations in Lucene implement. (Mark Miller, Grant Ingersoll)
|
18. LUCENE-1001: Provide access to Payloads via Spans. All existing Span Query implementations in Lucene implement. (Mark Miller, Grant Ingersoll)
|
||||||
|
|
||||||
|
19. LUCENE-1354: Provide programmatic access to CheckIndex (Grant Ingersoll, Mike McCandless)
|
||||||
|
|
||||||
Optimizations
|
Optimizations
|
||||||
|
|
||||||
1. LUCENE-705: When building a compound file, use
|
1. LUCENE-705: When building a compound file, use
|
||||||
|
|
|
@ -42,7 +42,7 @@ import java.util.ArrayList;
|
||||||
|
|
||||||
public class CheckIndex {
|
public class CheckIndex {
|
||||||
|
|
||||||
public static PrintStream out = System.out;
|
public static PrintStream out = null;
|
||||||
|
|
||||||
private static class MySegmentTermDocs extends SegmentTermDocs {
|
private static class MySegmentTermDocs extends SegmentTermDocs {
|
||||||
|
|
||||||
|
@ -63,21 +63,23 @@ public class CheckIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if index is clean, else false.*/
|
/** Returns true if index is clean, else false.*/
|
||||||
public static boolean check(Directory dir, boolean doFix) throws IOException {
|
public static CheckIndexStatus check(Directory dir, boolean doFix) throws IOException {
|
||||||
return check(dir, doFix, null);
|
return check(dir, doFix, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if index is clean, else false.*/
|
/** Returns true if index is clean, else false.*/
|
||||||
public static boolean check(Directory dir, boolean doFix, List onlySegments) throws IOException {
|
public static CheckIndexStatus check(Directory dir, boolean doFix, List onlySegments) throws IOException {
|
||||||
NumberFormat nf = NumberFormat.getInstance();
|
NumberFormat nf = NumberFormat.getInstance();
|
||||||
SegmentInfos sis = new SegmentInfos();
|
SegmentInfos sis = new SegmentInfos();
|
||||||
|
CheckIndexStatus result = new CheckIndexStatus();
|
||||||
|
result.dir = dir;
|
||||||
try {
|
try {
|
||||||
sis.read(dir);
|
sis.read(dir);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
out.println("ERROR: could not read any segments file in directory");
|
msg("ERROR: could not read any segments file in directory");
|
||||||
|
result.missingSegments = true;
|
||||||
t.printStackTrace(out);
|
t.printStackTrace(out);
|
||||||
return false;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int numSegments = sis.size();
|
final int numSegments = sis.size();
|
||||||
|
@ -86,17 +88,19 @@ public class CheckIndex {
|
||||||
try {
|
try {
|
||||||
input = dir.openInput(segmentsFileName);
|
input = dir.openInput(segmentsFileName);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
out.println("ERROR: could not open segments file in directory");
|
msg("ERROR: could not open segments file in directory");
|
||||||
t.printStackTrace(out);
|
t.printStackTrace(out);
|
||||||
return false;
|
result.cantOpenSegments = true;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
int format = 0;
|
int format = 0;
|
||||||
try {
|
try {
|
||||||
format = input.readInt();
|
format = input.readInt();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
out.println("ERROR: could not read segment file version in directory");
|
msg("ERROR: could not read segment file version in directory");
|
||||||
t.printStackTrace(out);
|
t.printStackTrace(out);
|
||||||
return false;
|
result.missingSegmentVersion = true;
|
||||||
|
return result;
|
||||||
} finally {
|
} finally {
|
||||||
if (input != null)
|
if (input != null)
|
||||||
input.close();
|
input.close();
|
||||||
|
@ -128,7 +132,10 @@ public class CheckIndex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out.println("Segments file=" + segmentsFileName + " numSegments=" + numSegments + " version=" + sFormat);
|
msg("Segments file=" + segmentsFileName + " numSegments=" + numSegments + " version=" + sFormat);
|
||||||
|
result.segmentsFileName = segmentsFileName;
|
||||||
|
result.numSegments = numSegments;
|
||||||
|
result.segmentFormat = sFormat;
|
||||||
|
|
||||||
if (onlySegments != null) {
|
if (onlySegments != null) {
|
||||||
out.print("\nChecking only these segments:");
|
out.print("\nChecking only these segments:");
|
||||||
|
@ -136,56 +143,80 @@ public class CheckIndex {
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
out.print(" " + it.next());
|
out.print(" " + it.next());
|
||||||
}
|
}
|
||||||
out.println(":");
|
result.segmentsChecked.addAll(onlySegments);
|
||||||
|
msg(":");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skip) {
|
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");
|
msg("\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;
|
result.toolOutOfDate = true;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SegmentInfos newSIS = (SegmentInfos) sis.clone();
|
|
||||||
newSIS.clear();
|
result.newSegments = (SegmentInfos) sis.clone();
|
||||||
boolean changed = false;
|
result.newSegments.clear();
|
||||||
int totLoseDocCount = 0;
|
|
||||||
int numBadSegments = 0;
|
|
||||||
for(int i=0;i<numSegments;i++) {
|
for(int i=0;i<numSegments;i++) {
|
||||||
final SegmentInfo info = sis.info(i);
|
final SegmentInfo info = sis.info(i);
|
||||||
if (onlySegments != null && !onlySegments.contains(info.name))
|
if (onlySegments != null && !onlySegments.contains(info.name))
|
||||||
continue;
|
continue;
|
||||||
out.println(" " + (1+i) + " of " + numSegments + ": name=" + info.name + " docCount=" + info.docCount);
|
CheckIndexStatus.SegmentInfoStatus segInfoStat = new CheckIndexStatus.SegmentInfoStatus();
|
||||||
|
result.segmentInfos.add(segInfoStat);
|
||||||
|
msg(" " + (1+i) + " of " + numSegments + ": name=" + info.name + " docCount=" + info.docCount);
|
||||||
|
segInfoStat.name = info.name;
|
||||||
|
segInfoStat.docCount = info.docCount;
|
||||||
|
|
||||||
int toLoseDocCount = info.docCount;
|
int toLoseDocCount = info.docCount;
|
||||||
|
|
||||||
SegmentReader reader = null;
|
SegmentReader reader = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
out.println(" compound=" + info.getUseCompoundFile());
|
msg(" compound=" + info.getUseCompoundFile());
|
||||||
out.println(" hasProx=" + info.getHasProx());
|
segInfoStat.compound = info.getUseCompoundFile();
|
||||||
out.println(" numFiles=" + info.files().size());
|
msg(" hasProx=" + info.getHasProx());
|
||||||
out.println(" size (MB)=" + nf.format(info.sizeInBytes()/(1024.*1024.)));
|
segInfoStat.hasProx = info.getHasProx();
|
||||||
|
msg(" numFiles=" + info.files().size());
|
||||||
|
segInfoStat.numFiles = info.files().size();
|
||||||
|
msg(" size (MB)=" + nf.format(info.sizeInBytes()/(1024.*1024.)));
|
||||||
|
segInfoStat.sizeMB = info.sizeInBytes()/(1024.*1024.);
|
||||||
|
|
||||||
|
|
||||||
final int docStoreOffset = info.getDocStoreOffset();
|
final int docStoreOffset = info.getDocStoreOffset();
|
||||||
if (docStoreOffset != -1) {
|
if (docStoreOffset != -1) {
|
||||||
out.println(" docStoreOffset=" + docStoreOffset);
|
msg(" docStoreOffset=" + docStoreOffset);
|
||||||
out.println(" docStoreSegment=" + info.getDocStoreSegment());
|
segInfoStat.docStoreOffset = docStoreOffset;
|
||||||
out.println(" docStoreIsCompoundFile=" + info.getDocStoreIsCompoundFile());
|
msg(" docStoreSegment=" + info.getDocStoreSegment());
|
||||||
|
segInfoStat.docStoreSegment = info.getDocStoreSegment();
|
||||||
|
msg(" docStoreIsCompoundFile=" + info.getDocStoreIsCompoundFile());
|
||||||
|
segInfoStat.docStoreCompoundFile = info.getDocStoreIsCompoundFile();
|
||||||
}
|
}
|
||||||
final String delFileName = info.getDelFileName();
|
final String delFileName = info.getDelFileName();
|
||||||
if (delFileName == null)
|
if (delFileName == null){
|
||||||
out.println(" no deletions");
|
msg(" no deletions");
|
||||||
else
|
segInfoStat.hasDeletions = false;
|
||||||
out.println(" has deletions [delFileName=" + delFileName + "]");
|
}
|
||||||
|
else{
|
||||||
|
msg(" has deletions [delFileName=" + delFileName + "]");
|
||||||
|
segInfoStat.hasDeletions = true;
|
||||||
|
segInfoStat.deletionsFileName = delFileName;
|
||||||
|
|
||||||
|
}
|
||||||
out.print(" test: open reader.........");
|
out.print(" test: open reader.........");
|
||||||
reader = SegmentReader.get(info);
|
reader = SegmentReader.get(info);
|
||||||
final int numDocs = reader.numDocs();
|
final int numDocs = reader.numDocs();
|
||||||
toLoseDocCount = numDocs;
|
toLoseDocCount = numDocs;
|
||||||
if (reader.hasDeletions()) {
|
if (reader.hasDeletions()) {
|
||||||
if (info.docCount - numDocs != info.getDelCount())
|
if (info.docCount - numDocs != info.getDelCount()){
|
||||||
throw new RuntimeException("delete count mismatch: info=" + info.getDelCount() + " vs reader=" + (info.docCount - numDocs));
|
throw new RuntimeException("delete count mismatch: info=" + info.getDelCount() + " vs reader=" + (info.docCount - numDocs));
|
||||||
out.println("OK [" + (info.docCount - numDocs) + " deleted docs]");
|
}
|
||||||
|
segInfoStat.numDeleted = info.docCount - numDocs;
|
||||||
|
msg("OK [" + (segInfoStat.numDeleted) + " deleted docs]");
|
||||||
} else {
|
} else {
|
||||||
if (info.getDelCount() != 0)
|
if (info.getDelCount() != 0){
|
||||||
throw new RuntimeException("delete count mismatch: info=" + info.getDelCount() + " vs reader=" + (info.docCount - numDocs));
|
throw new RuntimeException("delete count mismatch: info=" + info.getDelCount() + " vs reader=" + (info.docCount - numDocs));
|
||||||
out.println("OK");
|
}
|
||||||
|
msg("OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
out.print(" test: fields, norms.......");
|
out.print(" test: fields, norms.......");
|
||||||
|
@ -198,8 +229,8 @@ public class CheckIndex {
|
||||||
throw new RuntimeException("norms for field \"" + fieldName + "\" is length " + b.length + " != maxDoc " + info.docCount);
|
throw new RuntimeException("norms for field \"" + fieldName + "\" is length " + b.length + " != maxDoc " + info.docCount);
|
||||||
|
|
||||||
}
|
}
|
||||||
out.println("OK [" + fieldNames.size() + " fields]");
|
msg("OK [" + fieldNames.size() + " fields]");
|
||||||
|
segInfoStat.numFields = fieldNames.size();
|
||||||
out.print(" test: terms, freq, prox...");
|
out.print(" test: terms, freq, prox...");
|
||||||
final TermEnum termEnum = reader.terms();
|
final TermEnum termEnum = reader.terms();
|
||||||
final TermPositions termPositions = reader.termPositions();
|
final TermPositions termPositions = reader.termPositions();
|
||||||
|
@ -255,7 +286,7 @@ public class CheckIndex {
|
||||||
throw new RuntimeException("term " + term + " docFreq=" + docFreq + " != num docs seen " + freq0 + " + num docs deleted " + delCount);
|
throw new RuntimeException("term " + term + " docFreq=" + docFreq + " != num docs seen " + freq0 + " + num docs deleted " + delCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.println("OK [" + termCount + " terms; " + totFreq + " terms/docs pairs; " + totPos + " tokens]");
|
msg("OK [" + termCount + " terms; " + totFreq + " terms/docs pairs; " + totPos + " tokens]");
|
||||||
|
|
||||||
out.print(" test: stored fields.......");
|
out.print(" test: stored fields.......");
|
||||||
int docCount = 0;
|
int docCount = 0;
|
||||||
|
@ -270,7 +301,7 @@ public class CheckIndex {
|
||||||
if (docCount != reader.numDocs())
|
if (docCount != reader.numDocs())
|
||||||
throw new RuntimeException("docCount=" + docCount + " but saw " + docCount + " undeleted docs");
|
throw new RuntimeException("docCount=" + docCount + " but saw " + docCount + " undeleted docs");
|
||||||
|
|
||||||
out.println("OK [" + totFields + " total field count; avg " + nf.format((((float) totFields)/docCount)) + " fields per doc]");
|
msg("OK [" + totFields + " total field count; avg " + nf.format((((float) totFields)/docCount)) + " fields per doc]");
|
||||||
|
|
||||||
out.print(" test: term vectors........");
|
out.print(" test: term vectors........");
|
||||||
int totVectors = 0;
|
int totVectors = 0;
|
||||||
|
@ -281,22 +312,21 @@ public class CheckIndex {
|
||||||
totVectors += tfv.length;
|
totVectors += tfv.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
out.println("OK [" + totVectors + " total vector count; avg " + nf.format((((float) totVectors)/docCount)) + " term/freq vector fields per doc]");
|
msg("OK [" + totVectors + " total vector count; avg " + nf.format((((float) totVectors)/docCount)) + " term/freq vector fields per doc]");
|
||||||
out.println("");
|
msg("");
|
||||||
|
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
out.println("FAILED");
|
msg("FAILED");
|
||||||
String comment;
|
String comment;
|
||||||
if (doFix)
|
if (doFix)
|
||||||
comment = "will remove reference to this segment (-fix is specified)";
|
comment = "will remove reference to this segment (-fix is specified)";
|
||||||
else
|
else
|
||||||
comment = "would remove reference to this segment (-fix was not specified)";
|
comment = "would remove reference to this segment (-fix was not specified)";
|
||||||
out.println(" WARNING: " + comment + "; full exception:");
|
msg(" WARNING: " + comment + "; full exception:");
|
||||||
t.printStackTrace(out);
|
t.printStackTrace(out);
|
||||||
out.println("");
|
msg("");
|
||||||
totLoseDocCount += toLoseDocCount;
|
result.totLoseDocCount += toLoseDocCount;
|
||||||
numBadSegments++;
|
result.numBadSegments++;
|
||||||
changed = true;
|
|
||||||
continue;
|
continue;
|
||||||
} finally {
|
} finally {
|
||||||
if (reader != null)
|
if (reader != null)
|
||||||
|
@ -304,50 +334,25 @@ public class CheckIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keeper
|
// Keeper
|
||||||
newSIS.add(info.clone());
|
result.newSegments.add(info.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!changed) {
|
if (0 == result.numBadSegments) {
|
||||||
out.println("No problems were detected with this index.\n");
|
result.clean = true;
|
||||||
return true;
|
msg("No problems were detected with this index.\n");
|
||||||
} else {
|
} else
|
||||||
out.println("WARNING: " + numBadSegments + " broken segments detected");
|
msg("WARNING: " + result.numBadSegments + " broken segments (containing " + result.totLoseDocCount + " documents) detected");
|
||||||
if (doFix)
|
|
||||||
out.println("WARNING: " + totLoseDocCount + " documents will be lost");
|
|
||||||
else
|
|
||||||
out.println("WARNING: " + totLoseDocCount + " documents would be lost if -fix were specified");
|
|
||||||
out.println();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doFix) {
|
return result;
|
||||||
out.println("NOTE: will write new segments file in 5 seconds; this will remove " + totLoseDocCount + " docs from the index. THIS IS YOUR LAST CHANCE TO CTRL+C!");
|
}
|
||||||
for(int i=0;i<5;i++) {
|
|
||||||
try {
|
/** Repairs the index using previously returned result from
|
||||||
Thread.sleep(1000);
|
* {@link #check}. <b>WARNING</b>: this writes a new
|
||||||
} catch (InterruptedException ie) {
|
* segments file into the index, effectively removing
|
||||||
Thread.currentThread().interrupt();
|
* all documents in broken segments from the index. BE
|
||||||
i--;
|
* CAREFUL. */
|
||||||
continue;
|
static public void fix(CheckIndexStatus result) throws IOException {
|
||||||
}
|
result.newSegments.commit(result.dir);
|
||||||
|
|
||||||
out.println(" " + (5-i) + "...");
|
|
||||||
}
|
|
||||||
out.print("Writing...");
|
|
||||||
try {
|
|
||||||
newSIS.commit(dir);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
out.println("FAILED; exiting");
|
|
||||||
t.printStackTrace(out);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
out.println("OK");
|
|
||||||
out.println("Wrote new segments file \"" + newSIS.getCurrentSegmentFileName() + "\"");
|
|
||||||
} else {
|
|
||||||
out.println("NOTE: would write new segments file [-fix was not specified]");
|
|
||||||
}
|
|
||||||
out.println("");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean assertsOn;
|
static boolean assertsOn;
|
||||||
|
@ -357,6 +362,12 @@ public class CheckIndex {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void msg(String msg) {
|
||||||
|
if (out != null) {
|
||||||
|
out.println(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Throwable {
|
public static void main(String[] args) throws Throwable {
|
||||||
|
|
||||||
boolean doFix = false;
|
boolean doFix = false;
|
||||||
|
@ -369,14 +380,14 @@ public class CheckIndex {
|
||||||
i++;
|
i++;
|
||||||
} else if (args[i].equals("-segment")) {
|
} else if (args[i].equals("-segment")) {
|
||||||
if (i == args.length-1) {
|
if (i == args.length-1) {
|
||||||
out.println("ERROR: missing name for -segment option");
|
msg("ERROR: missing name for -segment option");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
onlySegments.add(args[i+1]);
|
onlySegments.add(args[i+1]);
|
||||||
i += 2;
|
i += 2;
|
||||||
} else {
|
} else {
|
||||||
if (indexPath != null) {
|
if (indexPath != null) {
|
||||||
out.println("ERROR: unexpected extra argument '" + args[i] + "'");
|
msg("ERROR: unexpected extra argument '" + args[i] + "'");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
indexPath = args[i];
|
indexPath = args[i];
|
||||||
|
@ -385,8 +396,8 @@ public class CheckIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indexPath == null) {
|
if (indexPath == null) {
|
||||||
out.println("\nERROR: index path not specified");
|
msg("\nERROR: index path not specified");
|
||||||
out.println("\nUsage: java org.apache.lucene.index.CheckIndex pathToIndex [-fix] [-segment X] [-segment Y]\n" +
|
msg("\nUsage: java org.apache.lucene.index.CheckIndex pathToIndex [-fix] [-segment X] [-segment Y]\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
" -fix: actually write a new segments_N file, removing any problematic segments\n" +
|
" -fix: actually write a new segments_N file, removing any problematic segments\n" +
|
||||||
" -segment X: only check the specified segments. This can be specified multiple\n" +
|
" -segment X: only check the specified segments. This can be specified multiple\n" +
|
||||||
|
@ -412,31 +423,55 @@ public class CheckIndex {
|
||||||
if (onlySegments.size() == 0)
|
if (onlySegments.size() == 0)
|
||||||
onlySegments = null;
|
onlySegments = null;
|
||||||
else if (doFix) {
|
else if (doFix) {
|
||||||
out.println("ERROR: cannot specify both -fix and -segment");
|
msg("ERROR: cannot specify both -fix and -segment");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert testAsserts();
|
assert testAsserts();
|
||||||
if (!assertsOn)
|
if (!assertsOn)
|
||||||
out.println("\nNOTE: testing will be more thorough if you run java with '-ea:org.apache.lucene', so assertions are enabled");
|
msg("\nNOTE: testing will be more thorough if you run java with '-ea:org.apache.lucene', so assertions are enabled");
|
||||||
|
|
||||||
out.println("\nOpening index @ " + indexPath + "\n");
|
msg("\nOpening index @ " + indexPath + "\n");
|
||||||
Directory dir = null;
|
Directory dir = null;
|
||||||
try {
|
try {
|
||||||
dir = FSDirectory.getDirectory(indexPath);
|
dir = FSDirectory.getDirectory(indexPath);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
out.println("ERROR: could not open directory \"" + indexPath + "\"; exiting");
|
msg("ERROR: could not open directory \"" + indexPath + "\"; exiting");
|
||||||
t.printStackTrace(out);
|
t.printStackTrace(out);
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isClean = check(dir, doFix, onlySegments);
|
CheckIndexStatus result = check(dir, doFix, onlySegments);
|
||||||
|
|
||||||
|
if (!result.clean) {
|
||||||
|
if (!doFix){
|
||||||
|
msg("WARNING: would write new segments file, and " + result.totLoseDocCount + " documents would be lost, if -fix were specified\n");
|
||||||
|
} else {
|
||||||
|
msg("WARNING: " + result.totLoseDocCount + " documents will be lost\n");
|
||||||
|
msg("NOTE: will write new segments file in 5 seconds; this will remove " + result.totLoseDocCount + " docs from the index. THIS IS YOUR LAST CHANCE TO CTRL+C!");
|
||||||
|
for(int s=0;s<5;s++) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
s--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
msg(" " + (5-i) + "...");
|
||||||
|
}
|
||||||
|
msg("Writing...");
|
||||||
|
CheckIndex.fix(result);
|
||||||
|
}
|
||||||
|
msg("OK");
|
||||||
|
msg("Wrote new segments file \"" + result.newSegments.getCurrentSegmentFileName() + "\"");
|
||||||
|
}
|
||||||
|
msg("");
|
||||||
|
|
||||||
final int exitCode;
|
final int exitCode;
|
||||||
if (isClean)
|
if (result != null && result.clean == true)
|
||||||
exitCode = 0;
|
exitCode = 0;
|
||||||
else
|
else
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
System.exit(exitCode);
|
System.exit(exitCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
package org.apache.lucene.index;
|
||||||
|
|
||||||
|
import org.apache.lucene.store.Directory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
public class CheckIndexStatus {
|
||||||
|
|
||||||
|
public boolean clean;
|
||||||
|
|
||||||
|
|
||||||
|
public boolean missingSegments;
|
||||||
|
public boolean cantOpenSegments;
|
||||||
|
public boolean missingSegmentVersion;
|
||||||
|
|
||||||
|
|
||||||
|
public String segmentsFileName;
|
||||||
|
public int numSegments;
|
||||||
|
public String segmentFormat;
|
||||||
|
public List/*<String>*/ segmentsChecked = new ArrayList();
|
||||||
|
|
||||||
|
public boolean toolOutOfDate;
|
||||||
|
|
||||||
|
public List/*<SegmentInfoStatus*/ segmentInfos = new ArrayList();
|
||||||
|
public Directory dir;
|
||||||
|
public SegmentInfos newSegments;
|
||||||
|
public int totLoseDocCount;
|
||||||
|
public int numBadSegments;
|
||||||
|
|
||||||
|
public static class SegmentInfoStatus{
|
||||||
|
public String name;
|
||||||
|
public int docCount;
|
||||||
|
public boolean compound;
|
||||||
|
public int numFiles;
|
||||||
|
public double sizeMB;
|
||||||
|
public int docStoreOffset = -1;
|
||||||
|
public String docStoreSegment;
|
||||||
|
public boolean docStoreCompoundFile;
|
||||||
|
|
||||||
|
public boolean hasDeletions;
|
||||||
|
public String deletionsFileName;
|
||||||
|
public int numDeleted;
|
||||||
|
|
||||||
|
public boolean openReaderPassed;
|
||||||
|
|
||||||
|
int numFields;
|
||||||
|
|
||||||
|
public boolean hasProx;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -49,13 +49,14 @@ public class TestCheckIndex extends LuceneTestCase {
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
|
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
|
||||||
|
|
||||||
CheckIndex.out = new PrintStream(bos);
|
CheckIndex.out = new PrintStream(bos);
|
||||||
if (!CheckIndex.check(dir, false, null)) {
|
CheckIndexStatus indexStatus = CheckIndex.check(dir, false, null);
|
||||||
|
if (indexStatus.clean == false) {
|
||||||
System.out.println("CheckIndex failed");
|
System.out.println("CheckIndex failed");
|
||||||
System.out.println(bos.toString());
|
System.out.println(bos.toString());
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
final List onlySegments = new ArrayList();
|
final List onlySegments = new ArrayList();
|
||||||
onlySegments.add("_0");
|
onlySegments.add("_0");
|
||||||
assertTrue(CheckIndex.check(dir, false, onlySegments));
|
assertTrue(CheckIndex.check(dir, false, onlySegments).clean == true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.lucene.index.IndexWriter;
|
||||||
import org.apache.lucene.index.MergeScheduler;
|
import org.apache.lucene.index.MergeScheduler;
|
||||||
import org.apache.lucene.index.ConcurrentMergeScheduler;
|
import org.apache.lucene.index.ConcurrentMergeScheduler;
|
||||||
import org.apache.lucene.index.CheckIndex;
|
import org.apache.lucene.index.CheckIndex;
|
||||||
|
import org.apache.lucene.index.CheckIndexStatus;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
@ -60,7 +61,10 @@ public class _TestUtil {
|
||||||
public static boolean checkIndex(Directory dir) throws IOException {
|
public static boolean checkIndex(Directory dir) throws IOException {
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
|
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
|
||||||
CheckIndex.out = new PrintStream(bos);
|
CheckIndex.out = new PrintStream(bos);
|
||||||
if (!CheckIndex.check(dir, false, null)) {
|
|
||||||
|
//TODO: fix this
|
||||||
|
CheckIndexStatus indexStatus = CheckIndex.check(dir, false, null);
|
||||||
|
if (indexStatus == null || indexStatus.clean == false) {
|
||||||
System.out.println("CheckIndex failed");
|
System.out.println("CheckIndex failed");
|
||||||
System.out.println(bos.toString());
|
System.out.println(bos.toString());
|
||||||
throw new RuntimeException("CheckIndex failed");
|
throw new RuntimeException("CheckIndex failed");
|
||||||
|
|
Loading…
Reference in New Issue