Added no-cache infrastucture the the filter cache.
During query parsing if a filter is encountered that extends from NoCacheFilter then the filter will not be given to the filter cache (also not wrapped in FilterCacheFilterWrapper). Also if a filter directly or indirectly wraps a NoCacheFilter then that filter will also not be cached. Relates to #4757
This commit is contained in:
parent
e34a35244c
commit
0e418d18a4
|
@ -19,11 +19,61 @@
|
|||
|
||||
package org.elasticsearch.common.lucene.search;
|
||||
|
||||
import org.apache.lucene.index.AtomicReaderContext;
|
||||
import org.apache.lucene.search.DocIdSet;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.util.Bits;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A marker interface for {@link org.apache.lucene.search.Filter} denoting the filter
|
||||
* as one that should not be cached, ever.
|
||||
*/
|
||||
public abstract class NoCacheFilter extends Filter {
|
||||
|
||||
private static final class NoCacheFilterWrapper extends NoCacheFilter {
|
||||
private final Filter delegate;
|
||||
private NoCacheFilterWrapper(Filter delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocIdSet getDocIdSet(AtomicReaderContext context, Bits acceptDocs) throws IOException {
|
||||
return delegate.getDocIdSet(context, acceptDocs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof NoCacheFilterWrapper) {
|
||||
return delegate.equals(((NoCacheFilterWrapper)obj).delegate);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
return "no_cache(" + delegate + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a filter in a NoCacheFilter or returns it if it already is a NoCacheFilter.
|
||||
*/
|
||||
public static Filter wrap(Filter filter) {
|
||||
if (filter instanceof NoCacheFilter) {
|
||||
return filter;
|
||||
}
|
||||
return new NoCacheFilterWrapper(filter);
|
||||
}
|
||||
}
|
|
@ -30,6 +30,7 @@ import org.apache.lucene.search.similarities.Similarity;
|
|||
import org.elasticsearch.cache.recycler.CacheRecycler;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.lucene.search.NoCacheFilter;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
|
@ -75,6 +76,8 @@ public class QueryParseContext {
|
|||
|
||||
private final Index index;
|
||||
|
||||
private boolean propagateNoCache = false;
|
||||
|
||||
IndexQueryParserService indexQueryParser;
|
||||
|
||||
private final Map<String, Filter> namedFilters = Maps.newHashMap();
|
||||
|
@ -168,6 +171,9 @@ public class QueryParseContext {
|
|||
if (filter == null) {
|
||||
return null;
|
||||
}
|
||||
if (this.propagateNoCache || filter instanceof NoCacheFilter) {
|
||||
return filter;
|
||||
}
|
||||
if (cacheKey != null) {
|
||||
filter = new CacheKeyFilter.Wrapper(filter, cacheKey);
|
||||
}
|
||||
|
@ -251,7 +257,7 @@ public class QueryParseContext {
|
|||
if (filterParser == null) {
|
||||
throw new QueryParsingException(index, "No filter registered for [" + filterName + "]");
|
||||
}
|
||||
Filter result = filterParser.parse(this);
|
||||
Filter result = executeFilterParser(filterParser);
|
||||
if (parser.currentToken() == XContentParser.Token.END_OBJECT || parser.currentToken() == XContentParser.Token.END_ARRAY) {
|
||||
// if we are at END_OBJECT, move to the next one...
|
||||
parser.nextToken();
|
||||
|
@ -264,12 +270,17 @@ public class QueryParseContext {
|
|||
if (filterParser == null) {
|
||||
throw new QueryParsingException(index, "No filter registered for [" + filterName + "]");
|
||||
}
|
||||
return executeFilterParser(filterParser);
|
||||
}
|
||||
|
||||
private Filter executeFilterParser(FilterParser filterParser) throws IOException {
|
||||
final boolean propagateNoCache = this.propagateNoCache; // first safe the state that we need to restore
|
||||
this.propagateNoCache = false; // parse the subfilter with caching, that's fine
|
||||
Filter result = filterParser.parse(this);
|
||||
// don't move to the nextToken in this case...
|
||||
// if (parser.currentToken() == XContentParser.Token.END_OBJECT || parser.currentToken() == XContentParser.Token.END_ARRAY) {
|
||||
// // if we are at END_OBJECT, move to the next one...
|
||||
// parser.nextToken();
|
||||
// }
|
||||
// now make sure we set propagateNoCache to true if it is true already or if the result is
|
||||
// an instance of NoCacheFilter or if we used to be true! all filters above will
|
||||
// be not cached ie. wrappers of this filter!
|
||||
this.propagateNoCache |= (result instanceof NoCacheFilter) || propagateNoCache;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue