LUCENE-2691: move NRT calls to IR, make package local on IW

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1006280 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Grant Ingersoll 2010-10-10 12:03:01 +00:00
parent 85efafdfa2
commit 82614b3e85
17 changed files with 114 additions and 38 deletions

View File

@ -147,6 +147,9 @@ API Changes
you also override this method on upgrade. (Robert Muir, Mike
McCandless)
* LUCENE-2691: IndexWriter.getReader() has been made package local and is now exposed via open and reopen methods on
IndexReader. The semantics of the call is the same as it was prior to the API change. (Grant Ingersoll, Mike McCandless)
New features
* LUCENE-2604: Added RegexpQuery support to QueryParser. Regular expressions

View File

@ -59,7 +59,7 @@ public class NearRealtimeReaderTask extends PerfTask {
}
long t = System.currentTimeMillis();
IndexReader r = w.getReader();
IndexReader r = IndexReader.open(w);
runData.setIndexReader(r);
// Transfer our reference to runData
r.decRef();

View File

@ -1301,7 +1301,7 @@ public class TestQPHelper extends LuceneTestCase {
Document doc = new Document();
doc.add(newField("field", "", Field.Store.NO, Field.Index.ANALYZED));
w.addDocument(doc);
IndexReader r = w.getReader();
IndexReader r = IndexReader.open(w);
IndexSearcher s = new IndexSearcher(r);
Query q = new StandardQueryParser(new CannedAnalyzer()).parse("\"a\"", "field");

View File

@ -96,7 +96,7 @@ public class TestDistance extends LuceneTestCase {
public void testLatLongFilterOnDeletedDocs() throws Exception {
writer.deleteDocuments(new Term("name", "Potomac"));
IndexReader r = writer.getReader();
IndexReader r = IndexReader.open(writer);
LatLongDistanceFilter f = new LatLongDistanceFilter(new QueryWrapperFilter(new MatchAllDocsQuery()),
lat, lng, 1.0, latField, lngField);

View File

@ -233,6 +233,27 @@ public abstract class IndexReader implements Cloneable,Closeable {
return open(directory, null, null, readOnly, DEFAULT_TERMS_INDEX_DIVISOR, null);
}
/**
* Open a near real time IndexReader from the {@link org.apache.lucene.index.IndexWriter}.
*
*
* @param writer The IndexWriter to open from
* @return The new IndexReader
* @throws CorruptIndexException
* @throws IOException if there is a low-level IO error
*
* @see #reopen(IndexWriter)
*
* @lucene.experimental
*/
public static IndexReader open(final IndexWriter writer) throws CorruptIndexException, IOException {
return writer.getReader();
}
/** Expert: returns an IndexReader reading the index in the given
* {@link IndexCommit}. You should pass readOnly=true, since it
* gives much better concurrent performance, unless you
@ -482,6 +503,70 @@ public abstract class IndexReader implements Cloneable,Closeable {
throw new UnsupportedOperationException("This reader does not support reopen(IndexCommit).");
}
/**
* Expert: returns a readonly reader, covering all
* committed as well as un-committed changes to the index.
* This provides "near real-time" searching, in that
* changes made during an IndexWriter session can be
* quickly made available for searching without closing
* the writer nor calling {@link #commit}.
*
* <p>Note that this is functionally equivalent to calling
* {#flush} (an internal IndexWriter operation) and then using {@link IndexReader#open} to
* open a new reader. But the turnaround time of this
* method should be faster since it avoids the potentially
* costly {@link #commit}.</p>
*
* <p>You must close the {@link IndexReader} returned by
* this method once you are done using it.</p>
*
* <p>It's <i>near</i> real-time because there is no hard
* guarantee on how quickly you can get a new reader after
* making changes with IndexWriter. You'll have to
* experiment in your situation to determine if it's
* fast enough. As this is a new and experimental
* feature, please report back on your findings so we can
* learn, improve and iterate.</p>
*
* <p>The resulting reader supports {@link
* IndexReader#reopen}, but that call will simply forward
* back to this method (though this may change in the
* future).</p>
*
* <p>The very first time this method is called, this
* writer instance will make every effort to pool the
* readers that it opens for doing merges, applying
* deletes, etc. This means additional resources (RAM,
* file descriptors, CPU time) will be consumed.</p>
*
* <p>For lower latency on reopening a reader, you should
* call {@link #setMergedSegmentWarmer} to
* pre-warm a newly merged segment before it's committed
* to the index. This is important for minimizing
* index-to-search delay after a large merge. </p>
*
* <p>If an addIndexes* call is running in another thread,
* then this reader will only search those segments from
* the foreign index that have been successfully copied
* over, so far</p>.
*
* <p><b>NOTE</b>: Once the writer is closed, any
* outstanding readers may continue to be used. However,
* if you attempt to reopen any of those readers, you'll
* hit an {@link AlreadyClosedException}.</p>
*
* @lucene.experimental
*
* @return IndexReader that covers entire index plus all
* changes made so far by this IndexWriter instance
*
* @throws IOException
*/
public IndexReader reopen(IndexWriter writer) throws CorruptIndexException, IOException {
return writer.getReader();
}
/**
* Efficiently clones the IndexReader (sharing most
* internal state).

View File

@ -339,7 +339,7 @@ public class IndexWriter implements Closeable {
* the writer nor calling {@link #commit}.
*
* <p>Note that this is functionally equivalent to calling
* {#commit} and then using {@link IndexReader#open} to
* {#flush} and then using {@link IndexReader#open} to
* open a new reader. But the turnaround time of this
* method should be faster since it avoids the potentially
* costly {@link #commit}.</p>
@ -389,24 +389,7 @@ public class IndexWriter implements Closeable {
*
* @throws IOException
*/
public IndexReader getReader() throws IOException {
return getReader(config.getReaderTermsIndexDivisor());
}
/** Expert: like {@link #getReader}, except you can
* specify which termInfosIndexDivisor should be used for
* any newly opened readers.
* @param termInfosIndexDivisor Subsamples which indexed
* terms are loaded into RAM. This has the same effect as {@link
* IndexWriter#setTermIndexInterval} except that setting
* must be done at indexing time while this setting can be
* set per reader. When set to N, then one in every
* N*termIndexInterval terms in the index is loaded into
* memory. By setting this to a value > 1 you can reduce
* memory usage, at the expense of higher latency when
* loading a TermInfo. The default value is 1. Set this
* to -1 to skip loading the terms index entirely. */
public IndexReader getReader(int termInfosIndexDivisor) throws IOException {
IndexReader getReader() throws IOException {
ensureOpen();
@ -420,18 +403,19 @@ public class IndexWriter implements Closeable {
poolReaders = true;
flush(true, true, false);
// Prevent segmentInfos from changing while opening the
// reader; in theory we could do similar retry logic,
// just like we do when loading segments_N
synchronized(this) {
applyDeletes();
final IndexReader r = new DirectoryReader(this, segmentInfos, termInfosIndexDivisor, codecs);
final IndexReader r = new DirectoryReader(this, segmentInfos, config.getReaderTermsIndexDivisor(), codecs);
if (infoStream != null) {
message("return reader version=" + r.getVersion() + " reader=" + r);
}
return r;
}
}
/** Holds shared SegmentReader instances. IndexWriter uses

View File

@ -634,7 +634,7 @@ public class TestExternalCodecs extends LuceneTestCase {
}
w.deleteDocuments(new Term("id", "77"));
IndexReader r = w.getReader();
IndexReader r = IndexReader.open(w);
IndexReader[] subs = r.getSequentialSubReaders();
assertTrue(subs.length > 1);
// test each segment
@ -654,7 +654,7 @@ public class TestExternalCodecs extends LuceneTestCase {
w.deleteDocuments(new Term("id", "44"));
w.optimize();
r = w.getReader();
r = IndexReader.open(w);
assertEquals(NUM_DOCS-2, r.maxDoc());
assertEquals(NUM_DOCS-2, r.numDocs());
s = new IndexSearcher(r);

View File

@ -73,6 +73,7 @@ import org.apache.lucene.store.MockDirectoryWrapper;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.store.SingleInstanceLockFactory;
import org.apache.lucene.util.UnicodeUtil;
import org.apache.lucene.util.Version;
import org.apache.lucene.util._TestUtil;
import org.apache.lucene.util.ThreadInterruptedException;
import org.apache.lucene.util.BytesRef;
@ -4825,17 +4826,20 @@ public class TestIndexWriter extends LuceneTestCase {
public void testIndexDivisor() throws Exception {
Directory dir = newDirectory();
IndexWriter w = new IndexWriter(dir, new MockAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
IndexWriterConfig config = new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer());
config.setTermIndexInterval(2);
IndexWriter w = new IndexWriter(dir, config);
StringBuilder s = new StringBuilder();
// must be > 256
for(int i=0;i<300;i++) {
s.append(' ').append(""+i);
s.append(' ').append(i);
}
Document d = new Document();
Field f = newField("field", s.toString(), Field.Store.NO, Field.Index.ANALYZED);
d.add(f);
w.addDocument(d);
IndexReader r = w.getReader(2).getSequentialSubReaders()[0];
IndexReader r = w.getReader().getSequentialSubReaders()[0];
TermsEnum t = r.fields().terms("field").iterator();
int count = 0;
while(t.next() != null) {

View File

@ -1151,7 +1151,7 @@ public class TestQueryParser extends LuceneTestCase {
Document doc = new Document();
doc.add(newField("f", "the wizard of ozzy", Field.Store.NO, Field.Index.ANALYZED));
w.addDocument(doc);
IndexReader r = w.getReader();
IndexReader r = IndexReader.open(w);
w.close();
IndexSearcher s = new IndexSearcher(r);
QueryParser qp = new QueryParser(TEST_VERSION_CURRENT, "f", a);

View File

@ -41,7 +41,7 @@ public class TestCachingSpanFilter extends LuceneTestCase {
// flipping a coin) may give us a newly opened reader,
// but we use .reopen on this reader below and expect to
// (must) get an NRT reader:
IndexReader reader = writer.w.getReader();
IndexReader reader = IndexReader.open(writer.w);
IndexSearcher searcher = new IndexSearcher(reader);
// add a doc, refresh the reader, and check that its there

View File

@ -159,7 +159,7 @@ public class TestCachingWrapperFilter extends LuceneTestCase {
// flipping a coin) may give us a newly opened reader,
// but we use .reopen on this reader below and expect to
// (must) get an NRT reader:
IndexReader reader = writer.w.getReader();
IndexReader reader = IndexReader.open(writer.w);
IndexSearcher searcher = new IndexSearcher(reader);
// add a doc, refresh the reader, and check that its there

View File

@ -45,7 +45,7 @@ public class TestElevationComparator extends LuceneTestCase {
writer.addDocument(adoc(new String[] {"id", "y", "title", "boosted boosted", "str_s","y"}));
writer.addDocument(adoc(new String[] {"id", "z", "title", "boosted boosted boosted","str_s", "z"}));
IndexReader r = writer.getReader();
IndexReader r = IndexReader.open(writer);
writer.close();
IndexSearcher searcher = new IndexSearcher(r);

View File

@ -203,7 +203,7 @@ public class TestFieldCache extends LuceneTestCase {
public void testEmptyIndex() throws Exception {
Directory dir = newDirectory();
IndexWriter writer= new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer()).setMaxBufferedDocs(500));
IndexReader r = writer.getReader();
IndexReader r = IndexReader.open(writer);
FieldCache.DocTerms terms = FieldCache.DEFAULT.getTerms(r, "foobar");
FieldCache.DocTermsIndex termsIndex = FieldCache.DEFAULT.getTermsIndex(r, "foobar");
r.close();

View File

@ -1160,7 +1160,7 @@ public class TestSort extends LuceneTestCase implements Serializable {
doc.add(newField("t", "1", Field.Store.NO, Field.Index.NOT_ANALYZED));
w.addDocument(doc);
IndexReader r = w.getReader();
IndexReader r = IndexReader.open(w);
w.close();
IndexSearcher s = new IndexSearcher(r);
TopDocs hits = s.search(new TermQuery(new Term("t", "1")), null, 10, new Sort(new SortField("f", SortField.STRING)));

View File

@ -39,7 +39,7 @@ public class TestValueSource extends LuceneTestCase {
w.commit();
}
IndexReader r = w.getReader();
IndexReader r = IndexReader.open(w);
w.close();
assertTrue(r.getSequentialSubReaders().length > 1);

View File

@ -126,7 +126,7 @@ public class PayloadHelper {
doc.add(new Field(NO_PAYLOAD_FIELD, English.intToEnglish(i), Field.Store.YES, Field.Index.ANALYZED));
writer.addDocument(doc);
}
reader = writer.getReader();
reader = IndexReader.open(writer);
writer.close();
IndexSearcher searcher = new IndexSearcher(SlowMultiReaderWrapper.wrap(reader));

View File

@ -48,7 +48,7 @@ public class TestFileSwitchDirectory extends LuceneTestCase {
((LogMergePolicy) writer.getConfig().getMergePolicy()).setUseCompoundFile(false);
((LogMergePolicy) writer.getConfig().getMergePolicy()).setUseCompoundDocStore(false);
TestIndexWriterReader.createIndexNoClose(true, "ram", writer);
IndexReader reader = writer.getReader();
IndexReader reader = IndexReader.open(writer);
assertEquals(100, reader.maxDoc());
writer.commit();
// we should see only fdx,fdt files here