You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2010/11/12 12:01:21 UTC
svn commit: r1034342 -
/lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/SegmentInfos.java
Author: mikemccand
Date: Fri Nov 12 11:01:21 2010
New Revision: 1034342
URL: http://svn.apache.org/viewvc?rev=1034342&view=rev
Log:
LUCENE-2576: change segments_N retry logic to re-list the directory before falling back to segments_(N-1)
Modified:
lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/SegmentInfos.java
Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/SegmentInfos.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/SegmentInfos.java?rev=1034342&r1=1034341&r2=1034342&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/SegmentInfos.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/SegmentInfos.java Fri Nov 12 11:01:21 2010
@@ -470,9 +470,9 @@ public final class SegmentInfos extends
long gen = 0;
int genLookaheadCount = 0;
IOException exc = null;
- boolean retry = false;
+ int retryCount = 0;
- int method = 0;
+ boolean useFirstMethod = true;
// Loop until we succeed in calling doBody() without
// hitting an IOException. An IOException most likely
@@ -486,14 +486,15 @@ public final class SegmentInfos extends
// it.
// We have three methods for determining the current
- // generation. We try the first two in parallel, and
- // fall back to the third when necessary.
+ // generation. We try the first two in parallel (when
+ // useFirstMethod is true), and fall back to the third
+ // when necessary.
while(true) {
- if (0 == method) {
+ if (useFirstMethod) {
- // Method 1: list the directory and use the highest
+ // List the directory and use the highest
// segments_N file. This method works well as long
// as there is no stale caching on the directory
// contents (NOTE: NFS clients often have such stale
@@ -504,14 +505,15 @@ public final class SegmentInfos extends
files = directory.listAll();
- if (files != null)
+ if (files != null) {
genA = getCurrentSegmentGeneration(files);
-
+ }
+
if (infoStream != null) {
message("directory listing genA=" + genA);
}
- // Method 2: open segments.gen and read its
+ // Also open segments.gen and read its
// contents. Then we take the larger of the two
// gens. This way, if either approach is hitting
// a stale cache (NFS) we have a better chance of
@@ -573,51 +575,42 @@ public final class SegmentInfos extends
// Pick the larger of the two gen's:
gen = Math.max(genA, genB);
-
+
if (gen == -1) {
// Neither approach found a generation
throw new IndexNotFoundException("no segments* file found in " + directory + ": files: " + Arrays.toString(files));
}
}
- // Third method (fallback if first & second methods
- // are not reliable): since both directory cache and
+ if (useFirstMethod && lastGen == gen && retryCount >= 2) {
+ // Give up on first method -- this is 3rd cycle on
+ // listing directory and checking gen file to
+ // attempt to locate the segments file.
+ useFirstMethod = false;
+ }
+
+ // Second method: since both directory cache and
// file contents cache seem to be stale, just
// advance the generation.
- if (1 == method || (0 == method && lastGen == gen && retry)) {
-
- method = 1;
-
+ if (!useFirstMethod) {
if (genLookaheadCount < defaultGenLookaheadCount) {
gen++;
genLookaheadCount++;
if (infoStream != null) {
message("look ahead increment gen to " + gen);
}
- }
- }
-
- if (lastGen == gen) {
-
- // This means we're about to try the same
- // segments_N last tried. This is allowed,
- // exactly once, because writer could have been in
- // the process of writing segments_N last time.
-
- if (retry) {
- // OK, we've tried the same segments_N file
- // twice in a row, so this must be a real
- // error. We throw the original exception we
- // got.
- throw exc;
} else {
- retry = true;
+ // All attempts have failed -- throw first exc:
+ throw exc;
}
-
- } else if (0 == method) {
- // Segment file has advanced since our last loop, so
- // reset retry:
- retry = false;
+ } else if (lastGen == gen) {
+ // This means we're about to try the same
+ // segments_N last tried.
+ retryCount++;
+ } else {
+ // Segment file has advanced since our last loop
+ // (we made "progress"), so reset retryCount:
+ retryCount = 0;
}
lastGen = gen;
@@ -640,13 +633,13 @@ public final class SegmentInfos extends
}
if (infoStream != null) {
- message("primary Exception on '" + segmentFileName + "': " + err + "'; will retry: retry=" + retry + "; gen = " + gen);
+ message("primary Exception on '" + segmentFileName + "': " + err + "'; will retry: retryCount=" + retryCount + "; gen = " + gen);
}
- if (!retry && gen > 1) {
+ if (gen > 1 && useFirstMethod && retryCount == 1) {
- // This is our first time trying this segments
- // file (because retry is false), and, there is
+ // This is our second time trying this same segments
+ // file (because retryCount is 1), and, there is
// possibly a segments_(N-1) (because gen > 1).
// So, check if the segments_(N-1) exists and
// try it if so:
@@ -719,7 +712,7 @@ public final class SegmentInfos extends
// since lastGeneration isn't incremented:
try {
final String segmentFileName = IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
- "",
+ "",
generation);
dir.deleteFile(segmentFileName);
} catch (Throwable t) {