mirror of https://github.com/apache/lucene.git
LUCENE-6377: Pass previous reader to SearcherFactory#newSearcher
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1670649 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d3b81fc812
commit
58202b255a
|
@ -53,6 +53,11 @@ Bug Fixes
|
||||||
* LUCENE-6378: Fix all RuntimeExceptions to throw the underlying root cause.
|
* LUCENE-6378: Fix all RuntimeExceptions to throw the underlying root cause.
|
||||||
(Varun Thacker, Adrien Grand, Mike McCandless)
|
(Varun Thacker, Adrien Grand, Mike McCandless)
|
||||||
|
|
||||||
|
API Changes
|
||||||
|
|
||||||
|
* LUCENE-6377: SearcherFactory#newSearcher now accepts the previous reader
|
||||||
|
to simplify warming logic during opening new searchers. (Simon Willnauer)
|
||||||
|
|
||||||
======================= Lucene 5.1.0 =======================
|
======================= Lucene 5.1.0 =======================
|
||||||
|
|
||||||
New Features
|
New Features
|
||||||
|
|
|
@ -50,8 +50,14 @@ import org.apache.lucene.search.similarities.Similarity; // javadocs
|
||||||
public class SearcherFactory {
|
public class SearcherFactory {
|
||||||
/**
|
/**
|
||||||
* Returns a new IndexSearcher over the given reader.
|
* Returns a new IndexSearcher over the given reader.
|
||||||
|
* @param reader the reader to create a new searcher for
|
||||||
|
* @param previousReader the reader previously used to create a new searcher.
|
||||||
|
* This can be <code>null</code> if unknown or if the given reader is the initially opened reader.
|
||||||
|
* If this reader is non-null it can be used to find newly opened segments compared to the new reader to warm
|
||||||
|
* the searcher up before returning.
|
||||||
*/
|
*/
|
||||||
public IndexSearcher newSearcher(IndexReader reader) throws IOException {
|
public IndexSearcher newSearcher(IndexReader reader, IndexReader previousReader) throws IOException {
|
||||||
return new IndexSearcher(reader);
|
return new IndexSearcher(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ public final class SearcherManager extends ReferenceManager<IndexSearcher> {
|
||||||
searcherFactory = new SearcherFactory();
|
searcherFactory = new SearcherFactory();
|
||||||
}
|
}
|
||||||
this.searcherFactory = searcherFactory;
|
this.searcherFactory = searcherFactory;
|
||||||
current = getSearcher(searcherFactory, DirectoryReader.open(writer, applyAllDeletes));
|
current = getSearcher(searcherFactory, DirectoryReader.open(writer, applyAllDeletes), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,7 +103,7 @@ public final class SearcherManager extends ReferenceManager<IndexSearcher> {
|
||||||
searcherFactory = new SearcherFactory();
|
searcherFactory = new SearcherFactory();
|
||||||
}
|
}
|
||||||
this.searcherFactory = searcherFactory;
|
this.searcherFactory = searcherFactory;
|
||||||
current = getSearcher(searcherFactory, DirectoryReader.open(dir));
|
current = getSearcher(searcherFactory, DirectoryReader.open(dir), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,7 +122,7 @@ public final class SearcherManager extends ReferenceManager<IndexSearcher> {
|
||||||
searcherFactory = new SearcherFactory();
|
searcherFactory = new SearcherFactory();
|
||||||
}
|
}
|
||||||
this.searcherFactory = searcherFactory;
|
this.searcherFactory = searcherFactory;
|
||||||
this.current = getSearcher(searcherFactory, reader);
|
this.current = getSearcher(searcherFactory, reader, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -138,7 +138,7 @@ public final class SearcherManager extends ReferenceManager<IndexSearcher> {
|
||||||
if (newReader == null) {
|
if (newReader == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return getSearcher(searcherFactory, newReader);
|
return getSearcher(searcherFactory, newReader, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,11 +172,11 @@ public final class SearcherManager extends ReferenceManager<IndexSearcher> {
|
||||||
* IndexReader} using the provided {@link
|
* IndexReader} using the provided {@link
|
||||||
* SearcherFactory}. NOTE: this decRefs incoming reader
|
* SearcherFactory}. NOTE: this decRefs incoming reader
|
||||||
* on throwing an exception. */
|
* on throwing an exception. */
|
||||||
public static IndexSearcher getSearcher(SearcherFactory searcherFactory, IndexReader reader) throws IOException {
|
public static IndexSearcher getSearcher(SearcherFactory searcherFactory, IndexReader reader, IndexReader previousReader) throws IOException {
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
final IndexSearcher searcher;
|
final IndexSearcher searcher;
|
||||||
try {
|
try {
|
||||||
searcher = searcherFactory.newSearcher(reader);
|
searcher = searcherFactory.newSearcher(reader, previousReader);
|
||||||
if (searcher.getIndexReader() != reader) {
|
if (searcher.getIndexReader() != reader) {
|
||||||
throw new IllegalStateException("SearcherFactory must wrap exactly the provided reader (got " + searcher.getIndexReader() + " but expected " + reader + ")");
|
throw new IllegalStateException("SearcherFactory must wrap exactly the provided reader (got " + searcher.getIndexReader() + " but expected " + reader + ")");
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,7 +219,7 @@ public class TestControlledRealTimeReopenThread extends ThreadedIndexingAndSearc
|
||||||
|
|
||||||
final SearcherFactory sf = new SearcherFactory() {
|
final SearcherFactory sf = new SearcherFactory() {
|
||||||
@Override
|
@Override
|
||||||
public IndexSearcher newSearcher(IndexReader r) throws IOException {
|
public IndexSearcher newSearcher(IndexReader r, IndexReader previous) throws IOException {
|
||||||
TestControlledRealTimeReopenThread.this.warmCalled = true;
|
TestControlledRealTimeReopenThread.this.warmCalled = true;
|
||||||
IndexSearcher s = new IndexSearcher(r, es);
|
IndexSearcher s = new IndexSearcher(r, es);
|
||||||
s.search(new TermQuery(new Term("body", "united")), 10);
|
s.search(new TermQuery(new Term("body", "united")), 10);
|
||||||
|
@ -413,7 +413,7 @@ public class TestControlledRealTimeReopenThread extends ThreadedIndexingAndSearc
|
||||||
|
|
||||||
final SearcherFactory theEvilOne = new SearcherFactory() {
|
final SearcherFactory theEvilOne = new SearcherFactory() {
|
||||||
@Override
|
@Override
|
||||||
public IndexSearcher newSearcher(IndexReader ignored) {
|
public IndexSearcher newSearcher(IndexReader ignored, IndexReader previous) {
|
||||||
return LuceneTestCase.newSearcher(other);
|
return LuceneTestCase.newSearcher(other);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -83,7 +83,7 @@ public class TestLRUQueryCache extends LuceneTestCase {
|
||||||
final RandomIndexWriter w = new RandomIndexWriter(random(), dir);
|
final RandomIndexWriter w = new RandomIndexWriter(random(), dir);
|
||||||
final SearcherFactory searcherFactory = new SearcherFactory() {
|
final SearcherFactory searcherFactory = new SearcherFactory() {
|
||||||
@Override
|
@Override
|
||||||
public IndexSearcher newSearcher(IndexReader reader) throws IOException {
|
public IndexSearcher newSearcher(IndexReader reader, IndexReader previous) throws IOException {
|
||||||
IndexSearcher searcher = new IndexSearcher(reader);
|
IndexSearcher searcher = new IndexSearcher(reader);
|
||||||
searcher.setQueryCachingPolicy(MAYBE_CACHE_POLICY);
|
searcher.setQueryCachingPolicy(MAYBE_CACHE_POLICY);
|
||||||
searcher.setQueryCache(queryCache);
|
searcher.setQueryCache(queryCache);
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class TestLiveFieldValues extends LuceneTestCase {
|
||||||
|
|
||||||
final SearcherManager mgr = new SearcherManager(w, true, new SearcherFactory() {
|
final SearcherManager mgr = new SearcherManager(w, true, new SearcherFactory() {
|
||||||
@Override
|
@Override
|
||||||
public IndexSearcher newSearcher(IndexReader r) {
|
public IndexSearcher newSearcher(IndexReader r, IndexReader previous) {
|
||||||
return new IndexSearcher(r);
|
return new IndexSearcher(r);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -78,7 +78,7 @@ public class TestSearcherManager extends ThreadedIndexingAndSearchingTestCase {
|
||||||
protected void doAfterWriter(final ExecutorService es) throws Exception {
|
protected void doAfterWriter(final ExecutorService es) throws Exception {
|
||||||
final SearcherFactory factory = new SearcherFactory() {
|
final SearcherFactory factory = new SearcherFactory() {
|
||||||
@Override
|
@Override
|
||||||
public IndexSearcher newSearcher(IndexReader r) throws IOException {
|
public IndexSearcher newSearcher(IndexReader r, IndexReader previous) throws IOException {
|
||||||
IndexSearcher s = new IndexSearcher(r, es);
|
IndexSearcher s = new IndexSearcher(r, es);
|
||||||
TestSearcherManager.this.warmCalled = true;
|
TestSearcherManager.this.warmCalled = true;
|
||||||
s.search(new TermQuery(new Term("body", "united")), 10);
|
s.search(new TermQuery(new Term("body", "united")), 10);
|
||||||
|
@ -217,7 +217,7 @@ public class TestSearcherManager extends ThreadedIndexingAndSearchingTestCase {
|
||||||
final ExecutorService es = random().nextBoolean() ? null : Executors.newCachedThreadPool(new NamedThreadFactory("testIntermediateClose"));
|
final ExecutorService es = random().nextBoolean() ? null : Executors.newCachedThreadPool(new NamedThreadFactory("testIntermediateClose"));
|
||||||
final SearcherFactory factory = new SearcherFactory() {
|
final SearcherFactory factory = new SearcherFactory() {
|
||||||
@Override
|
@Override
|
||||||
public IndexSearcher newSearcher(IndexReader r) {
|
public IndexSearcher newSearcher(IndexReader r, IndexReader previous) {
|
||||||
try {
|
try {
|
||||||
if (triedReopen.get()) {
|
if (triedReopen.get()) {
|
||||||
awaitEnterWarm.countDown();
|
awaitEnterWarm.countDown();
|
||||||
|
@ -400,7 +400,7 @@ public class TestSearcherManager extends ThreadedIndexingAndSearchingTestCase {
|
||||||
|
|
||||||
final SearcherFactory theEvilOne = new SearcherFactory() {
|
final SearcherFactory theEvilOne = new SearcherFactory() {
|
||||||
@Override
|
@Override
|
||||||
public IndexSearcher newSearcher(IndexReader ignored) {
|
public IndexSearcher newSearcher(IndexReader ignored, IndexReader previous) {
|
||||||
return LuceneTestCase.newSearcher(other);
|
return LuceneTestCase.newSearcher(other);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -503,4 +503,47 @@ public class TestSearcherManager extends ThreadedIndexingAndSearchingTestCase {
|
||||||
w.close();
|
w.close();
|
||||||
dir.close();
|
dir.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testPreviousReaderIsPassed() throws IOException {
|
||||||
|
final Directory dir = newDirectory();
|
||||||
|
final IndexWriter w = new IndexWriter(dir, newIndexWriterConfig());
|
||||||
|
w.addDocument(new Document());
|
||||||
|
class MySearcherFactory extends SearcherFactory {
|
||||||
|
IndexReader lastReader = null;
|
||||||
|
IndexReader lastPreviousReader = null;
|
||||||
|
int called = 0;
|
||||||
|
@Override
|
||||||
|
public IndexSearcher newSearcher(IndexReader reader, IndexReader previousReader) throws IOException {
|
||||||
|
called++;
|
||||||
|
lastReader = reader;
|
||||||
|
lastPreviousReader = previousReader;
|
||||||
|
return super.newSearcher(reader, previousReader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MySearcherFactory factory = new MySearcherFactory();
|
||||||
|
final SearcherManager sm = new SearcherManager(w, random().nextBoolean(), factory);
|
||||||
|
assertEquals(1, factory.called);
|
||||||
|
assertNull(factory.lastPreviousReader);
|
||||||
|
assertNotNull(factory.lastReader);
|
||||||
|
IndexSearcher acquire = sm.acquire();
|
||||||
|
assertSame(factory.lastReader, acquire.getIndexReader());
|
||||||
|
sm.release(acquire);
|
||||||
|
|
||||||
|
final IndexReader lastReader = factory.lastReader;
|
||||||
|
// refresh
|
||||||
|
w.addDocument(new Document());
|
||||||
|
assertTrue(sm.maybeRefresh());
|
||||||
|
|
||||||
|
acquire = sm.acquire();
|
||||||
|
assertSame(factory.lastReader, acquire.getIndexReader());
|
||||||
|
sm.release(acquire);
|
||||||
|
assertNotNull(factory.lastPreviousReader);
|
||||||
|
assertSame(lastReader, factory.lastPreviousReader);
|
||||||
|
assertNotSame(factory.lastReader, lastReader);
|
||||||
|
assertEquals(2, factory.called);
|
||||||
|
w.close();
|
||||||
|
sm.close();
|
||||||
|
dir.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class SearcherTaxonomyManager extends ReferenceManager<SearcherTaxonomyMa
|
||||||
this.searcherFactory = searcherFactory;
|
this.searcherFactory = searcherFactory;
|
||||||
this.taxoWriter = taxoWriter;
|
this.taxoWriter = taxoWriter;
|
||||||
DirectoryTaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoWriter);
|
DirectoryTaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoWriter);
|
||||||
current = new SearcherAndTaxonomy(SearcherManager.getSearcher(searcherFactory, DirectoryReader.open(writer, applyAllDeletes)), taxoReader);
|
current = new SearcherAndTaxonomy(SearcherManager.getSearcher(searcherFactory, DirectoryReader.open(writer, applyAllDeletes), null), taxoReader);
|
||||||
this.taxoEpoch = taxoWriter.getTaxonomyEpoch();
|
this.taxoEpoch = taxoWriter.getTaxonomyEpoch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ public class SearcherTaxonomyManager extends ReferenceManager<SearcherTaxonomyMa
|
||||||
}
|
}
|
||||||
this.searcherFactory = searcherFactory;
|
this.searcherFactory = searcherFactory;
|
||||||
DirectoryTaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
|
DirectoryTaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
|
||||||
current = new SearcherAndTaxonomy(SearcherManager.getSearcher(searcherFactory, DirectoryReader.open(indexDir)), taxoReader);
|
current = new SearcherAndTaxonomy(SearcherManager.getSearcher(searcherFactory, DirectoryReader.open(indexDir), null), taxoReader);
|
||||||
this.taxoWriter = null;
|
this.taxoWriter = null;
|
||||||
taxoEpoch = -1;
|
taxoEpoch = -1;
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ public class SearcherTaxonomyManager extends ReferenceManager<SearcherTaxonomyMa
|
||||||
throw new IllegalStateException("DirectoryTaxonomyWriter.replaceTaxonomy was called, which is not allowed when using SearcherTaxonomyManager");
|
throw new IllegalStateException("DirectoryTaxonomyWriter.replaceTaxonomy was called, which is not allowed when using SearcherTaxonomyManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SearcherAndTaxonomy(SearcherManager.getSearcher(searcherFactory, newReader), tr);
|
return new SearcherAndTaxonomy(SearcherManager.getSearcher(searcherFactory, newReader, r), tr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue