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 2009/03/11 18:32:38 UTC
svn commit: r752538 - in /lucene/java/trunk: CHANGES.txt
src/java/org/apache/lucene/index/DirectoryIndexReader.java
src/java/org/apache/lucene/index/IndexReader.java
src/test/org/apache/lucene/index/TestIndexReaderReopen.java
Author: mikemccand
Date: Wed Mar 11 17:32:37 2009
New Revision: 752538
URL: http://svn.apache.org/viewvc?rev=752538&view=rev
Log:
LUCENE-1551: add expert IndexReader.reopen(IndexCommit)
Modified:
lucene/java/trunk/CHANGES.txt
lucene/java/trunk/src/java/org/apache/lucene/index/DirectoryIndexReader.java
lucene/java/trunk/src/java/org/apache/lucene/index/IndexReader.java
lucene/java/trunk/src/test/org/apache/lucene/index/TestIndexReaderReopen.java
Modified: lucene/java/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/java/trunk/CHANGES.txt?rev=752538&r1=752537&r2=752538&view=diff
==============================================================================
--- lucene/java/trunk/CHANGES.txt (original)
+++ lucene/java/trunk/CHANGES.txt Wed Mar 11 17:32:37 2009
@@ -173,6 +173,11 @@
15. LUCENE-1398: Add ReverseStringFilter to contrib/analyzers, a filter
to reverse the characters in each token. (Koji Sekiguchi via yonik)
+16. LUCENE-1551: Add expert IndexReader.reopen(IndexCommit) to allow
+ efficiently opening a new reader on a specific commit, sharing
+ resources with the original reader. (Torin Danil via Mike
+ McCandless)
+
Optimizations
1. LUCENE-1427: Fixed QueryWrapperFilter to not waste time computing
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=752538&r1=752537&r2=752538&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 Wed Mar 11 17:32:37 2009
@@ -149,11 +149,15 @@
public final synchronized IndexReader reopen() throws CorruptIndexException, IOException {
// Preserve current readOnly
- return doReopen(readOnly);
+ return doReopen(readOnly, null);
}
public final synchronized IndexReader reopen(boolean openReadOnly) throws CorruptIndexException, IOException {
- return doReopen(openReadOnly);
+ return doReopen(openReadOnly, null);
+ }
+
+ public final synchronized IndexReader reopen(final IndexCommit commit) throws CorruptIndexException, IOException {
+ return doReopen(true, commit);
}
public final synchronized Object clone() {
@@ -194,29 +198,44 @@
// If there are no changes to the index, simply return
// ourself. If there are changes, load the latest
// SegmentInfos and reopen based on that
- protected final synchronized IndexReader doReopen(final boolean openReadOnly) throws CorruptIndexException, IOException {
+ protected final synchronized IndexReader doReopen(final boolean openReadOnly, IndexCommit commit) throws CorruptIndexException, IOException {
ensureOpen();
- if (hasChanges) {
- // We have changes, which means we are not readOnly:
- assert readOnly == false;
- // and we hold the write lock:
- assert writeLock != null;
- // so no other writer holds the write lock, which
- // means no changes could have been done to the index:
- assert isCurrent();
+ assert commit == null || openReadOnly;
- if (openReadOnly) {
- return (IndexReader) clone(openReadOnly);
- } else {
- return this;
+ if (commit == null) {
+ if (hasChanges) {
+ // We have changes, which means we are not readOnly:
+ assert readOnly == false;
+ // and we hold the write lock:
+ assert writeLock != null;
+ // so no other writer holds the write lock, which
+ // means no changes could have been done to the index:
+ assert isCurrent();
+
+ if (openReadOnly) {
+ return (IndexReader) clone(openReadOnly);
+ } else {
+ return this;
+ }
+ } else if (isCurrent()) {
+ if (openReadOnly != readOnly) {
+ // Just fallback to clone
+ return (IndexReader) clone(openReadOnly);
+ } else {
+ return this;
+ }
}
- } else if (isCurrent()) {
- if (openReadOnly != readOnly) {
- // Just fallback to clone
- return (IndexReader) clone(openReadOnly);
- } else {
- return this;
+ } else {
+ if (directory != commit.getDirectory())
+ throw new IOException("the specified commit does not match the specified Directory");
+ if (segmentInfos != null && commit.getSegmentsFileName().equals(segmentInfos.getCurrentSegmentFileName())) {
+ if (readOnly != openReadOnly) {
+ // Just fallback to clone
+ return (IndexReader) clone(openReadOnly);
+ } else {
+ return this;
+ }
}
}
@@ -247,7 +266,11 @@
closeDirectory = false;
try {
- reader = (DirectoryIndexReader) finder.run();
+ if (commit == null) {
+ reader = (DirectoryIndexReader) finder.run();
+ } else {
+ reader = (DirectoryIndexReader) finder.doBody(commit.getSegmentsFileName());
+ }
} finally {
if (myCloseDirectory) {
assert directory instanceof FSDirectory;
Modified: lucene/java/trunk/src/java/org/apache/lucene/index/IndexReader.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/index/IndexReader.java?rev=752538&r1=752537&r2=752538&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/index/IndexReader.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/index/IndexReader.java Wed Mar 11 17:32:37 2009
@@ -369,6 +369,16 @@
throw new UnsupportedOperationException("This reader does not support reopen().");
}
+ /** Expert: reopen this reader on a specific commit point.
+ * This always returns a readOnly reader. If the
+ * specified commit point matches what this reader is
+ * already on, and this reader is already readOnly, then
+ * this same instance is returned; if it is not already
+ * readOnly, a readOnly clone is returned. */
+ public synchronized IndexReader reopen(final IndexCommit commit) throws CorruptIndexException, IOException {
+ throw new UnsupportedOperationException("This reader does not support reopen(IndexCommit).");
+ }
+
/**
* Efficiently clones the IndexReader (sharing most
* internal state).
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=752538&r1=752537&r2=752538&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 Wed Mar 11 17:32:37 2009
@@ -1052,6 +1052,7 @@
}
}
+ /*
private void assertReaderOpen(IndexReader reader) {
reader.ensureOpen();
@@ -1062,6 +1063,7 @@
}
}
}
+ */
private void assertRefCountEquals(int refCount, IndexReader reader) {
assertEquals("Reader has wrong refCount value.", refCount, reader.getRefCount());
@@ -1225,4 +1227,64 @@
r2.close();
dir.close();
}
+
+ private static class KeepAllCommits implements IndexDeletionPolicy {
+ public void onInit(List commits) {
+ }
+ public void onCommit(List commits) {
+ }
+ }
+
+ public void testReopenOnCommit() throws Throwable {
+ Directory dir = new MockRAMDirectory();
+ IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), new KeepAllCommits(), IndexWriter.MaxFieldLength.UNLIMITED);
+ for(int i=0;i<4;i++) {
+ Document doc = new Document();
+ doc.add(new Field("id", ""+i, Field.Store.NO, Field.Index.NOT_ANALYZED));
+ writer.addDocument(doc);
+ writer.commit(""+i);
+ }
+ for(int i=0;i<4;i++) {
+ writer.deleteDocuments(new Term("id", ""+i));
+ writer.commit(""+(4+i));
+ }
+ writer.close();
+
+ IndexReader r = IndexReader.open(dir);
+ assertEquals(0, r.numDocs());
+ assertEquals(4, r.maxDoc());
+
+ Iterator it = IndexReader.listCommits(dir).iterator();
+ while(it.hasNext()) {
+ IndexCommit commit = (IndexCommit) it.next();
+ IndexReader r2 = r.reopen(commit);
+ assertTrue(r2 != r);
+
+ // Reader should be readOnly
+ try {
+ r2.deleteDocument(0);
+ fail("no exception hit");
+ } catch (UnsupportedOperationException uoe) {
+ // expected
+ }
+
+ final String s = commit.getUserData();
+ final int v;
+ if (s == null) {
+ // First commit created by IW
+ v = -1;
+ } else {
+ v = Integer.parseInt(s);
+ }
+ if (v < 4) {
+ assertEquals(1+v, r2.numDocs());
+ } else {
+ assertEquals(7-v, r2.numDocs());
+ }
+ r.close();
+ r = r2;
+ }
+ r.close();
+ dir.close();
+ }
}