diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 92fa303281c..203864350d1 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -74,6 +74,9 @@ API Changes
IndexOutput.getName returns its name (Dawid Weiss, Robert Muir, Mike
McCandless)
+* LUCENE-6855: CachingWrapperQuery is deprecated and will be removed in 6.0.
+ (Adrien Grand)
+
Changes in Runtime Behavior
* LUCENE-6789: IndexSearcher's default Similarity is changed to BM25Similarity.
diff --git a/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java b/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
index 524fc383fa1..48705321b72 100644
--- a/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
@@ -21,7 +21,7 @@ import java.io.IOException;
import java.util.Iterator;
import java.util.Objects;
-import org.apache.lucene.search.CachingWrapperQuery;
+import org.apache.lucene.search.QueryCache;
import org.apache.lucene.util.AttributeSource;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
@@ -39,7 +39,7 @@ import org.apache.lucene.util.BytesRef;
*
NOTE : If this {@link FilterLeafReader} does not change the
* content the contained reader, you could consider overriding
* {@link #getCoreCacheKey()} so that
- * {@link CachingWrapperQuery} shares the same entries for this atomic reader
+ * {@link QueryCache} impls share the same entries for this atomic reader
* and the wrapped one. {@link #getCombinedCoreAndDeletesKey()} could be
* overridden as well if the {@link #getLiveDocs() live docs} are not changed
* either.
diff --git a/lucene/core/src/java/org/apache/lucene/search/CachingWrapperQuery.java b/lucene/core/src/java/org/apache/lucene/search/CachingWrapperQuery.java
deleted file mode 100644
index 4dfe1cead6d..00000000000
--- a/lucene/core/src/java/org/apache/lucene/search/CachingWrapperQuery.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package org.apache.lucene.search;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.LeafReader;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.util.Accountable;
-import org.apache.lucene.util.Accountables;
-import org.apache.lucene.util.RoaringDocIdSet;
-
-/**
- * Wraps another {@link Query}'s result and caches it when scores are not
- * needed. The purpose is to allow queries to simply care about matching and
- * scoring, and then wrap with this class to add caching.
- */
-public class CachingWrapperQuery extends Query implements Accountable, Cloneable {
- private Query query; // not final because of clone
- private final QueryCachingPolicy policy;
- private final Map cache = Collections.synchronizedMap(new WeakHashMap());
-
- /** Wraps another query's result and caches it according to the provided policy.
- * @param query Query to cache results of
- * @param policy policy defining which filters should be cached on which segments
- */
- public CachingWrapperQuery(Query query, QueryCachingPolicy policy) {
- this.query = Objects.requireNonNull(query, "Query must not be null");
- this.policy = Objects.requireNonNull(policy, "QueryCachingPolicy must not be null");
- }
-
- /** Same as {@link CachingWrapperQuery#CachingWrapperQuery(Query, QueryCachingPolicy)}
- * but enforces the use of the
- * {@link QueryCachingPolicy.CacheOnLargeSegments#DEFAULT} policy. */
- public CachingWrapperQuery(Query query) {
- this(query, QueryCachingPolicy.CacheOnLargeSegments.DEFAULT);
- }
-
- /**
- * Gets the contained query.
- * @return the contained query.
- */
- public Query getQuery() {
- return query;
- }
-
- /**
- * Default cache implementation: uses {@link RoaringDocIdSet}.
- */
- protected DocIdSet cacheImpl(DocIdSetIterator iterator, LeafReader reader) throws IOException {
- return new RoaringDocIdSet.Builder(reader.maxDoc()).add(iterator).build();
- }
-
- @Override
- public Query rewrite(IndexReader reader) throws IOException {
- final Query rewritten = query.rewrite(reader);
- if (query == rewritten) {
- return super.rewrite(reader);
- } else {
- CachingWrapperQuery clone;
- try {
- clone = (CachingWrapperQuery) clone();
- clone.query = rewritten;
- return clone;
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e);
- }
- }
- }
-
- // for testing
- int hitCount, missCount;
-
- @Override
- public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
- final Weight weight = query.createWeight(searcher, needsScores);
- if (needsScores) {
- // our cache is not sufficient, we need scores too
- return weight;
- }
-
- return new ConstantScoreWeight(weight.getQuery()) {
-
- final AtomicBoolean used = new AtomicBoolean(false);
-
- @Override
- public void extractTerms(Set terms) {
- weight.extractTerms(terms);
- }
-
- @Override
- public Scorer scorer(LeafReaderContext context) throws IOException {
- if (used.compareAndSet(false, true)) {
- policy.onUse(getQuery());
- }
-
- final LeafReader reader = context.reader();
- final Object key = reader.getCoreCacheKey();
-
- DocIdSet docIdSet = cache.get(key);
- if (docIdSet != null) {
- hitCount++;
- } else if (policy.shouldCache(query, context)) {
- missCount++;
- final Scorer scorer = weight.scorer(context);
- if (scorer == null) {
- docIdSet = DocIdSet.EMPTY;
- } else {
- docIdSet = cacheImpl(scorer, context.reader());
- }
- cache.put(key, docIdSet);
- } else {
- return weight.scorer(context);
- }
-
- assert docIdSet != null;
- if (docIdSet == DocIdSet.EMPTY) {
- return null;
- }
- final DocIdSetIterator disi = docIdSet.iterator();
- if (disi == null) {
- return null;
- }
-
- return new ConstantScoreScorer(this, 0f, disi);
- }
- };
- }
-
- @Override
- public String toString(String field) {
- return getClass().getSimpleName() + "("+query.toString(field)+")";
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == null || !getClass().equals(o.getClass())) return false;
- final CachingWrapperQuery other = (CachingWrapperQuery) o;
- return this.query.equals(other.query);
- }
-
- @Override
- public int hashCode() {
- return (query.hashCode() ^ getClass().hashCode());
- }
-
- @Override
- public long ramBytesUsed() {
-
- // Sync only to pull the current set of values:
- List docIdSets;
- synchronized(cache) {
- docIdSets = new ArrayList<>(cache.values());
- }
-
- long total = 0;
- for(DocIdSet dis : docIdSets) {
- total += dis.ramBytesUsed();
- }
-
- return total;
- }
-
- @Override
- public Collection getChildResources() {
- // Sync to pull the current set of values:
- synchronized (cache) {
- // no need to clone, Accountable#namedAccountables already copies the data
- return Accountables.namedAccountables("segment", cache);
- }
- }
-}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestCachingWrapperQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestCachingWrapperQuery.java
deleted file mode 100644
index 1431cc084e0..00000000000
--- a/lucene/core/src/test/org/apache/lucene/search/TestCachingWrapperQuery.java
+++ /dev/null
@@ -1,338 +0,0 @@
-package org.apache.lucene.search;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.IOException;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.lucene.analysis.MockAnalyzer;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.StringField;
-import org.apache.lucene.index.DirectoryReader;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.RandomIndexWriter;
-import org.apache.lucene.index.SerialMergeScheduler;
-import org.apache.lucene.index.SlowCompositeReaderWrapper;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.util.IOUtils;
-import org.apache.lucene.util.LuceneTestCase;
-
-public class TestCachingWrapperQuery extends LuceneTestCase {
- Directory dir;
- DirectoryReader ir;
- IndexSearcher is;
- RandomIndexWriter iw;
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
- dir = newDirectory();
- iw = new RandomIndexWriter(random(), dir);
- Document doc = new Document();
- Field idField = new StringField("id", "", Field.Store.NO);
- doc.add(idField);
- // add 500 docs with id 0..499
- for (int i = 0; i < 500; i++) {
- idField.setStringValue(Integer.toString(i));
- iw.addDocument(doc);
- }
- // delete 20 of them
- for (int i = 0; i < 20; i++) {
- iw.deleteDocuments(new Term("id", Integer.toString(random().nextInt(iw.maxDoc()))));
- }
- ir = iw.getReader();
- is = newSearcher(ir);
- }
-
- @Override
- public void tearDown() throws Exception {
- iw.close();
- IOUtils.close(ir, dir);
- super.tearDown();
- }
-
- private void assertQueryEquals(Query f1, Query f2) throws Exception {
- // wrap into CSQ so that scores are not needed
- TopDocs hits1 = is.search(new ConstantScoreQuery(f1), ir.maxDoc());
- TopDocs hits2 = is.search(new ConstantScoreQuery(f2), ir.maxDoc());
- assertEquals(hits1.totalHits, hits2.totalHits);
- CheckHits.checkEqual(f1, hits1.scoreDocs, hits2.scoreDocs);
- // now do it again to confirm caching works
- TopDocs hits3 = is.search(new ConstantScoreQuery(f1), ir.maxDoc());
- TopDocs hits4 = is.search(new ConstantScoreQuery(f2), ir.maxDoc());
- assertEquals(hits3.totalHits, hits4.totalHits);
- CheckHits.checkEqual(f1, hits3.scoreDocs, hits4.scoreDocs);
- }
-
- /** test null iterator */
- public void testEmpty() throws Exception {
- BooleanQuery.Builder expected = new BooleanQuery.Builder();
- Query cached = new CachingWrapperQuery(expected.build(), MAYBE_CACHE_POLICY);
- assertQueryEquals(expected.build(), cached);
- }
-
- /** test iterator returns NO_MORE_DOCS */
- public void testEmpty2() throws Exception {
- BooleanQuery.Builder expected = new BooleanQuery.Builder();
- expected.add(new TermQuery(new Term("id", "0")), BooleanClause.Occur.MUST);
- expected.add(new TermQuery(new Term("id", "0")), BooleanClause.Occur.MUST_NOT);
- Query cached = new CachingWrapperQuery(expected.build(), MAYBE_CACHE_POLICY);
- assertQueryEquals(expected.build(), cached);
- }
-
- /** test iterator returns single document */
- public void testSingle() throws Exception {
- for (int i = 0; i < 10; i++) {
- int id = random().nextInt(ir.maxDoc());
- Query expected = new TermQuery(new Term("id", Integer.toString(id)));
- Query cached = new CachingWrapperQuery(expected, MAYBE_CACHE_POLICY);
- assertQueryEquals(expected, cached);
- }
- }
-
- /** test sparse filters (match single documents) */
- public void testSparse() throws Exception {
- for (int i = 0; i < 10; i++) {
- int id_start = random().nextInt(ir.maxDoc()-1);
- int id_end = id_start + 1;
- Query expected = TermRangeQuery.newStringRange("id",
- Integer.toString(id_start), Integer.toString(id_end), true, true);
- Query cached = new CachingWrapperQuery(expected, MAYBE_CACHE_POLICY);
- assertQueryEquals(expected, cached);
- }
- }
-
- /** test dense filters (match entire index) */
- public void testDense() throws Exception {
- Query expected = new MatchAllDocsQuery();
- Query cached = new CachingWrapperQuery(expected, MAYBE_CACHE_POLICY);
- assertQueryEquals(expected, cached);
- }
-
- private static class MockQuery extends Query {
-
- private final AtomicBoolean wasCalled = new AtomicBoolean();
-
- public boolean wasCalled() {
- return wasCalled.get();
- }
-
- public void clear() {
- wasCalled.set(false);
- }
-
- @Override
- public String toString(String field) {
- return "Mock";
- }
-
- @Override
- public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
- return new ConstantScoreWeight(this) {
- @Override
- public Scorer scorer(LeafReaderContext context) throws IOException {
- wasCalled.set(true);
- return new ConstantScoreScorer(this, score(), DocIdSetIterator.all(context.reader().maxDoc()));
- }
- };
- }
- }
-
- public void testCachingWorks() throws Exception {
- Directory dir = newDirectory();
- RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
- writer.close();
-
- IndexReader reader = SlowCompositeReaderWrapper.wrap(DirectoryReader.open(dir));
- IndexSearcher searcher = newSearcher(reader);
- LeafReaderContext context = (LeafReaderContext) reader.getContext();
- MockQuery filter = new MockQuery();
- CachingWrapperQuery cacher = new CachingWrapperQuery(filter, QueryCachingPolicy.ALWAYS_CACHE);
-
- // first time, nested filter is called
- cacher.createWeight(searcher, false).scorer(context);
- assertTrue("first time", filter.wasCalled());
-
- // make sure no exception if cache is holding the wrong docIdSet
- cacher.createWeight(searcher, false).scorer(context);
-
- // second time, nested filter should not be called
- filter.clear();
- cacher.createWeight(searcher, false).scorer(context);
- assertFalse("second time", filter.wasCalled());
-
- reader.close();
- dir.close();
- }
-
- public void testEnforceDeletions() throws Exception {
- Directory dir = newDirectory();
- RandomIndexWriter writer = new RandomIndexWriter(
- random(),
- dir,
- newIndexWriterConfig(new MockAnalyzer(random())).
- setMergeScheduler(new SerialMergeScheduler()).
- // asserts below requires no unexpected merges:
- setMergePolicy(newLogMergePolicy(10))
- );
-
- // NOTE: cannot use writer.getReader because RIW (on
- // 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:
- DirectoryReader reader = DirectoryReader.open(writer.w, true);
- // same reason we don't wrap?
- IndexSearcher searcher = newSearcher(reader, false);
-
- // add a doc, refresh the reader, and check that it's there
- Document doc = new Document();
- doc.add(newStringField("id", "1", Field.Store.YES));
- writer.addDocument(doc);
-
- reader = refreshReader(reader);
- searcher = newSearcher(reader, false);
-
- TopDocs docs = searcher.search(new MatchAllDocsQuery(), 1);
- assertEquals("Should find a hit...", 1, docs.totalHits);
-
- final Query startQuery = new TermQuery(new Term("id", "1"));
-
- CachingWrapperQuery query = new CachingWrapperQuery(startQuery, QueryCachingPolicy.ALWAYS_CACHE);
-
- docs = searcher.search(new ConstantScoreQuery(query), 1);
- assertTrue(query.ramBytesUsed() > 0);
-
- assertEquals("[query + filter] Should find a hit...", 1, docs.totalHits);
-
- Query constantScore = new ConstantScoreQuery(query);
- docs = searcher.search(constantScore, 1);
- assertEquals("[just filter] Should find a hit...", 1, docs.totalHits);
-
- // make sure we get a cache hit when we reopen reader
- // that had no change to deletions
-
- // fake delete (deletes nothing):
- writer.deleteDocuments(new Term("foo", "bar"));
-
- IndexReader oldReader = reader;
- reader = refreshReader(reader);
- assertTrue(reader == oldReader);
- int missCount = query.missCount;
- docs = searcher.search(constantScore, 1);
- assertEquals("[just filter] Should find a hit...", 1, docs.totalHits);
-
- // cache hit:
- assertEquals(missCount, query.missCount);
-
- // now delete the doc, refresh the reader, and see that it's not there
- writer.deleteDocuments(new Term("id", "1"));
-
- // NOTE: important to hold ref here so GC doesn't clear
- // the cache entry! Else the assert below may sometimes
- // fail:
- oldReader = reader;
- reader = refreshReader(reader);
-
- searcher = newSearcher(reader, false);
-
- missCount = query.missCount;
- docs = searcher.search(new ConstantScoreQuery(query), 1);
- assertEquals("[query + filter] Should *not* find a hit...", 0, docs.totalHits);
-
- // cache hit
- assertEquals(missCount, query.missCount);
- docs = searcher.search(constantScore, 1);
- assertEquals("[just filter] Should *not* find a hit...", 0, docs.totalHits);
-
- // apply deletes dynamically:
- query = new CachingWrapperQuery(startQuery, QueryCachingPolicy.ALWAYS_CACHE);
- writer.addDocument(doc);
- reader = refreshReader(reader);
- searcher = newSearcher(reader, false);
-
- docs = searcher.search(new ConstantScoreQuery(query), 1);
- assertEquals("[query + filter] Should find a hit...", 1, docs.totalHits);
- missCount = query.missCount;
- assertTrue(missCount > 0);
- constantScore = new ConstantScoreQuery(query);
- docs = searcher.search(constantScore, 1);
- assertEquals("[just filter] Should find a hit...", 1, docs.totalHits);
- assertEquals(missCount, query.missCount);
-
- writer.addDocument(doc);
-
- // NOTE: important to hold ref here so GC doesn't clear
- // the cache entry! Else the assert below may sometimes
- // fail:
- oldReader = reader;
-
- reader = refreshReader(reader);
- searcher = newSearcher(reader, false);
-
- docs = searcher.search(new ConstantScoreQuery(query), 1);
- assertEquals("[query + filter] Should find 2 hits...", 2, docs.totalHits);
- assertTrue(query.missCount > missCount);
- missCount = query.missCount;
-
- constantScore = new ConstantScoreQuery(query);
- docs = searcher.search(constantScore, 1);
- assertEquals("[just filter] Should find a hit...", 2, docs.totalHits);
- assertEquals(missCount, query.missCount);
-
- // now delete the doc, refresh the reader, and see that it's not there
- writer.deleteDocuments(new Term("id", "1"));
-
- reader = refreshReader(reader);
- searcher = newSearcher(reader, false);
-
- docs = searcher.search(new ConstantScoreQuery(query), 1);
- assertEquals("[query + filter] Should *not* find a hit...", 0, docs.totalHits);
- // CWF reused the same entry (it dynamically applied the deletes):
- assertEquals(missCount, query.missCount);
-
- docs = searcher.search(constantScore, 1);
- assertEquals("[just filter] Should *not* find a hit...", 0, docs.totalHits);
- // CWF reused the same entry (it dynamically applied the deletes):
- assertEquals(missCount, query.missCount);
-
- // NOTE: silliness to make sure JRE does not eliminate
- // our holding onto oldReader to prevent
- // CachingWrapperFilter's WeakHashMap from dropping the
- // entry:
- assertTrue(oldReader != null);
-
- reader.close();
- writer.close();
- dir.close();
- }
-
- private static DirectoryReader refreshReader(DirectoryReader reader) throws IOException {
- DirectoryReader oldReader = reader;
- reader = DirectoryReader.openIfChanged(reader);
- if (reader != null) {
- oldReader.close();
- return reader;
- } else {
- return oldReader;
- }
- }
-
-}
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java
index d6f6848352b..ae48f5dd1e9 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java
@@ -37,8 +37,6 @@ public class CoreParser implements QueryBuilder {
protected Analyzer analyzer;
protected QueryParser parser;
protected QueryBuilderFactory queryFactory;
- //Controls the max size of the LRU cache used for QueryFilter objects parsed.
- public static int maxNumCachedQueries = 20;
/**
@@ -78,7 +76,6 @@ public class CoreParser implements QueryBuilder {
queryFactory.addBuilder("UserQuery", new UserInputQueryBuilder(defaultField, analyzer));
}
queryFactory.addBuilder("ConstantScoreQuery", new ConstantScoreQueryBuilder(queryFactory));
- queryFactory.addBuilder("CachedQuery", new CachedQueryBuilder(queryFactory, maxNumCachedQueries));
SpanQueryBuilderFactory sqof = new SpanQueryBuilderFactory();
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/builders/CachedQueryBuilder.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/builders/CachedQueryBuilder.java
deleted file mode 100644
index 817c5755f7f..00000000000
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/builders/CachedQueryBuilder.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Created on 25-Jan-2006
- */
-package org.apache.lucene.queryparser.xml.builders;
-
-import java.util.Map;
-
-import org.apache.lucene.queryparser.xml.DOMUtils;
-import org.apache.lucene.queryparser.xml.ParserException;
-import org.apache.lucene.queryparser.xml.QueryBuilder;
-import org.apache.lucene.queryparser.xml.QueryBuilderFactory;
-import org.apache.lucene.search.CachingWrapperQuery;
-import org.apache.lucene.search.Query;
-import org.w3c.dom.Element;
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Filters are cached in an LRU Cache keyed on the contained query or filter object. Using this will
- * speed up overall performance for repeated uses of the same expensive query/filter. The sorts of
- * queries/filters likely to benefit from caching need not necessarily be complex - e.g. simple
- * TermQuerys with a large DF (document frequency) can be expensive on large indexes.
- * A good example of this might be a term query on a field with only 2 possible values -
- * "true" or "false". In a large index, querying or filtering on this field requires reading
- * millions of document ids from disk which can more usefully be cached as a filter bitset.
- *
- * For Queries/Filters to be cached and reused the object must implement hashcode and
- * equals methods correctly so that duplicate queries/filters can be detected in the cache.
- *
- * The CoreParser.maxNumCachedFilters property can be used to control the size of the LRU
- * Cache established during the construction of CoreParser instances.
- */
-public class CachedQueryBuilder implements QueryBuilder {
-
- private final QueryBuilderFactory queryFactory;
-
- private LRUCache queryCache;
-
- private final int cacheSize;
-
- public CachedQueryBuilder(QueryBuilderFactory queryFactory,
- int cacheSize) {
- this.queryFactory = queryFactory;
- this.cacheSize = cacheSize;
- }
-
- @Override
- public synchronized Query getQuery(Element e) throws ParserException {
- Element childElement = DOMUtils.getFirstChildOrFail(e);
-
- if (queryCache == null) {
- queryCache = new LRUCache<>(cacheSize);
- }
-
- // Test to see if child Element is a query or filter that needs to be
- // cached
- QueryBuilder qb = queryFactory.getQueryBuilder(childElement.getNodeName());
- Object cacheKey = null;
- Query q = qb.getQuery(childElement);
- cacheKey = q;
- Query cachedQuery = queryCache.get(cacheKey);
- if (cachedQuery != null) {
- return cachedQuery; // cache hit
- }
-
- //cache miss
- cachedQuery = new CachingWrapperQuery(q);
-
- queryCache.put(cacheKey, cachedQuery);
- return cachedQuery;
- }
-
- static class LRUCache extends java.util.LinkedHashMap {
-
- public LRUCache(int maxsize) {
- super(maxsize * 4 / 3 + 1, 0.75f, true);
- this.maxsize = maxsize;
- }
-
- protected int maxsize;
-
- @Override
- protected boolean removeEldestEntry(Map.Entry eldest) {
- return size() > maxsize;
- }
-
- }
-
-}
diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/CachedQuery.xml b/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/CachedQuery.xml
deleted file mode 100644
index 4db37b0ff03..00000000000
--- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/CachedQuery.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
- merger
-
-
- sumitomo
-
-
-
-
-
- bank
-
-
-
-
diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestParser.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestParser.java
index 94c795e91c7..1d33f2800db 100644
--- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestParser.java
+++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestParser.java
@@ -181,11 +181,6 @@ public class TestParser extends LuceneTestCase {
dumpResults("Nested Boolean query", q, 5);
}
- public void testCachedFilterXML() throws ParserException, IOException {
- Query q = parse("CachedQuery.xml");
- dumpResults("Cached filter", q, 5);
- }
-
public void testNumericRangeQueryQueryXML() throws ParserException, IOException {
Query q = parse("NumericRangeQueryQuery.xml");
dumpResults("NumericRangeQuery", q, 5);