You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by mi...@apache.org on 2008/11/18 10:57:52 UTC
svn commit: r718540 - in /lucene/java/trunk/src:
java/org/apache/lucene/index/DirectoryIndexReader.java
java/org/apache/lucene/index/SegmentReader.java
test/org/apache/lucene/index/TestIndexReaderReopen.java
Author: mikemccand
Date: Tue Nov 18 01:57:51 2008
New Revision: 718540
URL: http://svn.apache.org/viewvc?rev=718540&view=rev
Log:
LUCENE-1453: make sure reopen of IndexReaders that own the directory don't close the directory too soon
Modified:
lucene/java/trunk/src/java/org/apache/lucene/index/DirectoryIndexReader.java
lucene/java/trunk/src/java/org/apache/lucene/index/SegmentReader.java
lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexReaderReopen.java
Modified: lucene/java/trunk/src/java/org/apache/lucene/index/DirectoryIndexReader.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/index/DirectoryIndexReader.java?rev=718540&r1=718539&r2=718540&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/index/DirectoryIndexReader.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/index/DirectoryIndexReader.java Tue Nov 18 01:57:51 2008
@@ -28,6 +28,7 @@
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.Lock;
import org.apache.lucene.store.LockObtainFailedException;
+import org.apache.lucene.store.FSDirectory;
/**
* IndexReader implementation that has access to a Directory.
@@ -147,7 +148,7 @@
return this;
}
- return (DirectoryIndexReader) new SegmentInfos.FindSegmentsFile(directory) {
+ final SegmentInfos.FindSegmentsFile finder = new SegmentInfos.FindSegmentsFile(directory) {
protected Object doBody(String segmentFileName) throws CorruptIndexException, IOException {
SegmentInfos infos = new SegmentInfos();
@@ -162,7 +163,35 @@
return newReader;
}
- }.run();
+ };
+
+ DirectoryIndexReader reader = null;
+
+ // While trying to reopen, we temporarily mark our
+ // closeDirectory as false. This way any exceptions hit
+ // partway while opening the reader, which is expected
+ // eg if writer is committing, won't close our
+ // directory. We restore this value below:
+ final boolean myCloseDirectory = closeDirectory;
+ closeDirectory = false;
+
+ try {
+ reader = (DirectoryIndexReader) finder.run();
+ } finally {
+ if (myCloseDirectory) {
+ assert directory instanceof FSDirectory;
+ // Restore my closeDirectory
+ closeDirectory = true;
+ if (reader != null && reader != this) {
+ // Success, and a new reader was actually opened
+ reader.closeDirectory = true;
+ // Clone the directory
+ reader.directory = FSDirectory.getDirectory(((FSDirectory) directory).getFile());
+ }
+ }
+ }
+
+ return reader;
}
/**
Modified: lucene/java/trunk/src/java/org/apache/lucene/index/SegmentReader.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/index/SegmentReader.java?rev=718540&r1=718539&r2=718540&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/index/SegmentReader.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/index/SegmentReader.java Tue Nov 18 01:57:51 2008
@@ -660,10 +660,13 @@
if (storeCFSReader != null)
storeCFSReader.close();
-
- // maybe close directory
- super.doClose();
}
+
+ // In DirectoryIndexReader.reopen, our directory
+ // instance was made private to us (cloned), so we
+ // always call super.doClose to possibly close the
+ // directory:
+ super.doClose();
}
static boolean hasDeletions(SegmentInfo si) throws IOException {
Modified: lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexReaderReopen.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexReaderReopen.java?rev=718540&r1=718539&r2=718540&view=diff
==============================================================================
--- lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexReaderReopen.java (original)
+++ lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexReaderReopen.java Tue Nov 18 01:57:51 2008
@@ -27,8 +27,6 @@
import java.util.Random;
import java.util.Set;
-import junit.framework.TestCase;
-
import org.apache.lucene.analysis.KeywordAnalyzer;
import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
@@ -43,6 +41,7 @@
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.store.AlreadyClosedException;
import org.apache.lucene.util.LuceneTestCase;
public class TestIndexReaderReopen extends LuceneTestCase {
@@ -603,7 +602,7 @@
TestIndexReader.assertIndexEquals(index1, index2);
try {
- ReaderCouple couple = refreshReader(index1, test, 0, true);
+ refreshReader(index1, test, 0, true);
fail("Expected exception not thrown.");
} catch (Exception e) {
// expected exception
@@ -999,4 +998,63 @@
indexDir = new File(tempDir, "IndexReaderReopen");
}
+ // LUCENE-1453
+ public void testFSDirectoryReopen() throws CorruptIndexException, IOException {
+ Directory dir1 = FSDirectory.getDirectory(indexDir);
+ createIndex(dir1, false);
+ dir1.close();
+
+ IndexReader ir = IndexReader.open(indexDir);
+ modifyIndex(3, ir.directory());
+ IndexReader newIr = ir.reopen();
+ modifyIndex(3, newIr.directory());
+ IndexReader newIr2 = newIr.reopen();
+ modifyIndex(3, newIr2.directory());
+ IndexReader newIr3 = newIr2.reopen();
+
+ ir.close();
+ newIr.close();
+ newIr2.close();
+
+ // shouldn't throw Directory AlreadyClosedException
+ modifyIndex(3, newIr3.directory());
+ newIr3.close();
+ }
+
+ // LUCENE-1453
+ public void testFSDirectoryReopen2() throws CorruptIndexException, IOException {
+
+ String tempDir = System.getProperty("java.io.tmpdir");
+ if (tempDir == null)
+ throw new IOException("java.io.tmpdir undefined, cannot run test");
+ File indexDir2 = new File(tempDir, "IndexReaderReopen2");
+
+ Directory dir1 = FSDirectory.getDirectory(indexDir2);
+ createIndex(dir1, false);
+
+ IndexReader lastReader = IndexReader.open(indexDir2);
+
+ Random r = new Random(42);
+ for(int i=0;i<10;i++) {
+ int mod = r.nextInt(5);
+ modifyIndex(mod, lastReader.directory());
+ IndexReader reader = lastReader.reopen();
+ if (reader != lastReader) {
+ lastReader.close();
+ lastReader = reader;
+ }
+ }
+ lastReader.close();
+
+ // Make sure we didn't pick up too many incRef's along
+ // the way -- this close should be the final close:
+ dir1.close();
+
+ try {
+ dir1.list();
+ fail("did not hit AlreadyClosedException");
+ } catch (AlreadyClosedException ace) {
+ // expected
+ }
+ }
}