mirror of https://github.com/apache/lucene.git
LUCENE-1018: fix intermittent exception in TestConcurrentMergeScheduler
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@582508 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9de7367279
commit
ceebb95d63
|
@ -107,10 +107,8 @@ public class ConcurrentMergeScheduler implements MergeScheduler {
|
|||
while(mergeThreads.size() > 0) {
|
||||
if (VERBOSE) {
|
||||
message("now wait for threads; currently " + mergeThreads.size() + " still running");
|
||||
for(int i=0;i<mergeThreads.size();i++) {
|
||||
final MergeThread mergeThread = ((MergeThread) mergeThreads.get(i));
|
||||
message(" " + i + ": " + mergeThread.merge.segString(dir));
|
||||
}
|
||||
for(int i=0;i<mergeThreads.size();i++)
|
||||
message(" " + i + ": " + ((MergeThread) mergeThreads.get(i)));
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -210,24 +208,35 @@ public class ConcurrentMergeScheduler implements MergeScheduler {
|
|||
private class MergeThread extends Thread {
|
||||
|
||||
IndexWriter writer;
|
||||
MergePolicy.OneMerge merge;
|
||||
MergePolicy.OneMerge startMerge;
|
||||
MergePolicy.OneMerge runningMerge;
|
||||
|
||||
public MergeThread(IndexWriter writer, MergePolicy.OneMerge merge) throws IOException {
|
||||
public MergeThread(IndexWriter writer, MergePolicy.OneMerge startMerge) throws IOException {
|
||||
this.writer = writer;
|
||||
this.merge = merge;
|
||||
this.startMerge = startMerge;
|
||||
}
|
||||
|
||||
public synchronized void setRunningMerge(MergePolicy.OneMerge merge) {
|
||||
runningMerge = merge;
|
||||
}
|
||||
|
||||
public synchronized MergePolicy.OneMerge getRunningMerge() {
|
||||
return runningMerge;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
// First time through the while loop we do the merge
|
||||
// that we were started with:
|
||||
MergePolicy.OneMerge merge = this.startMerge;
|
||||
|
||||
try {
|
||||
|
||||
if (VERBOSE)
|
||||
message(" merge thread: start");
|
||||
|
||||
// First time through the while loop we do the merge
|
||||
// that we were started with:
|
||||
MergePolicy.OneMerge merge = this.merge;
|
||||
|
||||
while(true) {
|
||||
setRunningMerge(merge);
|
||||
writer.merge(merge);
|
||||
|
||||
// Subsequent times through the loop we do any new
|
||||
|
@ -248,13 +257,17 @@ public class ConcurrentMergeScheduler implements MergeScheduler {
|
|||
// When a merge was aborted & IndexWriter closed,
|
||||
// it's possible to get various IOExceptions,
|
||||
// NullPointerExceptions, AlreadyClosedExceptions:
|
||||
merge.setException(exc);
|
||||
writer.addMergeException(merge);
|
||||
if (merge != null) {
|
||||
merge.setException(exc);
|
||||
writer.addMergeException(merge);
|
||||
}
|
||||
|
||||
if (!merge.isAborted()) {
|
||||
if (merge == null || !merge.isAborted()) {
|
||||
// If the merge was not aborted then the exception
|
||||
// is real
|
||||
exceptions.add(exc);
|
||||
synchronized(ConcurrentMergeScheduler.this) {
|
||||
exceptions.add(exc);
|
||||
}
|
||||
|
||||
if (!suppressExceptions)
|
||||
// suppressExceptions is normally only set during
|
||||
|
@ -270,6 +283,9 @@ public class ConcurrentMergeScheduler implements MergeScheduler {
|
|||
}
|
||||
|
||||
public String toString() {
|
||||
MergePolicy.OneMerge merge = getRunningMerge();
|
||||
if (merge == null)
|
||||
merge = startMerge;
|
||||
return "merge thread: " + merge.segString(dir);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,6 +100,10 @@ final class IndexFileDeleter {
|
|||
private IndexDeletionPolicy policy;
|
||||
private DocumentsWriter docWriter;
|
||||
|
||||
/** Change to true to see details of reference counts when
|
||||
* infoStream != null */
|
||||
public static boolean VERBOSE_REF_COUNTS = false;
|
||||
|
||||
void setInfoStream(PrintStream infoStream) {
|
||||
this.infoStream = infoStream;
|
||||
if (infoStream != null)
|
||||
|
@ -342,6 +346,8 @@ final class IndexFileDeleter {
|
|||
deletable = null;
|
||||
int size = oldDeletable.size();
|
||||
for(int i=0;i<size;i++) {
|
||||
if (infoStream != null)
|
||||
message("delete pending file " + oldDeletable.get(i));
|
||||
deleteFile((String) oldDeletable.get(i));
|
||||
}
|
||||
}
|
||||
|
@ -441,7 +447,7 @@ final class IndexFileDeleter {
|
|||
for(int i=0;i<size;i++) {
|
||||
String fileName = (String) files.get(i);
|
||||
RefCount rc = getRefCount(fileName);
|
||||
if (infoStream != null) {
|
||||
if (infoStream != null && VERBOSE_REF_COUNTS) {
|
||||
message(" IncRef \"" + fileName + "\": pre-incr count is " + rc.count);
|
||||
}
|
||||
rc.IncRef();
|
||||
|
@ -457,7 +463,7 @@ final class IndexFileDeleter {
|
|||
|
||||
private void decRef(String fileName) throws IOException {
|
||||
RefCount rc = getRefCount(fileName);
|
||||
if (infoStream != null) {
|
||||
if (infoStream != null && VERBOSE_REF_COUNTS) {
|
||||
message(" DecRef \"" + fileName + "\": pre-decr count is " + rc.count);
|
||||
}
|
||||
if (0 == rc.DecRef()) {
|
||||
|
|
|
@ -1172,7 +1172,9 @@ public class IndexWriter {
|
|||
if (infoStream != null)
|
||||
message("now flush at close");
|
||||
|
||||
flush(true, true);
|
||||
// Only allow a new merge to be triggered if we are
|
||||
// going to wait for merges:
|
||||
flush(waitForMerges, true);
|
||||
|
||||
mergePolicy.close();
|
||||
|
||||
|
@ -1947,15 +1949,23 @@ public class IndexWriter {
|
|||
if (!waitForMerges) {
|
||||
// Abort all pending & running merges:
|
||||
Iterator it = pendingMerges.iterator();
|
||||
while(it.hasNext())
|
||||
((MergePolicy.OneMerge) it.next()).abort();
|
||||
|
||||
while(it.hasNext()) {
|
||||
final MergePolicy.OneMerge merge = (MergePolicy.OneMerge) it.next();
|
||||
if (infoStream != null)
|
||||
message("now abort pending merge " + merge.segString(directory));
|
||||
merge.abort();
|
||||
}
|
||||
pendingMerges.clear();
|
||||
it = runningMerges.iterator();
|
||||
while(it.hasNext())
|
||||
((MergePolicy.OneMerge) it.next()).abort();
|
||||
|
||||
it = runningMerges.iterator();
|
||||
while(it.hasNext()) {
|
||||
final MergePolicy.OneMerge merge = (MergePolicy.OneMerge) it.next();
|
||||
if (infoStream != null)
|
||||
message("now abort running merge " + merge.segString(directory));
|
||||
merge.abort();
|
||||
}
|
||||
runningMerges.clear();
|
||||
|
||||
mergingSegments.clear();
|
||||
notifyAll();
|
||||
} else {
|
||||
|
@ -3078,7 +3088,7 @@ public class IndexWriter {
|
|||
return mergedDocCount;
|
||||
}
|
||||
|
||||
void addMergeException(MergePolicy.OneMerge merge) {
|
||||
synchronized void addMergeException(MergePolicy.OneMerge merge) {
|
||||
if (!mergeExceptions.contains(merge) && mergeGen == merge.mergeGen)
|
||||
mergeExceptions.add(merge);
|
||||
}
|
||||
|
|
|
@ -225,8 +225,8 @@ public class TestConcurrentMergeScheduler extends TestCase {
|
|||
|
||||
try {
|
||||
directory.close();
|
||||
} catch (RuntimeException ioe) {
|
||||
// MockRAMDirectory will throw IOExceptions when there
|
||||
} catch (RuntimeException re) {
|
||||
// MockRAMDirectory will throw RuntimeExceptions when there
|
||||
// are still open files, which is OK since some merge
|
||||
// threads may still be running at this point.
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue