mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-17 10:25:15 +00:00
Introduced FixedBitSetFilterCache that guarantees to produce a FixedBitSet and does evict based on size or time.
Only when segments are merged away due to merging then entries in this cache are cleaned up. Nested and parent/child rely on the fact that type filters produce a FixedBitSet, the FixedBitSetFilterCache does this. Also if nested and parent/child is configured the type filters are eagerly loaded by default via the FixedBitSetFilterCache. Closes #7037 Closes #7031
This commit is contained in:
parent
852a1103f3
commit
94eed4ef56
@ -31,6 +31,7 @@ import org.elasticsearch.index.AbstractIndexComponent;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.cache.docset.DocSetCache;
|
||||
import org.elasticsearch.index.cache.filter.FilterCache;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache;
|
||||
import org.elasticsearch.index.cache.query.parser.QueryParserCache;
|
||||
import org.elasticsearch.index.settings.IndexSettings;
|
||||
|
||||
@ -42,15 +43,17 @@ public class IndexCache extends AbstractIndexComponent implements CloseableCompo
|
||||
private final FilterCache filterCache;
|
||||
private final QueryParserCache queryParserCache;
|
||||
private final DocSetCache docSetCache;
|
||||
private final FixedBitSetFilterCache fixedBitSetFilterCache;
|
||||
|
||||
private ClusterService clusterService;
|
||||
|
||||
@Inject
|
||||
public IndexCache(Index index, @IndexSettings Settings indexSettings, FilterCache filterCache, QueryParserCache queryParserCache, DocSetCache docSetCache) {
|
||||
public IndexCache(Index index, @IndexSettings Settings indexSettings, FilterCache filterCache, QueryParserCache queryParserCache, DocSetCache docSetCache, FixedBitSetFilterCache fixedBitSetFilterCache) {
|
||||
super(index, indexSettings);
|
||||
this.filterCache = filterCache;
|
||||
this.queryParserCache = queryParserCache;
|
||||
this.docSetCache = docSetCache;
|
||||
this.fixedBitSetFilterCache = fixedBitSetFilterCache;
|
||||
}
|
||||
|
||||
@Inject(optional = true)
|
||||
@ -78,6 +81,7 @@ public class IndexCache extends AbstractIndexComponent implements CloseableCompo
|
||||
filterCache.close();
|
||||
queryParserCache.close();
|
||||
docSetCache.clear("close");
|
||||
fixedBitSetFilterCache.clear("close");
|
||||
if (clusterService != null) {
|
||||
clusterService.remove(this);
|
||||
}
|
||||
@ -87,6 +91,7 @@ public class IndexCache extends AbstractIndexComponent implements CloseableCompo
|
||||
filterCache.clear(reason);
|
||||
queryParserCache.clear();
|
||||
docSetCache.clear(reason);
|
||||
fixedBitSetFilterCache.clear(reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -23,6 +23,7 @@ import org.elasticsearch.common.inject.AbstractModule;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.cache.docset.DocSetCacheModule;
|
||||
import org.elasticsearch.index.cache.filter.FilterCacheModule;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCacheModule;
|
||||
import org.elasticsearch.index.cache.query.parser.QueryParserCacheModule;
|
||||
|
||||
/**
|
||||
@ -41,6 +42,7 @@ public class IndexCacheModule extends AbstractModule {
|
||||
new FilterCacheModule(settings).configure(binder());
|
||||
new QueryParserCacheModule(settings).configure(binder());
|
||||
new DocSetCacheModule(settings).configure(binder());
|
||||
new FixedBitSetFilterCacheModule(settings).configure(binder());
|
||||
|
||||
bind(IndexCache.class).asEagerSingleton();
|
||||
}
|
||||
|
37
src/main/java/org/elasticsearch/index/cache/fixedbitset/FixedBitSetFilter.java
vendored
Normal file
37
src/main/java/org/elasticsearch/index/cache/fixedbitset/FixedBitSetFilter.java
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch 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.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.cache.fixedbitset;
|
||||
|
||||
import org.apache.lucene.index.AtomicReaderContext;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.FixedBitSet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A filter that always returns a {@link FixedBitSet}.
|
||||
*/
|
||||
public abstract class FixedBitSetFilter extends Filter {
|
||||
|
||||
@Override
|
||||
public abstract FixedBitSet getDocIdSet(AtomicReaderContext context, Bits acceptDocs) throws IOException;
|
||||
|
||||
}
|
305
src/main/java/org/elasticsearch/index/cache/fixedbitset/FixedBitSetFilterCache.java
vendored
Normal file
305
src/main/java/org/elasticsearch/index/cache/fixedbitset/FixedBitSetFilterCache.java
vendored
Normal file
@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch 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.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.cache.fixedbitset;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.RemovalListener;
|
||||
import com.google.common.cache.RemovalNotification;
|
||||
import org.apache.lucene.index.AtomicReader;
|
||||
import org.apache.lucene.index.AtomicReaderContext;
|
||||
import org.apache.lucene.search.DocIdSet;
|
||||
import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.FixedBitSet;
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.lucene.SegmentReaderUtils;
|
||||
import org.elasticsearch.common.lucene.search.NoCacheFilter;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.index.AbstractIndexComponent;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||
import org.elasticsearch.index.mapper.object.ObjectMapper;
|
||||
import org.elasticsearch.index.search.nested.NestedDocsFilter;
|
||||
import org.elasticsearch.index.search.nested.NonNestedDocsFilter;
|
||||
import org.elasticsearch.index.service.IndexService;
|
||||
import org.elasticsearch.index.service.InternalIndexService;
|
||||
import org.elasticsearch.index.settings.IndexSettings;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.index.shard.ShardUtils;
|
||||
import org.elasticsearch.index.shard.service.IndexShard;
|
||||
import org.elasticsearch.indices.warmer.IndicesWarmer;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* This is a cache for {@link FixedBitSet} based filters and is unbounded by size or time.
|
||||
* <p/>
|
||||
* Use this cache with care, only components that require that a filter is to be materialized as a {@link FixedBitSet}
|
||||
* and require that it should always be around should use this cache, otherwise the
|
||||
* {@link org.elasticsearch.index.cache.filter.FilterCache} should be used instead.
|
||||
*/
|
||||
public class FixedBitSetFilterCache extends AbstractIndexComponent implements AtomicReader.CoreClosedListener, RemovalListener<Object, Cache<Filter, FixedBitSetFilterCache.Value>> {
|
||||
|
||||
public static final String LOAD_RANDOM_ACCESS_FILTERS_EAGERLY = "index.load_fixed_bitset_filters_eagerly";
|
||||
|
||||
private final boolean loadRandomAccessFiltersEagerly;
|
||||
private final Cache<Object, Cache<Filter, Value>> loadedFilters;
|
||||
|
||||
private IndexService indexService;
|
||||
|
||||
@Inject
|
||||
public FixedBitSetFilterCache(Index index, @IndexSettings Settings indexSettings) {
|
||||
super(index, indexSettings);
|
||||
this.loadRandomAccessFiltersEagerly = indexSettings.getAsBoolean(LOAD_RANDOM_ACCESS_FILTERS_EAGERLY, true);
|
||||
this.loadedFilters = CacheBuilder.newBuilder().removalListener(this).build();
|
||||
}
|
||||
|
||||
@Inject(optional = true)
|
||||
public void setIndicesWarmer(IndicesWarmer indicesWarmer) {
|
||||
indicesWarmer.addListener(new FixedBitSetFilterWarmer());
|
||||
}
|
||||
|
||||
public FixedBitSetFilter getFixedBitSetFilter(Filter filter) {
|
||||
assert filter != null;
|
||||
assert !(filter instanceof NoCacheFilter);
|
||||
return new FixedBitSetFilterWrapper(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(Object ownerCoreCacheKey) {
|
||||
loadedFilters.invalidate(ownerCoreCacheKey);
|
||||
}
|
||||
|
||||
public void clear(String reason) {
|
||||
logger.debug("Clearing all FixedBitSets because [{}]", reason);
|
||||
loadedFilters.invalidateAll();
|
||||
loadedFilters.cleanUp();
|
||||
}
|
||||
|
||||
private FixedBitSet getAndLoadIfNotPresent(final Filter filter, final AtomicReaderContext context) throws IOException, ExecutionException {
|
||||
final Object coreCacheReader = context.reader().getCoreCacheKey();
|
||||
final ShardId shardId = ShardUtils.extractShardId(context.reader());
|
||||
Cache<Filter, Value> filterToFbs = loadedFilters.get(coreCacheReader, new Callable<Cache<Filter, Value>>() {
|
||||
@Override
|
||||
public Cache<Filter, Value> call() throws Exception {
|
||||
SegmentReaderUtils.registerCoreListener(context.reader(), FixedBitSetFilterCache.this);
|
||||
return CacheBuilder.newBuilder().build();
|
||||
}
|
||||
});
|
||||
return filterToFbs.get(filter, new Callable<Value>() {
|
||||
@Override
|
||||
public Value call() throws Exception {
|
||||
DocIdSet docIdSet = filter.getDocIdSet(context, null);
|
||||
final FixedBitSet fixedBitSet;
|
||||
if (docIdSet instanceof FixedBitSet) {
|
||||
fixedBitSet = (FixedBitSet) docIdSet;
|
||||
} else {
|
||||
fixedBitSet = new FixedBitSet(context.reader().maxDoc());
|
||||
if (docIdSet != null && docIdSet != DocIdSet.EMPTY) {
|
||||
DocIdSetIterator iterator = docIdSet.iterator();
|
||||
if (iterator != null) {
|
||||
int doc = iterator.nextDoc();
|
||||
if (doc != DocIdSetIterator.NO_MORE_DOCS) {
|
||||
do {
|
||||
fixedBitSet.set(doc);
|
||||
doc = iterator.nextDoc();
|
||||
} while (doc != DocIdSetIterator.NO_MORE_DOCS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Value value = new Value(fixedBitSet, shardId);
|
||||
if (shardId != null) {
|
||||
IndexShard shard = indexService.shard(shardId.id());
|
||||
if (shard != null) {
|
||||
shard.shardFixedBitSetFilterCache().onCached(value.fixedBitSet.ramBytesUsed());
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}).fixedBitSet;
|
||||
}
|
||||
|
||||
public void setIndexService(InternalIndexService indexService) {
|
||||
this.indexService = indexService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoval(RemovalNotification<Object, Cache<Filter, Value>> notification) {
|
||||
Object key = notification.getKey();
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Cache<Filter, Value> value = notification.getValue();
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Map.Entry<Filter, Value> entry : value.asMap().entrySet()) {
|
||||
if (entry.getValue().shardId == null) {
|
||||
continue;
|
||||
}
|
||||
IndexShard shard = indexService.shard(entry.getValue().shardId.id());
|
||||
if (shard != null) {
|
||||
ShardFixedBitSetFilterCache shardFixedBitSetFilterCache = shard.shardFixedBitSetFilterCache();
|
||||
shardFixedBitSetFilterCache.onRemoval(entry.getValue().fixedBitSet.ramBytesUsed());
|
||||
}
|
||||
// if null then this means the shard has already been removed and the stats are 0 anyway for the shard this key belongs to
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Value {
|
||||
|
||||
final FixedBitSet fixedBitSet;
|
||||
final ShardId shardId;
|
||||
|
||||
public Value(FixedBitSet fixedBitSet, ShardId shardId) {
|
||||
this.fixedBitSet = fixedBitSet;
|
||||
this.shardId = shardId;
|
||||
}
|
||||
}
|
||||
|
||||
final class FixedBitSetFilterWrapper extends FixedBitSetFilter {
|
||||
|
||||
final Filter filter;
|
||||
|
||||
FixedBitSetFilterWrapper(Filter filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FixedBitSet getDocIdSet(AtomicReaderContext context, Bits acceptDocs) throws IOException {
|
||||
try {
|
||||
return getAndLoadIfNotPresent(filter, context);
|
||||
} catch (ExecutionException e) {
|
||||
throw ExceptionsHelper.convertToElastic(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "random_access(" + filter + ")";
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof FixedBitSetFilterWrapper)) return false;
|
||||
return this.filter.equals(((FixedBitSetFilterWrapper) o).filter);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return filter.hashCode() ^ 0x1117BF26;
|
||||
}
|
||||
}
|
||||
|
||||
final class FixedBitSetFilterWarmer extends IndicesWarmer.Listener {
|
||||
|
||||
@Override
|
||||
public TerminationHandle warmNewReaders(final IndexShard indexShard, IndexMetaData indexMetaData, IndicesWarmer.WarmerContext context, ThreadPool threadPool) {
|
||||
if (!loadRandomAccessFiltersEagerly) {
|
||||
return TerminationHandle.NO_WAIT;
|
||||
}
|
||||
|
||||
boolean hasNested = false;
|
||||
final Set<Filter> warmUp = new HashSet<>();
|
||||
final MapperService mapperService = indexShard.mapperService();
|
||||
for (DocumentMapper docMapper : mapperService.docMappers(false)) {
|
||||
ParentFieldMapper parentFieldMapper = docMapper.parentFieldMapper();
|
||||
if (parentFieldMapper.active()) {
|
||||
warmUp.add(docMapper.typeFilter());
|
||||
DocumentMapper parentDocumentMapper = mapperService.documentMapper(parentFieldMapper.type());
|
||||
if (parentDocumentMapper != null) {
|
||||
warmUp.add(parentDocumentMapper.typeFilter());
|
||||
}
|
||||
}
|
||||
|
||||
if (docMapper.hasNestedObjects()) {
|
||||
hasNested = true;
|
||||
for (ObjectMapper objectMapper : docMapper.objectMappers().values()) {
|
||||
if (objectMapper.nested().isNested()) {
|
||||
warmUp.add(objectMapper.nestedTypeFilter());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasNested) {
|
||||
warmUp.add(NonNestedDocsFilter.INSTANCE);
|
||||
warmUp.add(NestedDocsFilter.INSTANCE);
|
||||
}
|
||||
|
||||
final Executor executor = threadPool.executor(executor());
|
||||
final CountDownLatch latch = new CountDownLatch(context.searcher().reader().leaves().size() * warmUp.size());
|
||||
for (final AtomicReaderContext ctx : context.searcher().reader().leaves()) {
|
||||
for (final Filter filterToWarm : warmUp) {
|
||||
executor.execute(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final long start = System.nanoTime();
|
||||
getAndLoadIfNotPresent(filterToWarm, ctx);
|
||||
if (indexShard.warmerService().logger().isTraceEnabled()) {
|
||||
indexShard.warmerService().logger().trace("warmed random access for [{}], took [{}]", filterToWarm, TimeValue.timeValueNanos(System.nanoTime() - start));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
indexShard.warmerService().logger().warn("failed to load random access for [{}]", t, filterToWarm);
|
||||
} finally {
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
return new TerminationHandle() {
|
||||
@Override
|
||||
public void awaitTermination() throws InterruptedException {
|
||||
latch.await();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public TerminationHandle warmTopReader(IndexShard indexShard, IndexMetaData indexMetaData, IndicesWarmer.WarmerContext context, ThreadPool threadPool) {
|
||||
return TerminationHandle.NO_WAIT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Cache<Object, Cache<Filter, Value>> getLoadedFilters() {
|
||||
return loadedFilters;
|
||||
}
|
||||
}
|
39
src/main/java/org/elasticsearch/index/cache/fixedbitset/FixedBitSetFilterCacheModule.java
vendored
Normal file
39
src/main/java/org/elasticsearch/index/cache/fixedbitset/FixedBitSetFilterCacheModule.java
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch 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.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.cache.fixedbitset;
|
||||
|
||||
import org.elasticsearch.common.inject.AbstractModule;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class FixedBitSetFilterCacheModule extends AbstractModule {
|
||||
|
||||
private final Settings settings;
|
||||
|
||||
public FixedBitSetFilterCacheModule(Settings settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(FixedBitSetFilterCache.class).asEagerSingleton();
|
||||
}
|
||||
}
|
51
src/main/java/org/elasticsearch/index/cache/fixedbitset/ShardFixedBitSetFilterCache.java
vendored
Normal file
51
src/main/java/org/elasticsearch/index/cache/fixedbitset/ShardFixedBitSetFilterCache.java
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch 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.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.cache.fixedbitset;
|
||||
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.metrics.CounterMetric;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.settings.IndexSettings;
|
||||
import org.elasticsearch.index.shard.AbstractIndexShardComponent;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ShardFixedBitSetFilterCache extends AbstractIndexShardComponent {
|
||||
|
||||
private final CounterMetric totalMetric = new CounterMetric();
|
||||
|
||||
@Inject
|
||||
public ShardFixedBitSetFilterCache(ShardId shardId, @IndexSettings Settings indexSettings) {
|
||||
super(shardId, indexSettings);
|
||||
}
|
||||
|
||||
public void onCached(long sizeInBytes) {
|
||||
totalMetric.inc(sizeInBytes);
|
||||
}
|
||||
|
||||
public void onRemoval(long sizeInBytes) {
|
||||
totalMetric.dec(sizeInBytes);
|
||||
}
|
||||
|
||||
public long getMemorySizeInBytes() {
|
||||
return totalMetric.count();
|
||||
}
|
||||
}
|
32
src/main/java/org/elasticsearch/index/cache/fixedbitset/ShardFixedBitSetFilterCacheModule.java
vendored
Normal file
32
src/main/java/org/elasticsearch/index/cache/fixedbitset/ShardFixedBitSetFilterCacheModule.java
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch 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.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.cache.fixedbitset;
|
||||
|
||||
import org.elasticsearch.common.inject.AbstractModule;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ShardFixedBitSetFilterCacheModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ShardFixedBitSetFilterCache.class).asEagerSingleton();
|
||||
}
|
||||
}
|
@ -40,6 +40,7 @@ public class SegmentsStats implements Streamable, ToXContent {
|
||||
private long indexWriterMemoryInBytes;
|
||||
private long indexWriterMaxMemoryInBytes;
|
||||
private long versionMapMemoryInBytes;
|
||||
private long fixedBitSetMemoryInBytes;
|
||||
|
||||
public SegmentsStats() {
|
||||
|
||||
@ -62,6 +63,10 @@ public class SegmentsStats implements Streamable, ToXContent {
|
||||
this.versionMapMemoryInBytes += versionMapMemoryInBytes;
|
||||
}
|
||||
|
||||
public void addFixedBitSetMemoryInBytes(long fixedBitSetMemoryInBytes) {
|
||||
this.fixedBitSetMemoryInBytes += fixedBitSetMemoryInBytes;
|
||||
}
|
||||
|
||||
public void add(SegmentsStats mergeStats) {
|
||||
if (mergeStats == null) {
|
||||
return;
|
||||
@ -70,6 +75,7 @@ public class SegmentsStats implements Streamable, ToXContent {
|
||||
addIndexWriterMemoryInBytes(mergeStats.indexWriterMemoryInBytes);
|
||||
addIndexWriterMaxMemoryInBytes(mergeStats.indexWriterMaxMemoryInBytes);
|
||||
addVersionMapMemoryInBytes(mergeStats.versionMapMemoryInBytes);
|
||||
addFixedBitSetMemoryInBytes(mergeStats.fixedBitSetMemoryInBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,6 +129,17 @@ public class SegmentsStats implements Streamable, ToXContent {
|
||||
return new ByteSizeValue(versionMapMemoryInBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimation of how much the cached fixed bit sets are taking. (which nested and p/c rely on)
|
||||
*/
|
||||
public long getFixedBitSetMemoryInBytes() {
|
||||
return fixedBitSetMemoryInBytes;
|
||||
}
|
||||
|
||||
public ByteSizeValue getFixedBitSetMemory() {
|
||||
return new ByteSizeValue(fixedBitSetMemoryInBytes);
|
||||
}
|
||||
|
||||
public static SegmentsStats readSegmentsStats(StreamInput in) throws IOException {
|
||||
SegmentsStats stats = new SegmentsStats();
|
||||
stats.readFrom(in);
|
||||
@ -137,6 +154,7 @@ public class SegmentsStats implements Streamable, ToXContent {
|
||||
builder.byteSizeField(Fields.INDEX_WRITER_MEMORY_IN_BYTES, Fields.INDEX_WRITER_MEMORY, indexWriterMemoryInBytes);
|
||||
builder.byteSizeField(Fields.INDEX_WRITER_MAX_MEMORY_IN_BYTES, Fields.INDEX_WRITER_MAX_MEMORY, indexWriterMaxMemoryInBytes);
|
||||
builder.byteSizeField(Fields.VERSION_MAP_MEMORY_IN_BYTES, Fields.VERSION_MAP_MEMORY, versionMapMemoryInBytes);
|
||||
builder.byteSizeField(Fields.FIXED_BIT_SET_MEMORY_IN_BYTES, Fields.FIXED_BIT_SET, fixedBitSetMemoryInBytes);
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
@ -152,6 +170,8 @@ public class SegmentsStats implements Streamable, ToXContent {
|
||||
static final XContentBuilderString INDEX_WRITER_MAX_MEMORY_IN_BYTES = new XContentBuilderString("index_writer_max_memory_in_bytes");
|
||||
static final XContentBuilderString VERSION_MAP_MEMORY = new XContentBuilderString("version_map_memory");
|
||||
static final XContentBuilderString VERSION_MAP_MEMORY_IN_BYTES = new XContentBuilderString("version_map_memory_in_bytes");
|
||||
static final XContentBuilderString FIXED_BIT_SET = new XContentBuilderString("fixed_bit_set");
|
||||
static final XContentBuilderString FIXED_BIT_SET_MEMORY_IN_BYTES = new XContentBuilderString("fixed_bit_set_memory_in_bytes");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -165,6 +185,9 @@ public class SegmentsStats implements Streamable, ToXContent {
|
||||
if (in.getVersion().onOrAfter(Version.V_1_4_0)) {
|
||||
indexWriterMaxMemoryInBytes = in.readLong();
|
||||
}
|
||||
if (in.getVersion().onOrAfter(Version.V_1_4_0)) {
|
||||
fixedBitSetMemoryInBytes = in.readLong();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -178,5 +201,8 @@ public class SegmentsStats implements Streamable, ToXContent {
|
||||
if (out.getVersion().onOrAfter(Version.V_1_4_0)) {
|
||||
out.writeLong(indexWriterMaxMemoryInBytes);
|
||||
}
|
||||
if (out.getVersion().onOrAfter(Version.V_1_4_0)) {
|
||||
out.writeLong(fixedBitSetMemoryInBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.IndexComponent;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
@ -127,41 +128,25 @@ public interface IndexFieldData<FD extends AtomicFieldData> extends IndexCompone
|
||||
* parent + 1, or 0 if there is no previous parent, and R (excluded).
|
||||
*/
|
||||
public static class Nested {
|
||||
private final Filter rootFilter, innerFilter;
|
||||
private final FixedBitSetFilter rootFilter, innerFilter;
|
||||
|
||||
public Nested(Filter rootFilter, Filter innerFilter) {
|
||||
public Nested(FixedBitSetFilter rootFilter, FixedBitSetFilter innerFilter) {
|
||||
this.rootFilter = rootFilter;
|
||||
this.innerFilter = innerFilter;
|
||||
}
|
||||
|
||||
// TODO: nested docs should not be random filters but specialized
|
||||
// ones that guarantee that you always get a FixedBitSet
|
||||
@Deprecated
|
||||
private static FixedBitSet toFixedBitSet(DocIdSet set, int maxDoc) throws IOException {
|
||||
if (set == null || set instanceof FixedBitSet) {
|
||||
return (FixedBitSet) set;
|
||||
} else {
|
||||
final FixedBitSet fixedBitSet = new FixedBitSet(maxDoc);
|
||||
final DocIdSetIterator it = set.iterator();
|
||||
if (it != null) {
|
||||
fixedBitSet.or(it);
|
||||
}
|
||||
return fixedBitSet;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@link FixedBitSet} that matches the root documents.
|
||||
*/
|
||||
public FixedBitSet rootDocs(AtomicReaderContext ctx) throws IOException {
|
||||
return toFixedBitSet(rootFilter.getDocIdSet(ctx, null), ctx.reader().maxDoc());
|
||||
return rootFilter.getDocIdSet(ctx, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@link FixedBitSet} that matches the inner documents.
|
||||
*/
|
||||
public FixedBitSet innerDocs(AtomicReaderContext ctx) throws IOException {
|
||||
return toFixedBitSet(innerFilter.getDocIdSet(ctx, null), ctx.reader().maxDoc());
|
||||
return innerFilter.getDocIdSet(ctx, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||
@ -148,12 +149,12 @@ public class HasChildFilterParser implements FilterParser {
|
||||
throw new QueryParsingException(parseContext.index(), "[has_child] 'max_children' is less than 'min_children'");
|
||||
}
|
||||
|
||||
Filter nonNestedDocsFilter = null;
|
||||
FixedBitSetFilter nonNestedDocsFilter = null;
|
||||
if (parentDocMapper.hasNestedObjects()) {
|
||||
nonNestedDocsFilter = parseContext.cacheFilter(NonNestedDocsFilter.INSTANCE, null);
|
||||
nonNestedDocsFilter = parseContext.fixedBitSetFilter(NonNestedDocsFilter.INSTANCE);
|
||||
}
|
||||
|
||||
Filter parentFilter = parseContext.cacheFilter(parentDocMapper.typeFilter(), null);
|
||||
FixedBitSetFilter parentFilter = parseContext.fixedBitSetFilter(parentDocMapper.typeFilter());
|
||||
ParentChildIndexFieldData parentChildIndexFieldData = parseContext.getForField(parentFieldMapper);
|
||||
|
||||
Query childrenQuery;
|
||||
|
@ -19,12 +19,12 @@
|
||||
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||
@ -146,16 +146,16 @@ public class HasChildQueryParser implements QueryParser {
|
||||
throw new QueryParsingException(parseContext.index(), "[has_child] 'max_children' is less than 'min_children'");
|
||||
}
|
||||
|
||||
Filter nonNestedDocsFilter = null;
|
||||
FixedBitSetFilter nonNestedDocsFilter = null;
|
||||
if (parentDocMapper.hasNestedObjects()) {
|
||||
nonNestedDocsFilter = parseContext.cacheFilter(NonNestedDocsFilter.INSTANCE, null);
|
||||
nonNestedDocsFilter = parseContext.fixedBitSetFilter(NonNestedDocsFilter.INSTANCE);
|
||||
}
|
||||
|
||||
// wrap the query with type query
|
||||
innerQuery = new XFilteredQuery(innerQuery, parseContext.cacheFilter(childDocMapper.typeFilter(), null));
|
||||
|
||||
Query query;
|
||||
Filter parentFilter = parseContext.cacheFilter(parentDocMapper.typeFilter(), null);
|
||||
FixedBitSetFilter parentFilter = parseContext.fixedBitSetFilter(parentDocMapper.typeFilter());
|
||||
ParentChildIndexFieldData parentChildIndexFieldData = parseContext.getForField(parentFieldMapper);
|
||||
if (minChildren > 1 || maxChildren > 0 || scoreType != ScoreType.NONE) {
|
||||
query = new ChildrenQuery(parentChildIndexFieldData, parentType, childType, parentFilter, innerQuery, scoreType, minChildren,
|
||||
|
@ -23,6 +23,10 @@ import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||
import org.elasticsearch.index.query.support.XContentStructure;
|
||||
import org.elasticsearch.index.search.child.CustomQueryWrappingFilter;
|
||||
|
||||
|
@ -27,6 +27,7 @@ import org.elasticsearch.common.lucene.search.NotFilter;
|
||||
import org.elasticsearch.common.lucene.search.XBooleanFilter;
|
||||
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||
@ -164,15 +165,14 @@ public class HasParentQueryParser implements QueryParser {
|
||||
if (parentTypes.size() == 1) {
|
||||
DocumentMapper documentMapper = parseContext.mapperService().documentMapper(parentTypes.iterator().next());
|
||||
if (documentMapper != null) {
|
||||
parentFilter = parseContext.cacheFilter(documentMapper.typeFilter(), null);
|
||||
parentFilter = documentMapper.typeFilter();
|
||||
}
|
||||
} else {
|
||||
XBooleanFilter parentsFilter = new XBooleanFilter();
|
||||
for (String parentTypeStr : parentTypes) {
|
||||
DocumentMapper documentMapper = parseContext.mapperService().documentMapper(parentTypeStr);
|
||||
if (documentMapper != null) {
|
||||
Filter filter = parseContext.cacheFilter(documentMapper.typeFilter(), null);
|
||||
parentsFilter.add(filter, BooleanClause.Occur.SHOULD);
|
||||
parentsFilter.add(documentMapper.typeFilter(), BooleanClause.Occur.SHOULD);
|
||||
}
|
||||
}
|
||||
parentFilter = parentsFilter;
|
||||
@ -182,7 +182,7 @@ public class HasParentQueryParser implements QueryParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
Filter childrenFilter = parseContext.cacheFilter(new NotFilter(parentFilter), null);
|
||||
FixedBitSetFilter childrenFilter = parseContext.fixedBitSetFilter(new NotFilter(parentFilter));
|
||||
if (score) {
|
||||
return new ParentQuery(parentChildIndexFieldData, innerQuery, parentType, childrenFilter);
|
||||
} else {
|
||||
|
@ -38,6 +38,7 @@ import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.cache.IndexCache;
|
||||
import org.elasticsearch.index.engine.IndexEngine;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldDataService;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.mapper.internal.AllFieldMapper;
|
||||
@ -84,6 +85,8 @@ public class IndexQueryParserService extends AbstractIndexComponent {
|
||||
|
||||
final IndexFieldDataService fieldDataService;
|
||||
|
||||
final FixedBitSetFilterCache fixedBitSetFilterCache;
|
||||
|
||||
final IndexEngine indexEngine;
|
||||
|
||||
private final Map<String, QueryParser> queryParsers;
|
||||
@ -98,7 +101,8 @@ public class IndexQueryParserService extends AbstractIndexComponent {
|
||||
public IndexQueryParserService(Index index, @IndexSettings Settings indexSettings,
|
||||
IndicesQueriesRegistry indicesQueriesRegistry,
|
||||
ScriptService scriptService, AnalysisService analysisService,
|
||||
MapperService mapperService, IndexCache indexCache, IndexFieldDataService fieldDataService, IndexEngine indexEngine,
|
||||
MapperService mapperService, IndexCache indexCache, IndexFieldDataService fieldDataService,
|
||||
IndexEngine indexEngine, FixedBitSetFilterCache fixedBitSetFilterCache,
|
||||
@Nullable SimilarityService similarityService,
|
||||
@Nullable Map<String, QueryParserFactory> namedQueryParsers,
|
||||
@Nullable Map<String, FilterParserFactory> namedFilterParsers) {
|
||||
@ -110,6 +114,7 @@ public class IndexQueryParserService extends AbstractIndexComponent {
|
||||
this.indexCache = indexCache;
|
||||
this.fieldDataService = fieldDataService;
|
||||
this.indexEngine = indexEngine;
|
||||
this.fixedBitSetFilterCache = fixedBitSetFilterCache;
|
||||
|
||||
this.defaultField = indexSettings.get("index.query.default_field", AllFieldMapper.NAME);
|
||||
this.queryStringLenient = indexSettings.getAsBoolean("index.query_string.lenient", false);
|
||||
|
@ -21,7 +21,6 @@ package org.elasticsearch.index.query;
|
||||
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.join.FixedBitSetCachingWrapperFilter;
|
||||
import org.apache.lucene.search.join.ScoreMode;
|
||||
import org.apache.lucene.search.join.ToParentBlockJoinQuery;
|
||||
import org.elasticsearch.common.Strings;
|
||||
@ -144,11 +143,10 @@ public class NestedFilterParser implements FilterParser {
|
||||
// // filter based on the type...
|
||||
// parentFilter = mapper.docMapper().typeFilter();
|
||||
//}
|
||||
parentFilter = parseContext.cacheFilter(parentFilter, null);
|
||||
}
|
||||
// if the filter cache is disabled, then we still have a filter that is not cached while ToParentBlockJoinQuery
|
||||
// expects FixedBitSet instances
|
||||
parentFilter = new FixedBitSetCachingWrapperFilter(parentFilter);
|
||||
parentFilter = parseContext.fixedBitSetFilter(parentFilter);
|
||||
|
||||
Filter nestedFilter = Queries.wrap(new ToParentBlockJoinQuery(query, parentFilter, ScoreMode.None));
|
||||
|
||||
|
@ -23,7 +23,6 @@ import org.apache.lucene.index.AtomicReaderContext;
|
||||
import org.apache.lucene.search.DocIdSet;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.join.FixedBitSetCachingWrapperFilter;
|
||||
import org.apache.lucene.search.join.ScoreMode;
|
||||
import org.apache.lucene.search.join.ToParentBlockJoinQuery;
|
||||
import org.apache.lucene.util.Bits;
|
||||
@ -151,12 +150,8 @@ public class NestedQueryParser implements QueryParser {
|
||||
// // filter based on the type...
|
||||
// parentFilter = mapper.docMapper().typeFilter();
|
||||
//}
|
||||
parentFilter = parseContext.cacheFilter(parentFilter, null);
|
||||
}
|
||||
// if the filter cache is disabled, then we still have a filter that is not cached while ToParentBlockJoinQuery
|
||||
// expects FixedBitSet instances
|
||||
parentFilter = new FixedBitSetCachingWrapperFilter(parentFilter);
|
||||
|
||||
parentFilter = parseContext.fixedBitSetFilter(parentFilter);
|
||||
ToParentBlockJoinQuery joinQuery = new ToParentBlockJoinQuery(query, parentFilter, scoreMode);
|
||||
joinQuery.setBoost(boost);
|
||||
if (queryName != null) {
|
||||
|
@ -36,6 +36,7 @@ import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.cache.filter.support.CacheKeyFilter;
|
||||
import org.elasticsearch.index.cache.query.parser.QueryParserCache;
|
||||
import org.elasticsearch.index.engine.IndexEngine;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.mapper.FieldMappers;
|
||||
@ -169,6 +170,10 @@ public class QueryParseContext {
|
||||
return queryParser;
|
||||
}
|
||||
|
||||
public FixedBitSetFilter fixedBitSetFilter(Filter filter) {
|
||||
return indexQueryParser.fixedBitSetFilterCache.getFixedBitSetFilter(filter);
|
||||
}
|
||||
|
||||
public Filter cacheFilter(Filter filter, @Nullable CacheKeyFilter.Key cacheKey) {
|
||||
if (filter == null) {
|
||||
return null;
|
||||
|
@ -18,12 +18,12 @@
|
||||
*/
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||
@ -126,9 +126,9 @@ public class TopChildrenQueryParser implements QueryParser {
|
||||
}
|
||||
String parentType = childDocMapper.parentFieldMapper().type();
|
||||
|
||||
Filter nonNestedDocsFilter = null;
|
||||
FixedBitSetFilter nonNestedDocsFilter = null;
|
||||
if (childDocMapper.hasNestedObjects()) {
|
||||
nonNestedDocsFilter = parseContext.cacheFilter(NonNestedDocsFilter.INSTANCE, null);
|
||||
nonNestedDocsFilter = parseContext.fixedBitSetFilter(NonNestedDocsFilter.INSTANCE);
|
||||
}
|
||||
|
||||
innerQuery.setBoost(boost);
|
||||
|
@ -30,6 +30,7 @@ import org.elasticsearch.common.lucene.docset.DocIdSets;
|
||||
import org.elasticsearch.common.lucene.search.ApplyAcceptedDocsFilter;
|
||||
import org.elasticsearch.common.lucene.search.NoopCollector;
|
||||
import org.elasticsearch.common.lucene.search.Queries;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.AtomicParentChildFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexParentChildFieldData;
|
||||
import org.elasticsearch.search.internal.SearchContext;
|
||||
@ -47,14 +48,14 @@ public class ChildrenConstantScoreQuery extends Query {
|
||||
private Query originalChildQuery;
|
||||
private final String parentType;
|
||||
private final String childType;
|
||||
private final Filter parentFilter;
|
||||
private final FixedBitSetFilter parentFilter;
|
||||
private final int shortCircuitParentDocSet;
|
||||
private final Filter nonNestedDocsFilter;
|
||||
private final FixedBitSetFilter nonNestedDocsFilter;
|
||||
|
||||
private Query rewrittenChildQuery;
|
||||
private IndexReader rewriteIndexReader;
|
||||
|
||||
public ChildrenConstantScoreQuery(IndexParentChildFieldData parentChildIndexFieldData, Query childQuery, String parentType, String childType, Filter parentFilter, int shortCircuitParentDocSet, Filter nonNestedDocsFilter) {
|
||||
public ChildrenConstantScoreQuery(IndexParentChildFieldData parentChildIndexFieldData, Query childQuery, String parentType, String childType, FixedBitSetFilter parentFilter, int shortCircuitParentDocSet, FixedBitSetFilter nonNestedDocsFilter) {
|
||||
this.parentChildIndexFieldData = parentChildIndexFieldData;
|
||||
this.parentFilter = parentFilter;
|
||||
this.parentType = parentType;
|
||||
|
@ -36,6 +36,7 @@ import org.elasticsearch.common.util.BigArrays;
|
||||
import org.elasticsearch.common.util.FloatArray;
|
||||
import org.elasticsearch.common.util.IntArray;
|
||||
import org.elasticsearch.common.util.LongHash;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.IndexParentChildFieldData;
|
||||
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
|
||||
import org.elasticsearch.search.internal.SearchContext;
|
||||
@ -58,18 +59,18 @@ public class ChildrenQuery extends Query {
|
||||
protected final ParentChildIndexFieldData ifd;
|
||||
protected final String parentType;
|
||||
protected final String childType;
|
||||
protected final Filter parentFilter;
|
||||
protected final FixedBitSetFilter parentFilter;
|
||||
protected final ScoreType scoreType;
|
||||
protected Query originalChildQuery;
|
||||
protected final int minChildren;
|
||||
protected final int maxChildren;
|
||||
protected final int shortCircuitParentDocSet;
|
||||
protected final Filter nonNestedDocsFilter;
|
||||
protected final FixedBitSetFilter nonNestedDocsFilter;
|
||||
|
||||
protected Query rewrittenChildQuery;
|
||||
protected IndexReader rewriteIndexReader;
|
||||
|
||||
public ChildrenQuery(ParentChildIndexFieldData ifd, String parentType, String childType, Filter parentFilter, Query childQuery, ScoreType scoreType, int minChildren, int maxChildren, int shortCircuitParentDocSet, Filter nonNestedDocsFilter) {
|
||||
public ChildrenQuery(ParentChildIndexFieldData ifd, String parentType, String childType, FixedBitSetFilter parentFilter, Query childQuery, ScoreType scoreType, int minChildren, int maxChildren, int shortCircuitParentDocSet, FixedBitSetFilter nonNestedDocsFilter) {
|
||||
this.ifd = ifd;
|
||||
this.parentType = parentType;
|
||||
this.childType = childType;
|
||||
|
@ -29,6 +29,7 @@ import org.elasticsearch.common.lucene.docset.DocIdSets;
|
||||
import org.elasticsearch.common.lucene.search.ApplyAcceptedDocsFilter;
|
||||
import org.elasticsearch.common.lucene.search.NoopCollector;
|
||||
import org.elasticsearch.common.lucene.search.Queries;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.AtomicParentChildFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexParentChildFieldData;
|
||||
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
|
||||
@ -45,12 +46,12 @@ public class ParentConstantScoreQuery extends Query {
|
||||
private final ParentChildIndexFieldData parentChildIndexFieldData;
|
||||
private Query originalParentQuery;
|
||||
private final String parentType;
|
||||
private final Filter childrenFilter;
|
||||
private final FixedBitSetFilter childrenFilter;
|
||||
|
||||
private Query rewrittenParentQuery;
|
||||
private IndexReader rewriteIndexReader;
|
||||
|
||||
public ParentConstantScoreQuery(ParentChildIndexFieldData parentChildIndexFieldData, Query parentQuery, String parentType, Filter childrenFilter) {
|
||||
public ParentConstantScoreQuery(ParentChildIndexFieldData parentChildIndexFieldData, Query parentQuery, String parentType, FixedBitSetFilter childrenFilter) {
|
||||
this.parentChildIndexFieldData = parentChildIndexFieldData;
|
||||
this.originalParentQuery = parentQuery;
|
||||
this.parentType = parentType;
|
||||
|
@ -32,6 +32,7 @@ import org.elasticsearch.common.lucene.search.Queries;
|
||||
import org.elasticsearch.common.util.BigArrays;
|
||||
import org.elasticsearch.common.util.FloatArray;
|
||||
import org.elasticsearch.common.util.LongHash;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.IndexParentChildFieldData;
|
||||
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
|
||||
import org.elasticsearch.search.internal.SearchContext;
|
||||
@ -50,12 +51,12 @@ public class ParentQuery extends Query {
|
||||
private final ParentChildIndexFieldData parentChildIndexFieldData;
|
||||
private Query originalParentQuery;
|
||||
private final String parentType;
|
||||
private final Filter childrenFilter;
|
||||
private final FixedBitSetFilter childrenFilter;
|
||||
|
||||
private Query rewrittenParentQuery;
|
||||
private IndexReader rewriteIndexReader;
|
||||
|
||||
public ParentQuery(ParentChildIndexFieldData parentChildIndexFieldData, Query parentQuery, String parentType, Filter childrenFilter) {
|
||||
public ParentQuery(ParentChildIndexFieldData parentChildIndexFieldData, Query parentQuery, String parentType, FixedBitSetFilter childrenFilter) {
|
||||
this.parentChildIndexFieldData = parentChildIndexFieldData;
|
||||
this.originalParentQuery = parentQuery;
|
||||
this.parentType = parentType;
|
||||
|
@ -30,6 +30,7 @@ import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.ElasticsearchIllegalStateException;
|
||||
import org.elasticsearch.common.lease.Releasable;
|
||||
import org.elasticsearch.common.lucene.search.EmptyScorer;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.IndexParentChildFieldData;
|
||||
import org.elasticsearch.index.mapper.Uid;
|
||||
import org.elasticsearch.index.mapper.internal.UidFieldMapper;
|
||||
@ -66,14 +67,14 @@ public class TopChildrenQuery extends Query {
|
||||
private final int factor;
|
||||
private final int incrementalFactor;
|
||||
private Query originalChildQuery;
|
||||
private final Filter nonNestedDocsFilter;
|
||||
private final FixedBitSetFilter nonNestedDocsFilter;
|
||||
|
||||
// This field will hold the rewritten form of originalChildQuery, so that we can reuse it
|
||||
private Query rewrittenChildQuery;
|
||||
private IndexReader rewriteIndexReader;
|
||||
|
||||
// Note, the query is expected to already be filtered to only child type docs
|
||||
public TopChildrenQuery(IndexParentChildFieldData parentChildIndexFieldData, Query childQuery, String childType, String parentType, ScoreType scoreType, int factor, int incrementalFactor, Filter nonNestedDocsFilter) {
|
||||
public TopChildrenQuery(IndexParentChildFieldData parentChildIndexFieldData, Query childQuery, String childType, String parentType, ScoreType scoreType, int factor, int incrementalFactor, FixedBitSetFilter nonNestedDocsFilter) {
|
||||
this.parentChildIndexFieldData = parentChildIndexFieldData;
|
||||
this.originalChildQuery = childQuery;
|
||||
this.childType = childType;
|
||||
|
@ -29,6 +29,7 @@ import org.elasticsearch.index.aliases.IndexAliasesService;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.cache.IndexCache;
|
||||
import org.elasticsearch.index.engine.IndexEngine;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldDataService;
|
||||
import org.elasticsearch.index.gateway.IndexGateway;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
@ -51,6 +52,8 @@ public interface IndexService extends IndexComponent, Iterable<IndexShard> {
|
||||
|
||||
IndexFieldDataService fieldData();
|
||||
|
||||
FixedBitSetFilterCache fixedBitSetFilterCache();
|
||||
|
||||
IndexSettingsService settingsService();
|
||||
|
||||
AnalysisService analysisService();
|
||||
|
@ -54,6 +54,8 @@ import org.elasticsearch.index.merge.scheduler.MergeSchedulerProvider;
|
||||
import org.elasticsearch.index.percolator.PercolatorQueriesRegistry;
|
||||
import org.elasticsearch.index.percolator.PercolatorShardModule;
|
||||
import org.elasticsearch.index.query.IndexQueryParserService;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache;
|
||||
import org.elasticsearch.index.cache.fixedbitset.ShardFixedBitSetFilterCacheModule;
|
||||
import org.elasticsearch.index.search.stats.ShardSearchModule;
|
||||
import org.elasticsearch.index.settings.IndexSettings;
|
||||
import org.elasticsearch.index.settings.IndexSettingsService;
|
||||
@ -115,6 +117,8 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
|
||||
|
||||
private final IndexFieldDataService indexFieldData;
|
||||
|
||||
private final FixedBitSetFilterCache fixedBitSetFilterCache;
|
||||
|
||||
private final IndexEngine indexEngine;
|
||||
|
||||
private final IndexGateway indexGateway;
|
||||
@ -133,7 +137,8 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
|
||||
public InternalIndexService(Injector injector, Index index, @IndexSettings Settings indexSettings, NodeEnvironment nodeEnv, ThreadPool threadPool,
|
||||
AnalysisService analysisService, MapperService mapperService, IndexQueryParserService queryParserService,
|
||||
SimilarityService similarityService, IndexAliasesService aliasesService, IndexCache indexCache, IndexEngine indexEngine,
|
||||
IndexGateway indexGateway, IndexStore indexStore, IndexSettingsService settingsService, IndexFieldDataService indexFieldData) {
|
||||
IndexGateway indexGateway, IndexStore indexStore, IndexSettingsService settingsService, IndexFieldDataService indexFieldData,
|
||||
FixedBitSetFilterCache fixedBitSetFilterCache) {
|
||||
super(index, indexSettings);
|
||||
this.injector = injector;
|
||||
this.threadPool = threadPool;
|
||||
@ -149,6 +154,7 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
|
||||
this.indexGateway = indexGateway;
|
||||
this.indexStore = indexStore;
|
||||
this.settingsService = settingsService;
|
||||
this.fixedBitSetFilterCache = fixedBitSetFilterCache;
|
||||
|
||||
this.pluginsService = injector.getInstance(PluginsService.class);
|
||||
this.indicesLifecycle = (InternalIndicesLifecycle) injector.getInstance(IndicesLifecycle.class);
|
||||
@ -156,6 +162,7 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
|
||||
// inject workarounds for cyclic dep
|
||||
indexCache.filter().setIndexService(this);
|
||||
indexFieldData.setIndexService(this);
|
||||
fixedBitSetFilterCache.setIndexService(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -222,6 +229,11 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
|
||||
return indexFieldData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FixedBitSetFilterCache fixedBitSetFilterCache() {
|
||||
return fixedBitSetFilterCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnalysisService analysisService() {
|
||||
return this.analysisService;
|
||||
@ -331,6 +343,7 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
|
||||
modules.add(new MergeSchedulerModule(indexSettings));
|
||||
modules.add(new ShardFilterCacheModule());
|
||||
modules.add(new ShardQueryCacheModule());
|
||||
modules.add(new ShardFixedBitSetFilterCacheModule());
|
||||
modules.add(new ShardFieldDataModule());
|
||||
modules.add(new TranslogModule(indexSettings));
|
||||
modules.add(new EngineModule(indexSettings));
|
||||
|
@ -46,6 +46,7 @@ import org.elasticsearch.index.mapper.SourceToParse;
|
||||
import org.elasticsearch.index.merge.MergeStats;
|
||||
import org.elasticsearch.index.percolator.PercolatorQueriesRegistry;
|
||||
import org.elasticsearch.index.percolator.stats.ShardPercolateService;
|
||||
import org.elasticsearch.index.cache.fixedbitset.ShardFixedBitSetFilterCache;
|
||||
import org.elasticsearch.index.refresh.RefreshStats;
|
||||
import org.elasticsearch.index.search.stats.SearchStats;
|
||||
import org.elasticsearch.index.search.stats.ShardSearchService;
|
||||
@ -129,6 +130,8 @@ public interface IndexShard extends IndexShardComponent {
|
||||
|
||||
ShardSuggestService shardSuggestService();
|
||||
|
||||
ShardFixedBitSetFilterCache shardFixedBitSetFilterCache();
|
||||
|
||||
MapperService mapperService();
|
||||
|
||||
IndexFieldDataService indexFieldDataService();
|
||||
|
@ -29,7 +29,6 @@ import org.apache.lucene.util.ThreadInterruptedException;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
import org.elasticsearch.ElasticsearchIllegalStateException;
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.cluster.routing.ShardRouting;
|
||||
import org.elasticsearch.cluster.routing.ShardRoutingState;
|
||||
import org.elasticsearch.common.Booleans;
|
||||
@ -69,6 +68,7 @@ import org.elasticsearch.index.merge.scheduler.MergeSchedulerProvider;
|
||||
import org.elasticsearch.index.percolator.PercolatorQueriesRegistry;
|
||||
import org.elasticsearch.index.percolator.stats.ShardPercolateService;
|
||||
import org.elasticsearch.index.query.IndexQueryParserService;
|
||||
import org.elasticsearch.index.cache.fixedbitset.ShardFixedBitSetFilterCache;
|
||||
import org.elasticsearch.index.refresh.RefreshStats;
|
||||
import org.elasticsearch.index.search.nested.NonNestedDocsFilter;
|
||||
import org.elasticsearch.index.search.stats.SearchStats;
|
||||
@ -131,6 +131,7 @@ public class InternalIndexShard extends AbstractIndexShardComponent implements I
|
||||
private final IndexFieldDataService indexFieldDataService;
|
||||
private final IndexService indexService;
|
||||
private final ShardSuggestService shardSuggestService;
|
||||
private final ShardFixedBitSetFilterCache shardFixedBitSetFilterCache;
|
||||
|
||||
private final Object mutex = new Object();
|
||||
private final String checkIndexOnStartup;
|
||||
@ -155,7 +156,7 @@ public class InternalIndexShard extends AbstractIndexShardComponent implements I
|
||||
public InternalIndexShard(ShardId shardId, @IndexSettings Settings indexSettings, IndexSettingsService indexSettingsService, IndicesLifecycle indicesLifecycle, Store store, Engine engine, MergeSchedulerProvider mergeScheduler, Translog translog,
|
||||
ThreadPool threadPool, MapperService mapperService, IndexQueryParserService queryParserService, IndexCache indexCache, IndexAliasesService indexAliasesService, ShardIndexingService indexingService, ShardGetService getService, ShardSearchService searchService, ShardIndexWarmerService shardWarmerService,
|
||||
ShardFilterCache shardFilterCache, ShardFieldData shardFieldData, PercolatorQueriesRegistry percolatorQueriesRegistry, ShardPercolateService shardPercolateService, CodecService codecService,
|
||||
ShardTermVectorService termVectorService, IndexFieldDataService indexFieldDataService, IndexService indexService, ShardSuggestService shardSuggestService, ShardQueryCache shardQueryCache) {
|
||||
ShardTermVectorService termVectorService, IndexFieldDataService indexFieldDataService, IndexService indexService, ShardSuggestService shardSuggestService, ShardQueryCache shardQueryCache, ShardFixedBitSetFilterCache shardFixedBitSetFilterCache) {
|
||||
super(shardId, indexSettings);
|
||||
this.indicesLifecycle = (InternalIndicesLifecycle) indicesLifecycle;
|
||||
this.indexSettingsService = indexSettingsService;
|
||||
@ -182,6 +183,7 @@ public class InternalIndexShard extends AbstractIndexShardComponent implements I
|
||||
this.indexService = indexService;
|
||||
this.codecService = codecService;
|
||||
this.shardSuggestService = shardSuggestService;
|
||||
this.shardFixedBitSetFilterCache = shardFixedBitSetFilterCache;
|
||||
state = IndexShardState.CREATED;
|
||||
|
||||
this.refreshInterval = indexSettings.getAsTime(INDEX_REFRESH_INTERVAL, engine.defaultRefreshInterval());
|
||||
@ -229,6 +231,11 @@ public class InternalIndexShard extends AbstractIndexShardComponent implements I
|
||||
return shardSuggestService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShardFixedBitSetFilterCache shardFixedBitSetFilterCache() {
|
||||
return shardFixedBitSetFilterCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexFieldDataService indexFieldDataService() {
|
||||
return indexFieldDataService;
|
||||
@ -544,7 +551,9 @@ public class InternalIndexShard extends AbstractIndexShardComponent implements I
|
||||
|
||||
@Override
|
||||
public SegmentsStats segmentStats() {
|
||||
return engine.segmentsStats();
|
||||
SegmentsStats segmentsStats = engine.segmentsStats();
|
||||
segmentsStats.addFixedBitSetMemoryInBytes(shardFixedBitSetFilterCache.getMemorySizeInBytes());
|
||||
return segmentsStats;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -34,6 +34,7 @@ import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.cache.docset.DocSetCache;
|
||||
import org.elasticsearch.index.cache.filter.FilterCache;
|
||||
import org.elasticsearch.index.engine.Engine;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldDataService;
|
||||
import org.elasticsearch.index.fieldvisitor.JustSourceFieldsVisitor;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
@ -449,6 +450,11 @@ public class PercolateContext extends SearchContext {
|
||||
return indexService.cache().filter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FixedBitSetFilterCache fixedBitSetFilterCache() {
|
||||
return indexService.fixedBitSetFilterCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocSetCache docSetCache() {
|
||||
return indexService.cache().docSet();
|
||||
|
@ -261,6 +261,9 @@ public class RestIndicesAction extends AbstractCatAction {
|
||||
table.addCell("segments.version_map_memory", "sibling:pri;alias:svmm,segmentsVersionMapMemory;default:false;text-align:right;desc:memory used by version map");
|
||||
table.addCell("pri.segments.version_map_memory", "default:false;text-align:right;desc:memory used by version map");
|
||||
|
||||
table.addCell("segments.fixed_bitset_memory", "sibling:pri;alias:sfbm,fixedBitsetMemory;default:false;text-align:right;desc:memory used by fixed bit sets for nested object field types and type filters for types referred in _parent fields");
|
||||
table.addCell("pri.segments.fixed_bitset_memory", "default:false;text-align:right;desc:memory used by fixed bit sets for nested object field types and type filters for types referred in _parent fields");
|
||||
|
||||
table.addCell("warmer.current", "sibling:pri;alias:wc,warmerCurrent;default:false;text-align:right;desc:current warmer ops");
|
||||
table.addCell("pri.warmer.current", "default:false;text-align:right;desc:current warmer ops");
|
||||
|
||||
@ -455,6 +458,9 @@ public class RestIndicesAction extends AbstractCatAction {
|
||||
table.addCell(indexStats == null ? null : indexStats.getTotal().getSegments().getVersionMapMemory());
|
||||
table.addCell(indexStats == null ? null : indexStats.getPrimaries().getSegments().getVersionMapMemory());
|
||||
|
||||
table.addCell(indexStats == null ? null : indexStats.getTotal().getSegments().getFixedBitSetMemory());
|
||||
table.addCell(indexStats == null ? null : indexStats.getPrimaries().getSegments().getFixedBitSetMemory());
|
||||
|
||||
table.addCell(indexStats == null ? null : indexStats.getTotal().getWarmer().current());
|
||||
table.addCell(indexStats == null ? null : indexStats.getPrimaries().getWarmer().current());
|
||||
|
||||
|
@ -177,6 +177,7 @@ public class RestNodesAction extends AbstractCatAction {
|
||||
table.addCell("segments.index_writer_memory", "alias:siwm,segmentsIndexWriterMemory;default:false;text-align:right;desc:memory used by index writer");
|
||||
table.addCell("segments.index_writer_max_memory", "alias:siwmx,segmentsIndexWriterMaxMemory;default:false;text-align:right;desc:maximum memory index writer may use before it must write buffered documents to a new segment");
|
||||
table.addCell("segments.version_map_memory", "alias:svmm,segmentsVersionMapMemory;default:false;text-align:right;desc:memory used by version map");
|
||||
table.addCell("segments.fixed_bitset_memory", "alias:sfbm,fixedBitsetMemory;default:false;text-align:right;desc:memory used by fixed bit sets for nested object field types and type filters for types referred in _parent fields");
|
||||
|
||||
table.addCell("suggest.current", "alias:suc,suggestCurrent;default:false;text-align:right;desc:number of current suggest ops");
|
||||
table.addCell("suggest.time", "alias:suti,suggestTime;default:false;text-align:right;desc:time spend in suggest");
|
||||
@ -287,6 +288,7 @@ public class RestNodesAction extends AbstractCatAction {
|
||||
table.addCell(stats == null ? null : stats.getIndices().getSegments().getIndexWriterMemory());
|
||||
table.addCell(stats == null ? null : stats.getIndices().getSegments().getIndexWriterMaxMemory());
|
||||
table.addCell(stats == null ? null : stats.getIndices().getSegments().getVersionMapMemory());
|
||||
table.addCell(stats == null ? null : stats.getIndices().getSegments().getFixedBitSetMemory());
|
||||
|
||||
table.addCell(stats == null ? null : stats.getIndices().getSuggest().getCurrent());
|
||||
table.addCell(stats == null ? null : stats.getIndices().getSuggest().getTime());
|
||||
|
@ -148,6 +148,7 @@ public class RestShardsAction extends AbstractCatAction {
|
||||
table.addCell("segments.index_writer_memory", "alias:siwm,segmentsIndexWriterMemory;default:false;text-align:right;desc:memory used by index writer");
|
||||
table.addCell("segments.index_writer_max_memory", "alias:siwmx,segmentsIndexWriterMaxMemory;default:false;text-align:right;desc:maximum memory index writer may use before it must write buffered documents to a new segment");
|
||||
table.addCell("segments.version_map_memory", "alias:svmm,segmentsVersionMapMemory;default:false;text-align:right;desc:memory used by version map");
|
||||
table.addCell("segments.fixed_bitset_memory", "alias:sfbm,fixedBitsetMemory;default:false;text-align:right;desc:memory used by fixed bit sets for nested object field types and type filters for types referred in _parent fields");
|
||||
|
||||
table.addCell("warmer.current", "alias:wc,warmerCurrent;default:false;text-align:right;desc:current warmer ops");
|
||||
table.addCell("warmer.total", "alias:wto,warmerTotal;default:false;text-align:right;desc:total warmer ops");
|
||||
@ -248,6 +249,7 @@ public class RestShardsAction extends AbstractCatAction {
|
||||
table.addCell(shardStats == null ? null : shardStats.getSegments().getIndexWriterMemory());
|
||||
table.addCell(shardStats == null ? null : shardStats.getSegments().getIndexWriterMaxMemory());
|
||||
table.addCell(shardStats == null ? null : shardStats.getSegments().getVersionMapMemory());
|
||||
table.addCell(shardStats == null ? null : shardStats.getSegments().getFixedBitSetMemory());
|
||||
|
||||
table.addCell(shardStats == null ? null : shardStats.getWarmer().current());
|
||||
table.addCell(shardStats == null ? null : shardStats.getWarmer().total());
|
||||
|
@ -23,7 +23,6 @@ import org.apache.lucene.index.SortedDocValues;
|
||||
import org.apache.lucene.search.DocIdSet;
|
||||
import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.join.FixedBitSetCachingWrapperFilter;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.elasticsearch.ElasticsearchIllegalStateException;
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
@ -32,6 +31,7 @@ import org.elasticsearch.common.lucene.ReaderContextAware;
|
||||
import org.elasticsearch.common.lucene.docset.DocIdSets;
|
||||
import org.elasticsearch.common.util.LongArray;
|
||||
import org.elasticsearch.common.util.LongObjectPagedHashMap;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.search.child.ConstantScorer;
|
||||
import org.elasticsearch.search.aggregations.Aggregator;
|
||||
import org.elasticsearch.search.aggregations.AggregatorFactories;
|
||||
@ -52,8 +52,8 @@ import java.util.List;
|
||||
public class ParentToChildrenAggregator extends SingleBucketAggregator implements ReaderContextAware {
|
||||
|
||||
private final String parentType;
|
||||
private final Filter childFilter;
|
||||
private final Filter parentFilter;
|
||||
private final FixedBitSetFilter childFilter;
|
||||
private final FixedBitSetFilter parentFilter;
|
||||
private final ValuesSource.Bytes.WithOrdinals.ParentChild valuesSource;
|
||||
|
||||
// Maybe use PagedGrowableWriter? This will be less wasteful than LongArray, but then we don't have the reuse feature of BigArrays.
|
||||
@ -75,9 +75,8 @@ public class ParentToChildrenAggregator extends SingleBucketAggregator implement
|
||||
ValuesSource.Bytes.WithOrdinals.ParentChild valuesSource, long maxOrd) {
|
||||
super(name, factories, aggregationContext, parent);
|
||||
this.parentType = parentType;
|
||||
this.childFilter = childFilter;
|
||||
// TODO: remove FixedBitSetCachingWrapperFilter once #7031 gets in
|
||||
this.parentFilter = new FixedBitSetCachingWrapperFilter(parentFilter);
|
||||
this.childFilter = aggregationContext.searchContext().fixedBitSetFilterCache().getFixedBitSetFilter(childFilter);
|
||||
this.parentFilter = aggregationContext.searchContext().fixedBitSetFilterCache().getFixedBitSetFilter(parentFilter);
|
||||
this.parentOrdToBuckets = aggregationContext.bigArrays().newLongArray(maxOrd, false);
|
||||
this.parentOrdToBuckets.fill(0, maxOrd, -1);
|
||||
this.parentOrdToOtherBuckets = new LongObjectPagedHashMap<>(aggregationContext.bigArrays());
|
||||
|
@ -21,11 +21,11 @@ package org.elasticsearch.search.aggregations.bucket.nested;
|
||||
import org.apache.lucene.index.AtomicReaderContext;
|
||||
import org.apache.lucene.search.DocIdSet;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.join.FixedBitSetCachingWrapperFilter;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.FixedBitSet;
|
||||
import org.elasticsearch.common.lucene.ReaderContextAware;
|
||||
import org.elasticsearch.common.lucene.docset.DocIdSets;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.mapper.object.ObjectMapper;
|
||||
import org.elasticsearch.index.search.nested.NonNestedDocsFilter;
|
||||
@ -43,8 +43,8 @@ public class NestedAggregator extends SingleBucketAggregator implements ReaderCo
|
||||
|
||||
private final String nestedPath;
|
||||
private final Aggregator parentAggregator;
|
||||
private Filter parentFilter;
|
||||
private final Filter childFilter;
|
||||
private FixedBitSetFilter parentFilter;
|
||||
private final FixedBitSetFilter childFilter;
|
||||
|
||||
private Bits childDocs;
|
||||
private FixedBitSet parentDocs;
|
||||
@ -65,7 +65,7 @@ public class NestedAggregator extends SingleBucketAggregator implements ReaderCo
|
||||
throw new AggregationExecutionException("[nested] nested path [" + nestedPath + "] is not nested");
|
||||
}
|
||||
|
||||
childFilter = aggregationContext.searchContext().filterCache().cache(objectMapper.nestedTypeFilter());
|
||||
childFilter = aggregationContext.searchContext().fixedBitSetFilterCache().getFixedBitSetFilter(objectMapper.nestedTypeFilter());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -79,9 +79,7 @@ public class NestedAggregator extends SingleBucketAggregator implements ReaderCo
|
||||
if (parentFilterNotCached == null) {
|
||||
parentFilterNotCached = NonNestedDocsFilter.INSTANCE;
|
||||
}
|
||||
parentFilter = SearchContext.current().filterCache().cache(parentFilterNotCached);
|
||||
// if the filter cache is disabled, we still need to produce bit sets
|
||||
parentFilter = new FixedBitSetCachingWrapperFilter(parentFilter);
|
||||
parentFilter = SearchContext.current().fixedBitSetFilterCache().getFixedBitSetFilter(parentFilterNotCached);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -25,6 +25,7 @@ import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.elasticsearch.common.lucene.ReaderContextAware;
|
||||
import org.elasticsearch.common.lucene.docset.DocIdSets;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.mapper.object.ObjectMapper;
|
||||
import org.elasticsearch.index.search.nested.NonNestedDocsFilter;
|
||||
@ -41,7 +42,7 @@ import java.io.IOException;
|
||||
*/
|
||||
public class ReverseNestedAggregator extends SingleBucketAggregator implements ReaderContextAware {
|
||||
|
||||
private final Filter parentFilter;
|
||||
private final FixedBitSetFilter parentFilter;
|
||||
private DocIdSetIterator parentDocs;
|
||||
|
||||
// TODO: Add LongIntPagedHashMap?
|
||||
@ -56,7 +57,7 @@ public class ReverseNestedAggregator extends SingleBucketAggregator implements R
|
||||
throw new SearchParseException(context.searchContext(), "Reverse nested aggregation [" + name + "] can only be used inside a [nested] aggregation");
|
||||
}
|
||||
if (nestedPath == null) {
|
||||
parentFilter = SearchContext.current().filterCache().cache(NonNestedDocsFilter.INSTANCE);
|
||||
parentFilter = SearchContext.current().fixedBitSetFilterCache().getFixedBitSetFilter(NonNestedDocsFilter.INSTANCE);
|
||||
} else {
|
||||
MapperService.SmartNameObjectMapper mapper = SearchContext.current().smartNameObjectMapper(nestedPath);
|
||||
if (mapper == null) {
|
||||
@ -69,7 +70,7 @@ public class ReverseNestedAggregator extends SingleBucketAggregator implements R
|
||||
if (!objectMapper.nested().isNested()) {
|
||||
throw new AggregationExecutionException("[reverse_nested] nested path [" + nestedPath + "] is not nested");
|
||||
}
|
||||
parentFilter = SearchContext.current().filterCache().cache(objectMapper.nestedTypeFilter());
|
||||
parentFilter = SearchContext.current().fixedBitSetFilterCache().getFixedBitSetFilter(objectMapper.nestedTypeFilter());
|
||||
}
|
||||
bucketOrdToLastCollectedParentDoc = new LongIntOpenHashMap(32);
|
||||
aggregationContext.ensureScoreDocsInOrder();
|
||||
|
@ -30,6 +30,7 @@ import org.elasticsearch.common.util.BigArrays;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.cache.docset.DocSetCache;
|
||||
import org.elasticsearch.index.cache.filter.FilterCache;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldDataService;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.mapper.FieldMappers;
|
||||
@ -330,6 +331,11 @@ public class TopHitsContext extends SearchContext {
|
||||
return context.filterCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FixedBitSetFilterCache fixedBitSetFilterCache() {
|
||||
return context.fixedBitSetFilterCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocSetCache docSetCache() {
|
||||
return context.docSetCache();
|
||||
|
@ -41,6 +41,7 @@ import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.cache.docset.DocSetCache;
|
||||
import org.elasticsearch.index.cache.filter.FilterCache;
|
||||
import org.elasticsearch.index.engine.Engine;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldDataService;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.mapper.FieldMappers;
|
||||
@ -439,6 +440,11 @@ public class DefaultSearchContext extends SearchContext {
|
||||
return indexService.cache().filter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FixedBitSetFilterCache fixedBitSetFilterCache() {
|
||||
return indexService.fixedBitSetFilterCache();
|
||||
}
|
||||
|
||||
public DocSetCache docSetCache() {
|
||||
return indexService.cache().docSet();
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import org.elasticsearch.common.util.BigArrays;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.cache.docset.DocSetCache;
|
||||
import org.elasticsearch.index.cache.filter.FilterCache;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldDataService;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.mapper.FieldMappers;
|
||||
@ -208,6 +209,8 @@ public abstract class SearchContext implements Releasable {
|
||||
|
||||
public abstract FilterCache filterCache();
|
||||
|
||||
public abstract FixedBitSetFilterCache fixedBitSetFilterCache();
|
||||
|
||||
public abstract DocSetCache docSetCache();
|
||||
|
||||
public abstract IndexFieldDataService fieldData();
|
||||
|
@ -33,6 +33,7 @@ import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.geo.GeoUtils;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.*;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
@ -155,12 +156,12 @@ public class GeoDistanceSortParser implements SortParser {
|
||||
}
|
||||
final Nested nested;
|
||||
if (objectMapper != null && objectMapper.nested().isNested()) {
|
||||
Filter rootDocumentsFilter = context.filterCache().cache(NonNestedDocsFilter.INSTANCE);
|
||||
Filter innerDocumentsFilter;
|
||||
FixedBitSetFilter rootDocumentsFilter = context.fixedBitSetFilterCache().getFixedBitSetFilter(NonNestedDocsFilter.INSTANCE);
|
||||
FixedBitSetFilter innerDocumentsFilter;
|
||||
if (nestedFilter != null) {
|
||||
innerDocumentsFilter = context.filterCache().cache(nestedFilter);
|
||||
innerDocumentsFilter = context.fixedBitSetFilterCache().getFixedBitSetFilter(nestedFilter);
|
||||
} else {
|
||||
innerDocumentsFilter = context.filterCache().cache(objectMapper.nestedTypeFilter());
|
||||
innerDocumentsFilter = context.fixedBitSetFilterCache().getFixedBitSetFilter(objectMapper.nestedTypeFilter());
|
||||
}
|
||||
nested = new Nested(rootDocumentsFilter, innerDocumentsFilter);
|
||||
} else {
|
||||
|
@ -27,6 +27,7 @@ import org.apache.lucene.search.SortField;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.*;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
|
||||
@ -135,12 +136,12 @@ public class ScriptSortParser implements SortParser {
|
||||
throw new ElasticsearchIllegalArgumentException("mapping for explicit nested path is not mapped as nested: [" + nestedPath + "]");
|
||||
}
|
||||
|
||||
Filter rootDocumentsFilter = context.filterCache().cache(NonNestedDocsFilter.INSTANCE);
|
||||
Filter innerDocumentsFilter;
|
||||
FixedBitSetFilter rootDocumentsFilter = context.fixedBitSetFilterCache().getFixedBitSetFilter(NonNestedDocsFilter.INSTANCE);
|
||||
FixedBitSetFilter innerDocumentsFilter;
|
||||
if (nestedFilter != null) {
|
||||
innerDocumentsFilter = context.filterCache().cache(nestedFilter);
|
||||
innerDocumentsFilter = context.fixedBitSetFilterCache().getFixedBitSetFilter(nestedFilter);
|
||||
} else {
|
||||
innerDocumentsFilter = context.filterCache().cache(objectMapper.nestedTypeFilter());
|
||||
innerDocumentsFilter = context.fixedBitSetFilterCache().getFixedBitSetFilter(objectMapper.nestedTypeFilter());
|
||||
}
|
||||
nested = new Nested(rootDocumentsFilter, innerDocumentsFilter);
|
||||
} else {
|
||||
|
@ -28,6 +28,7 @@ import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
@ -247,12 +248,12 @@ public class SortParseElement implements SearchParseElement {
|
||||
}
|
||||
final Nested nested;
|
||||
if (objectMapper != null && objectMapper.nested().isNested()) {
|
||||
Filter rootDocumentsFilter = context.filterCache().cache(NonNestedDocsFilter.INSTANCE);
|
||||
Filter innerDocumentsFilter;
|
||||
FixedBitSetFilter rootDocumentsFilter = context.fixedBitSetFilterCache().getFixedBitSetFilter(NonNestedDocsFilter.INSTANCE);
|
||||
FixedBitSetFilter innerDocumentsFilter;
|
||||
if (nestedFilter != null) {
|
||||
innerDocumentsFilter = context.filterCache().cache(nestedFilter);
|
||||
innerDocumentsFilter = context.fixedBitSetFilterCache().getFixedBitSetFilter(nestedFilter);
|
||||
} else {
|
||||
innerDocumentsFilter = context.filterCache().cache(objectMapper.nestedTypeFilter());
|
||||
innerDocumentsFilter = context.fixedBitSetFilterCache().getFixedBitSetFilter(objectMapper.nestedTypeFilter());
|
||||
}
|
||||
nested = new Nested(rootDocumentsFilter, innerDocumentsFilter);
|
||||
} else {
|
||||
|
99
src/test/java/org/elasticsearch/index/cache/fixedbitset/FixedBitSetFilterCacheTest.java
vendored
Normal file
99
src/test/java/org/elasticsearch/index/cache/fixedbitset/FixedBitSetFilterCacheTest.java
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch 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.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.cache.fixedbitset;
|
||||
|
||||
import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.StringField;
|
||||
import org.apache.lucene.index.*;
|
||||
import org.apache.lucene.queries.TermFilter;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.TopDocs;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
import org.elasticsearch.common.lucene.Lucene;
|
||||
import org.elasticsearch.common.lucene.search.XConstantScoreQuery;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class FixedBitSetFilterCacheTest extends ElasticsearchTestCase {
|
||||
|
||||
@Test
|
||||
public void testInvalidateEntries() throws Exception {
|
||||
IndexWriter writer = new IndexWriter(
|
||||
new RAMDirectory(),
|
||||
new IndexWriterConfig(Lucene.VERSION, new StandardAnalyzer(Lucene.VERSION)).setMergePolicy(new LogByteSizeMergePolicy())
|
||||
);
|
||||
Document document = new Document();
|
||||
document.add(new StringField("field", "value", Field.Store.NO));
|
||||
writer.addDocument(document);
|
||||
writer.commit();
|
||||
|
||||
document = new Document();
|
||||
document.add(new StringField("field", "value", Field.Store.NO));
|
||||
writer.addDocument(document);
|
||||
writer.commit();
|
||||
|
||||
document = new Document();
|
||||
document.add(new StringField("field", "value", Field.Store.NO));
|
||||
writer.addDocument(document);
|
||||
writer.commit();
|
||||
|
||||
IndexReader reader = DirectoryReader.open(writer, false);
|
||||
IndexSearcher searcher = new IndexSearcher(reader);
|
||||
|
||||
FixedBitSetFilterCache cache = new FixedBitSetFilterCache(new Index("test"), ImmutableSettings.EMPTY);
|
||||
FixedBitSetFilter filter = cache.getFixedBitSetFilter(new TermFilter(new Term("field", "value")));
|
||||
TopDocs docs = searcher.search(new XConstantScoreQuery(filter), 1);
|
||||
assertThat(docs.totalHits, equalTo(3));
|
||||
|
||||
// now cached
|
||||
docs = searcher.search(new XConstantScoreQuery(filter), 1);
|
||||
assertThat(docs.totalHits, equalTo(3));
|
||||
// There are 3 segments
|
||||
assertThat(cache.getLoadedFilters().size(), equalTo(3l));
|
||||
|
||||
writer.forceMerge(1);
|
||||
reader.close();
|
||||
reader = DirectoryReader.open(writer, false);
|
||||
searcher = new IndexSearcher(reader);
|
||||
|
||||
docs = searcher.search(new XConstantScoreQuery(filter), 1);
|
||||
assertThat(docs.totalHits, equalTo(3));
|
||||
|
||||
// now cached
|
||||
docs = searcher.search(new XConstantScoreQuery(filter), 1);
|
||||
assertThat(docs.totalHits, equalTo(3));
|
||||
// Only one segment now, so the size must be 1
|
||||
assertThat(cache.getLoadedFilters().size(), equalTo(1l));
|
||||
|
||||
reader.close();
|
||||
writer.close();
|
||||
// There is no reference from readers and writer to any segment in the test index, so the size in the fbs cache must be 0
|
||||
assertThat(cache.getLoadedFilters().size(), equalTo(0l));
|
||||
}
|
||||
|
||||
}
|
@ -21,19 +21,26 @@ package org.elasticsearch.index.fielddata;
|
||||
|
||||
import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
||||
import org.apache.lucene.index.*;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
|
||||
import org.elasticsearch.common.lucene.Lucene;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.mapper.*;
|
||||
import org.elasticsearch.index.mapper.ContentPath;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.mapper.Mapper.BuilderContext;
|
||||
import org.elasticsearch.index.mapper.MapperBuilders;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache;
|
||||
import org.elasticsearch.index.service.IndexService;
|
||||
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
|
||||
import org.elasticsearch.test.ElasticsearchSingleNodeTest;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import static org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||
|
||||
// we might wanna cut this over to LuceneTestCase
|
||||
@SuppressCodecs({"Lucene3x", "Lucene40", "Lucene41", "Lucene42", "Lucene45", "Lucene46"})
|
||||
// avoid codecs that do not support SortedNumerics, SortedSet, etc
|
||||
@ -115,4 +122,9 @@ public abstract class AbstractFieldDataTests extends ElasticsearchSingleNodeTest
|
||||
writer.close();
|
||||
}
|
||||
|
||||
protected Nested createNested(Filter parentFilter, Filter childFilter) {
|
||||
FixedBitSetFilterCache s = indexService.fixedBitSetFilterCache();
|
||||
return new Nested(s.getFixedBitSetFilter(parentFilter), s.getFixedBitSetFilter(childFilter));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ public abstract class AbstractStringFieldDataTests extends AbstractFieldDataImpl
|
||||
}
|
||||
Filter parentFilter = new TermFilter(new Term("type", "parent"));
|
||||
Filter childFilter = new NotFilter(parentFilter);
|
||||
Nested nested = new Nested(parentFilter, childFilter);
|
||||
Nested nested = createNested(parentFilter, childFilter);
|
||||
BytesRefFieldComparatorSource nestedComparatorSource = new BytesRefFieldComparatorSource(fieldData, missingValue, sortMode, nested);
|
||||
ToParentBlockJoinQuery query = new ToParentBlockJoinQuery(new XFilteredQuery(new MatchAllDocsQuery(), childFilter), new FixedBitSetCachingWrapperFilter(parentFilter), ScoreMode.None);
|
||||
Sort sort = new Sort(new SortField("text", nestedComparatorSource));
|
||||
|
@ -19,14 +19,12 @@
|
||||
|
||||
package org.elasticsearch.index.search.child;
|
||||
|
||||
import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.ScoreDoc;
|
||||
import org.apache.lucene.search.TopDocs;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.util.FixedBitSet;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
||||
import org.elasticsearch.common.compress.CompressedString;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.mapper.internal.UidFieldMapper;
|
||||
import org.elasticsearch.index.service.IndexService;
|
||||
@ -90,4 +88,9 @@ public abstract class AbstractChildTests extends ElasticsearchSingleNodeLuceneTe
|
||||
assertThat("actualHit.score != expectedHit.score", actualHit.score, equalTo(expectedHit.score));
|
||||
}
|
||||
}
|
||||
|
||||
static FixedBitSetFilter wrap(Filter filter) {
|
||||
return SearchContext.current().fixedBitSetFilterCache().getFixedBitSetFilter(filter);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import org.elasticsearch.common.lucene.search.NotFilter;
|
||||
import org.elasticsearch.common.lucene.search.XConstantScoreQuery;
|
||||
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||
import org.elasticsearch.index.engine.Engine;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
|
||||
import org.elasticsearch.index.mapper.Uid;
|
||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||
@ -75,8 +76,8 @@ public class ChildrenConstantScoreQueryTests extends AbstractChildTests {
|
||||
Query childQuery = new TermQuery(new Term("field", "value"));
|
||||
ParentFieldMapper parentFieldMapper = SearchContext.current().mapperService().documentMapper("child").parentFieldMapper();
|
||||
ParentChildIndexFieldData parentChildIndexFieldData = SearchContext.current().fieldData().getForField(parentFieldMapper);
|
||||
Filter parentFilter = new TermFilter(new Term(TypeFieldMapper.NAME, "parent"));
|
||||
Query query = new ChildrenConstantScoreQuery(parentChildIndexFieldData, childQuery, "parent", "child", parentFilter, 12, NonNestedDocsFilter.INSTANCE);
|
||||
FixedBitSetFilter parentFilter = wrap(new TermFilter(new Term(TypeFieldMapper.NAME, "parent")));
|
||||
Query query = new ChildrenConstantScoreQuery(parentChildIndexFieldData, childQuery, "parent", "child", parentFilter, 12, wrap(NonNestedDocsFilter.INSTANCE));
|
||||
QueryUtils.check(query);
|
||||
}
|
||||
|
||||
@ -108,7 +109,7 @@ public class ChildrenConstantScoreQueryTests extends AbstractChildTests {
|
||||
));
|
||||
|
||||
TermQuery childQuery = new TermQuery(new Term("field1", "value" + (1 + random().nextInt(3))));
|
||||
TermFilter parentFilter = new TermFilter(new Term(TypeFieldMapper.NAME, "parent"));
|
||||
FixedBitSetFilter parentFilter = wrap(new TermFilter(new Term(TypeFieldMapper.NAME, "parent")));
|
||||
int shortCircuitParentDocSet = random().nextInt(5);
|
||||
ParentFieldMapper parentFieldMapper = SearchContext.current().mapperService().documentMapper("child").parentFieldMapper();
|
||||
ParentChildIndexFieldData parentChildIndexFieldData = SearchContext.current().fieldData().getForField(parentFieldMapper);
|
||||
@ -203,19 +204,10 @@ public class ChildrenConstantScoreQueryTests extends AbstractChildTests {
|
||||
|
||||
ParentFieldMapper parentFieldMapper = SearchContext.current().mapperService().documentMapper("child").parentFieldMapper();
|
||||
ParentChildIndexFieldData parentChildIndexFieldData = SearchContext.current().fieldData().getForField(parentFieldMapper);
|
||||
Filter rawParentFilter = new TermFilter(new Term(TypeFieldMapper.NAME, "parent"));
|
||||
FixedBitSetFilter parentFilter = wrap(new TermFilter(new Term(TypeFieldMapper.NAME, "parent")));
|
||||
Filter rawFilterMe = new NotFilter(new TermFilter(new Term("filter", "me")));
|
||||
int max = numUniqueChildValues / 4;
|
||||
for (int i = 0; i < max; i++) {
|
||||
// Randomly pick a cached version: there is specific logic inside ChildrenQuery that deals with the fact
|
||||
// that deletes are applied at the top level when filters are cached.
|
||||
Filter parentFilter;
|
||||
if (random().nextBoolean()) {
|
||||
parentFilter = SearchContext.current().filterCache().cache(rawParentFilter);
|
||||
} else {
|
||||
parentFilter = rawParentFilter;
|
||||
}
|
||||
|
||||
// Using this in FQ, will invoke / test the Scorer#advance(..) and also let the Weight#scorer not get live docs as acceptedDocs
|
||||
Filter filterMe;
|
||||
if (random().nextBoolean()) {
|
||||
@ -255,7 +247,7 @@ public class ChildrenConstantScoreQueryTests extends AbstractChildTests {
|
||||
String childValue = childValues[random().nextInt(numUniqueChildValues)];
|
||||
TermQuery childQuery = new TermQuery(new Term("field1", childValue));
|
||||
int shortCircuitParentDocSet = random().nextInt(numParentDocs);
|
||||
Filter nonNestedDocsFilter = random().nextBoolean() ? NonNestedDocsFilter.INSTANCE : null;
|
||||
FixedBitSetFilter nonNestedDocsFilter = random().nextBoolean() ? wrap(NonNestedDocsFilter.INSTANCE) : null;
|
||||
Query query;
|
||||
if (random().nextBoolean()) {
|
||||
// Usage in HasChildQueryParser
|
||||
|
@ -36,6 +36,7 @@ import org.elasticsearch.common.lease.Releasables;
|
||||
import org.elasticsearch.common.lucene.search.NotFilter;
|
||||
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||
import org.elasticsearch.index.engine.Engine;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
|
||||
import org.elasticsearch.index.mapper.Uid;
|
||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||
@ -76,11 +77,11 @@ public class ChildrenQueryTests extends AbstractChildTests {
|
||||
ScoreType scoreType = ScoreType.values()[random().nextInt(ScoreType.values().length)];
|
||||
ParentFieldMapper parentFieldMapper = SearchContext.current().mapperService().documentMapper("child").parentFieldMapper();
|
||||
ParentChildIndexFieldData parentChildIndexFieldData = SearchContext.current().fieldData().getForField(parentFieldMapper);
|
||||
Filter parentFilter = new TermFilter(new Term(TypeFieldMapper.NAME, "parent"));
|
||||
FixedBitSetFilter parentFilter = wrap(new TermFilter(new Term(TypeFieldMapper.NAME, "parent")));
|
||||
int minChildren = random().nextInt(10);
|
||||
int maxChildren = scaledRandomIntBetween(minChildren, 10);
|
||||
Query query = new ChildrenQuery(parentChildIndexFieldData, "parent", "child", parentFilter, childQuery, scoreType, minChildren,
|
||||
maxChildren, 12, NonNestedDocsFilter.INSTANCE);
|
||||
maxChildren, 12, wrap(NonNestedDocsFilter.INSTANCE));
|
||||
QueryUtils.check(query);
|
||||
}
|
||||
|
||||
@ -167,19 +168,10 @@ public class ChildrenQueryTests extends AbstractChildTests {
|
||||
|
||||
ParentFieldMapper parentFieldMapper = SearchContext.current().mapperService().documentMapper("child").parentFieldMapper();
|
||||
ParentChildIndexFieldData parentChildIndexFieldData = SearchContext.current().fieldData().getForField(parentFieldMapper);
|
||||
Filter rawParentFilter = new TermFilter(new Term(TypeFieldMapper.NAME, "parent"));
|
||||
FixedBitSetFilter parentFilter = wrap(new TermFilter(new Term(TypeFieldMapper.NAME, "parent")));
|
||||
Filter rawFilterMe = new NotFilter(new TermFilter(new Term("filter", "me")));
|
||||
int max = numUniqueChildValues / 4;
|
||||
for (int i = 0; i < max; i++) {
|
||||
// Randomly pick a cached version: there is specific logic inside ChildrenQuery that deals with the fact
|
||||
// that deletes are applied at the top level when filters are cached.
|
||||
Filter parentFilter;
|
||||
if (random().nextBoolean()) {
|
||||
parentFilter = SearchContext.current().filterCache().cache(rawParentFilter);
|
||||
} else {
|
||||
parentFilter = rawParentFilter;
|
||||
}
|
||||
|
||||
// Using this in FQ, will invoke / test the Scorer#advance(..) and also let the Weight#scorer not get live docs as acceptedDocs
|
||||
Filter filterMe;
|
||||
if (random().nextBoolean()) {
|
||||
@ -220,7 +212,7 @@ public class ChildrenQueryTests extends AbstractChildTests {
|
||||
Query childQuery = new ConstantScoreQuery(new TermQuery(new Term("field1", childValue)));
|
||||
int shortCircuitParentDocSet = random().nextInt(numParentDocs);
|
||||
ScoreType scoreType = ScoreType.values()[random().nextInt(ScoreType.values().length)];
|
||||
Filter nonNestedDocsFilter = random().nextBoolean() ? NonNestedDocsFilter.INSTANCE : null;
|
||||
FixedBitSetFilter nonNestedDocsFilter = random().nextBoolean() ? wrap(NonNestedDocsFilter.INSTANCE) : null;
|
||||
|
||||
// leave min/max set to 0 half the time
|
||||
int minChildren = random().nextInt(2) * scaledRandomIntBetween(0, 110);
|
||||
|
@ -35,6 +35,7 @@ import org.elasticsearch.common.lucene.search.NotFilter;
|
||||
import org.elasticsearch.common.lucene.search.XConstantScoreQuery;
|
||||
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||
import org.elasticsearch.index.engine.Engine;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
|
||||
import org.elasticsearch.index.mapper.Uid;
|
||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||
@ -74,7 +75,7 @@ public class ParentConstantScoreQueryTests extends AbstractChildTests {
|
||||
Query parentQuery = new TermQuery(new Term("field", "value"));
|
||||
ParentFieldMapper parentFieldMapper = SearchContext.current().mapperService().documentMapper("child").parentFieldMapper();
|
||||
ParentChildIndexFieldData parentChildIndexFieldData = SearchContext.current().fieldData().getForField(parentFieldMapper);
|
||||
Filter childrenFilter = new TermFilter(new Term(TypeFieldMapper.NAME, "child"));
|
||||
FixedBitSetFilter childrenFilter = wrap(new TermFilter(new Term(TypeFieldMapper.NAME, "child")));
|
||||
Query query = new ParentConstantScoreQuery(parentChildIndexFieldData, parentQuery, "parent", childrenFilter);
|
||||
QueryUtils.check(query);
|
||||
}
|
||||
@ -161,19 +162,10 @@ public class ParentConstantScoreQueryTests extends AbstractChildTests {
|
||||
|
||||
ParentFieldMapper parentFieldMapper = SearchContext.current().mapperService().documentMapper("child").parentFieldMapper();
|
||||
ParentChildIndexFieldData parentChildIndexFieldData = SearchContext.current().fieldData().getForField(parentFieldMapper);
|
||||
TermFilter rawChildrenFilter = new TermFilter(new Term(TypeFieldMapper.NAME, "child"));
|
||||
FixedBitSetFilter childrenFilter = wrap(new TermFilter(new Term(TypeFieldMapper.NAME, "child")));
|
||||
Filter rawFilterMe = new NotFilter(new TermFilter(new Term("filter", "me")));
|
||||
int max = numUniqueParentValues / 4;
|
||||
for (int i = 0; i < max; i++) {
|
||||
// Randomly pick a cached version: there is specific logic inside ChildrenQuery that deals with the fact
|
||||
// that deletes are applied at the top level when filters are cached.
|
||||
Filter childrenFilter;
|
||||
if (random().nextBoolean()) {
|
||||
childrenFilter = SearchContext.current().filterCache().cache(rawChildrenFilter);
|
||||
} else {
|
||||
childrenFilter = rawChildrenFilter;
|
||||
}
|
||||
|
||||
// Using this in FQ, will invoke / test the Scorer#advance(..) and also let the Weight#scorer not get live docs as acceptedDocs
|
||||
Filter filterMe;
|
||||
if (random().nextBoolean()) {
|
||||
|
@ -35,6 +35,7 @@ import org.elasticsearch.common.lease.Releasables;
|
||||
import org.elasticsearch.common.lucene.search.NotFilter;
|
||||
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||
import org.elasticsearch.index.engine.Engine;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilter;
|
||||
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
|
||||
import org.elasticsearch.index.mapper.Uid;
|
||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||
@ -73,7 +74,7 @@ public class ParentQueryTests extends AbstractChildTests {
|
||||
Query parentQuery = new TermQuery(new Term("field", "value"));
|
||||
ParentFieldMapper parentFieldMapper = SearchContext.current().mapperService().documentMapper("child").parentFieldMapper();
|
||||
ParentChildIndexFieldData parentChildIndexFieldData = SearchContext.current().fieldData().getForField(parentFieldMapper);
|
||||
Filter childrenFilter = new TermFilter(new Term(TypeFieldMapper.NAME, "child"));
|
||||
FixedBitSetFilter childrenFilter = wrap(new TermFilter(new Term(TypeFieldMapper.NAME, "child")));
|
||||
Query query = new ParentQuery(parentChildIndexFieldData, parentQuery, "parent", childrenFilter);
|
||||
QueryUtils.check(query);
|
||||
}
|
||||
@ -160,19 +161,10 @@ public class ParentQueryTests extends AbstractChildTests {
|
||||
|
||||
ParentFieldMapper parentFieldMapper = SearchContext.current().mapperService().documentMapper("child").parentFieldMapper();
|
||||
ParentChildIndexFieldData parentChildIndexFieldData = SearchContext.current().fieldData().getForField(parentFieldMapper);
|
||||
TermFilter rawChildrenFilter = new TermFilter(new Term(TypeFieldMapper.NAME, "child"));
|
||||
FixedBitSetFilter childrenFilter = wrap(new TermFilter(new Term(TypeFieldMapper.NAME, "child")));
|
||||
Filter rawFilterMe = new NotFilter(new TermFilter(new Term("filter", "me")));
|
||||
int max = numUniqueParentValues / 4;
|
||||
for (int i = 0; i < max; i++) {
|
||||
// Randomly pick a cached version: there is specific logic inside ChildrenQuery that deals with the fact
|
||||
// that deletes are applied at the top level when filters are cached.
|
||||
Filter childrenFilter;
|
||||
if (random().nextBoolean()) {
|
||||
childrenFilter = SearchContext.current().filterCache().cache(rawChildrenFilter);
|
||||
} else {
|
||||
childrenFilter = rawChildrenFilter;
|
||||
}
|
||||
|
||||
// Using this in FQ, will invoke / test the Scorer#advance(..) and also let the Weight#scorer not get live docs as acceptedDocs
|
||||
Filter filterMe;
|
||||
if (random().nextBoolean()) {
|
||||
|
@ -57,7 +57,7 @@ public class TopChildrenQueryTests extends AbstractChildTests {
|
||||
ScoreType scoreType = ScoreType.values()[random().nextInt(ScoreType.values().length)];
|
||||
ParentFieldMapper parentFieldMapper = SearchContext.current().mapperService().documentMapper("child").parentFieldMapper();
|
||||
ParentChildIndexFieldData parentChildIndexFieldData = SearchContext.current().fieldData().getForField(parentFieldMapper);
|
||||
Query query = new TopChildrenQuery(parentChildIndexFieldData, childQuery, "child", "parent", scoreType, 1, 1, NonNestedDocsFilter.INSTANCE);
|
||||
Query query = new TopChildrenQuery(parentChildIndexFieldData, childQuery, "child", "parent", scoreType, 1, 1, wrap(NonNestedDocsFilter.INSTANCE));
|
||||
QueryUtils.check(query);
|
||||
}
|
||||
|
||||
|
@ -210,7 +210,7 @@ public abstract class AbstractNumberNestedSortingTests extends AbstractFieldData
|
||||
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(writer, false));
|
||||
Filter parentFilter = new TermFilter(new Term("__type", "parent"));
|
||||
Filter childFilter = new NotFilter(parentFilter);
|
||||
XFieldComparatorSource nestedComparatorSource = createFieldComparator("field2", sortMode, null, new Nested(parentFilter, childFilter));
|
||||
XFieldComparatorSource nestedComparatorSource = createFieldComparator("field2", sortMode, null, createNested(parentFilter, childFilter));
|
||||
ToParentBlockJoinQuery query = new ToParentBlockJoinQuery(new XFilteredQuery(new MatchAllDocsQuery(), childFilter), new FixedBitSetCachingWrapperFilter(parentFilter), ScoreMode.None);
|
||||
|
||||
Sort sort = new Sort(new SortField("field2", nestedComparatorSource));
|
||||
@ -244,7 +244,7 @@ public abstract class AbstractNumberNestedSortingTests extends AbstractFieldData
|
||||
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(9));
|
||||
|
||||
childFilter = new TermFilter(new Term("filter_1", "T"));
|
||||
nestedComparatorSource = createFieldComparator("field2", sortMode, null, new Nested(parentFilter, childFilter));
|
||||
nestedComparatorSource = createFieldComparator("field2", sortMode, null, createNested(parentFilter, childFilter));
|
||||
query = new ToParentBlockJoinQuery(
|
||||
new XFilteredQuery(new MatchAllDocsQuery(), childFilter),
|
||||
new FixedBitSetCachingWrapperFilter(parentFilter),
|
||||
@ -280,7 +280,7 @@ public abstract class AbstractNumberNestedSortingTests extends AbstractFieldData
|
||||
assertThat(topDocs.scoreDocs[4].doc, equalTo(3));
|
||||
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(9));
|
||||
|
||||
nestedComparatorSource = createFieldComparator("field2", sortMode, 127, new Nested(parentFilter, childFilter));
|
||||
nestedComparatorSource = createFieldComparator("field2", sortMode, 127, createNested(parentFilter, childFilter));
|
||||
sort = new Sort(new SortField("field2", nestedComparatorSource, true));
|
||||
topDocs = searcher.search(new TermQuery(new Term("__type", "parent")), 5, sort);
|
||||
assertThat(topDocs.totalHits, equalTo(8));
|
||||
@ -296,7 +296,7 @@ public abstract class AbstractNumberNestedSortingTests extends AbstractFieldData
|
||||
assertThat(topDocs.scoreDocs[4].doc, equalTo(7));
|
||||
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(8));
|
||||
|
||||
nestedComparatorSource = createFieldComparator("field2", sortMode, -127, new Nested(parentFilter, childFilter));
|
||||
nestedComparatorSource = createFieldComparator("field2", sortMode, -127, createNested(parentFilter, childFilter));
|
||||
sort = new Sort(new SortField("field2", nestedComparatorSource));
|
||||
topDocs = searcher.search(new TermQuery(new Term("__type", "parent")), 5, sort);
|
||||
assertThat(topDocs.totalHits, equalTo(8));
|
||||
@ -321,7 +321,7 @@ public abstract class AbstractNumberNestedSortingTests extends AbstractFieldData
|
||||
protected void assertAvgScoreMode(Filter parentFilter, IndexSearcher searcher) throws IOException {
|
||||
MultiValueMode sortMode = MultiValueMode.AVG;
|
||||
Filter childFilter = new NotFilter(parentFilter);
|
||||
XFieldComparatorSource nestedComparatorSource = createFieldComparator("field2", sortMode, -127, new Nested(parentFilter, childFilter));
|
||||
XFieldComparatorSource nestedComparatorSource = createFieldComparator("field2", sortMode, -127, createNested(parentFilter, childFilter));
|
||||
Query query = new ToParentBlockJoinQuery(new XFilteredQuery(new MatchAllDocsQuery(), childFilter), new FixedBitSetCachingWrapperFilter(parentFilter), ScoreMode.None);
|
||||
Sort sort = new Sort(new SortField("field2", nestedComparatorSource));
|
||||
TopDocs topDocs = searcher.search(query, 5, sort);
|
||||
|
@ -62,7 +62,7 @@ public class DoubleNestedSortingTests extends AbstractNumberNestedSortingTests {
|
||||
protected void assertAvgScoreMode(Filter parentFilter, IndexSearcher searcher) throws IOException {
|
||||
MultiValueMode sortMode = MultiValueMode.AVG;
|
||||
Filter childFilter = new NotFilter(parentFilter);
|
||||
XFieldComparatorSource nestedComparatorSource = createFieldComparator("field2", sortMode, -127, new Nested(parentFilter, childFilter));
|
||||
XFieldComparatorSource nestedComparatorSource = createFieldComparator("field2", sortMode, -127, createNested(parentFilter, childFilter));
|
||||
Query query = new ToParentBlockJoinQuery(new XFilteredQuery(new MatchAllDocsQuery(), childFilter), new FixedBitSetCachingWrapperFilter(parentFilter), ScoreMode.None);
|
||||
Sort sort = new Sort(new SortField("field2", nestedComparatorSource));
|
||||
TopDocs topDocs = searcher.search(query, 5, sort);
|
||||
|
@ -62,7 +62,7 @@ public class FloatNestedSortingTests extends DoubleNestedSortingTests {
|
||||
protected void assertAvgScoreMode(Filter parentFilter, IndexSearcher searcher, IndexFieldData.XFieldComparatorSource innerFieldComparator) throws IOException {
|
||||
MultiValueMode sortMode = MultiValueMode.AVG;
|
||||
Filter childFilter = new NotFilter(parentFilter);
|
||||
XFieldComparatorSource nestedComparatorSource = createFieldComparator("field2", sortMode, -127, new Nested(parentFilter, childFilter));
|
||||
XFieldComparatorSource nestedComparatorSource = createFieldComparator("field2", sortMode, -127, createNested(parentFilter, childFilter));
|
||||
Query query = new ToParentBlockJoinQuery(new XFilteredQuery(new MatchAllDocsQuery(), childFilter), new FixedBitSetCachingWrapperFilter(parentFilter), ScoreMode.None);
|
||||
Sort sort = new Sort(new SortField("field2", nestedComparatorSource));
|
||||
TopDocs topDocs = searcher.search(query, 5, sort);
|
||||
|
@ -35,9 +35,11 @@ import org.elasticsearch.common.lucene.search.AndFilter;
|
||||
import org.elasticsearch.common.lucene.search.NotFilter;
|
||||
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.index.fielddata.*;
|
||||
import org.elasticsearch.index.fielddata.AbstractFieldDataTests;
|
||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||
import org.elasticsearch.index.fielddata.NoOrdinalsStringFieldDataTests;
|
||||
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
|
||||
import org.elasticsearch.index.fielddata.plain.PagedBytesIndexFieldData;
|
||||
import org.elasticsearch.search.MultiValueMode;
|
||||
@ -107,7 +109,7 @@ public class NestedSortingTests extends AbstractFieldDataTests {
|
||||
private TopDocs getTopDocs(IndexSearcher searcher, IndexFieldData<?> indexFieldData, String missingValue, MultiValueMode sortMode, int n, boolean reverse) throws IOException {
|
||||
Filter parentFilter = new TermFilter(new Term("__type", "parent"));
|
||||
Filter childFilter = new TermFilter(new Term("__type", "child"));
|
||||
XFieldComparatorSource nestedComparatorSource = indexFieldData.comparatorSource(missingValue, sortMode, new Nested(parentFilter, childFilter));
|
||||
XFieldComparatorSource nestedComparatorSource = indexFieldData.comparatorSource(missingValue, sortMode, createNested(parentFilter, childFilter));
|
||||
Query query = new ConstantScoreQuery(parentFilter);
|
||||
Sort sort = new Sort(new SortField("f", nestedComparatorSource, reverse));
|
||||
return searcher.search(query, n, sort);
|
||||
@ -273,7 +275,7 @@ public class NestedSortingTests extends AbstractFieldDataTests {
|
||||
PagedBytesIndexFieldData indexFieldData = getForField("field2");
|
||||
Filter parentFilter = new TermFilter(new Term("__type", "parent"));
|
||||
Filter childFilter = new NotFilter(parentFilter);
|
||||
BytesRefFieldComparatorSource nestedComparatorSource = new BytesRefFieldComparatorSource(indexFieldData, null, sortMode, new Nested(parentFilter, childFilter));
|
||||
BytesRefFieldComparatorSource nestedComparatorSource = new BytesRefFieldComparatorSource(indexFieldData, null, sortMode, createNested(parentFilter, childFilter));
|
||||
ToParentBlockJoinQuery query = new ToParentBlockJoinQuery(new XFilteredQuery(new MatchAllDocsQuery(), childFilter), new FixedBitSetCachingWrapperFilter(parentFilter), ScoreMode.None);
|
||||
|
||||
Sort sort = new Sort(new SortField("field2", nestedComparatorSource));
|
||||
@ -292,7 +294,7 @@ public class NestedSortingTests extends AbstractFieldDataTests {
|
||||
assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).utf8ToString(), equalTo("i"));
|
||||
|
||||
sortMode = MultiValueMode.MAX;
|
||||
nestedComparatorSource = new BytesRefFieldComparatorSource(indexFieldData, null, sortMode, new Nested(parentFilter, childFilter));
|
||||
nestedComparatorSource = new BytesRefFieldComparatorSource(indexFieldData, null, sortMode, createNested(parentFilter, childFilter));
|
||||
sort = new Sort(new SortField("field2", nestedComparatorSource, true));
|
||||
topDocs = searcher.search(query, 5, sort);
|
||||
assertThat(topDocs.totalHits, equalTo(7));
|
||||
@ -310,7 +312,7 @@ public class NestedSortingTests extends AbstractFieldDataTests {
|
||||
|
||||
|
||||
childFilter = new AndFilter(Arrays.asList(new NotFilter(parentFilter), new TermFilter(new Term("filter_1", "T"))));
|
||||
nestedComparatorSource = new BytesRefFieldComparatorSource(indexFieldData, null, sortMode, new Nested(parentFilter, childFilter));
|
||||
nestedComparatorSource = new BytesRefFieldComparatorSource(indexFieldData, null, sortMode, createNested(parentFilter, childFilter));
|
||||
query = new ToParentBlockJoinQuery(
|
||||
new XFilteredQuery(new MatchAllDocsQuery(), childFilter),
|
||||
new FixedBitSetCachingWrapperFilter(parentFilter),
|
||||
|
@ -21,6 +21,7 @@ package org.elasticsearch.nested;
|
||||
|
||||
import org.apache.lucene.search.Explanation;
|
||||
import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus;
|
||||
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse;
|
||||
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
|
||||
import org.elasticsearch.action.delete.DeleteResponse;
|
||||
import org.elasticsearch.action.get.GetResponse;
|
||||
@ -29,6 +30,7 @@ import org.elasticsearch.action.search.SearchPhaseExecutionException;
|
||||
import org.elasticsearch.action.search.SearchRequestBuilder;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.action.search.SearchType;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.index.query.FilterBuilders;
|
||||
@ -1161,6 +1163,64 @@ public class SimpleNestedTests extends ElasticsearchIntegrationTest {
|
||||
assertThat(searchResponse.getHits().getHits()[2].sortValues()[0].toString(), equalTo("3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckFixedBitSetCache() throws Exception {
|
||||
boolean loadFixedBitSeLazily = randomBoolean();
|
||||
ImmutableSettings.Builder settingsBuilder = ImmutableSettings.builder().put(indexSettings())
|
||||
.put("index.refresh_interval", -1);
|
||||
if (loadFixedBitSeLazily) {
|
||||
settingsBuilder.put("index.load_fixed_bitset_filters_eagerly", false);
|
||||
}
|
||||
assertAcked(prepareCreate("test")
|
||||
.setSettings(settingsBuilder)
|
||||
.addMapping("type")
|
||||
);
|
||||
|
||||
client().prepareIndex("test", "type", "0").setSource("field", "value").get();
|
||||
client().prepareIndex("test", "type", "1").setSource("field", "value").get();
|
||||
refresh();
|
||||
ensureSearchable("test");
|
||||
|
||||
// No nested mapping yet, there shouldn't be anything in the fixed bit set cache
|
||||
ClusterStatsResponse clusterStatsResponse = client().admin().cluster().prepareClusterStats().get();
|
||||
assertThat(clusterStatsResponse.getIndicesStats().getSegments().getFixedBitSetMemoryInBytes(), equalTo(0l));
|
||||
|
||||
// Now add nested mapping
|
||||
assertAcked(
|
||||
client().admin().indices().preparePutMapping("test").setType("type").setSource("array1", "type=nested")
|
||||
);
|
||||
|
||||
XContentBuilder builder = jsonBuilder().startObject()
|
||||
.startArray("array1").startObject().field("field1", "value1").endObject().endArray()
|
||||
.endObject();
|
||||
// index simple data
|
||||
client().prepareIndex("test", "type", "2").setSource(builder).get();
|
||||
client().prepareIndex("test", "type", "3").setSource(builder).get();
|
||||
client().prepareIndex("test", "type", "4").setSource(builder).get();
|
||||
client().prepareIndex("test", "type", "5").setSource(builder).get();
|
||||
client().prepareIndex("test", "type", "6").setSource(builder).get();
|
||||
refresh();
|
||||
ensureSearchable("test");
|
||||
|
||||
if (loadFixedBitSeLazily) {
|
||||
clusterStatsResponse = client().admin().cluster().prepareClusterStats().get();
|
||||
assertThat(clusterStatsResponse.getIndicesStats().getSegments().getFixedBitSetMemoryInBytes(), equalTo(0l));
|
||||
|
||||
// only when querying with nested the fixed bitsets are loaded
|
||||
SearchResponse searchResponse = client().prepareSearch("test")
|
||||
.setQuery(nestedQuery("array1", termQuery("field1", "value1")))
|
||||
.get();
|
||||
assertNoFailures(searchResponse);
|
||||
assertThat(searchResponse.getHits().totalHits(), equalTo(5l));
|
||||
}
|
||||
clusterStatsResponse = client().admin().cluster().prepareClusterStats().get();
|
||||
assertThat(clusterStatsResponse.getIndicesStats().getSegments().getFixedBitSetMemoryInBytes(), greaterThan(0l));
|
||||
|
||||
assertAcked(client().admin().indices().prepareDelete("test"));
|
||||
clusterStatsResponse = client().admin().cluster().prepareClusterStats().get();
|
||||
assertThat(clusterStatsResponse.getIndicesStats().getSegments().getFixedBitSetMemoryInBytes(), equalTo(0l));
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
private void assertDocumentCount(String index, long numdocs) {
|
||||
|
@ -20,6 +20,7 @@ package org.elasticsearch.search.child;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse;
|
||||
import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
|
||||
@ -347,6 +348,63 @@ public class SimpleChildQuerySearchTests extends ElasticsearchIntegrationTest {
|
||||
assertThat(indicesStatsResponse.getTotal().getFieldData().getMemorySizeInBytes(), equalTo(0l));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckFixedBitSetCache() throws Exception {
|
||||
boolean loadFixedBitSetLazily = randomBoolean();
|
||||
ImmutableSettings.Builder settingsBuilder = ImmutableSettings.builder().put(indexSettings())
|
||||
.put("index.refresh_interval", -1);
|
||||
if (loadFixedBitSetLazily) {
|
||||
settingsBuilder.put("index.load_fixed_bitset_filters_eagerly", false);
|
||||
}
|
||||
// enforce lazy loading to make sure that p/c stats are not counted as part of field data
|
||||
assertAcked(prepareCreate("test")
|
||||
.setSettings(settingsBuilder)
|
||||
.addMapping("parent")
|
||||
);
|
||||
|
||||
client().prepareIndex("test", "parent", "p0").setSource("p_field", "p_value0").get();
|
||||
client().prepareIndex("test", "parent", "p1").setSource("p_field", "p_value1").get();
|
||||
refresh();
|
||||
ensureSearchable("test");
|
||||
|
||||
// No _parent field yet, there shouldn't be anything in the parent id cache
|
||||
ClusterStatsResponse clusterStatsResponse = client().admin().cluster().prepareClusterStats().get();
|
||||
assertThat(clusterStatsResponse.getIndicesStats().getSegments().getFixedBitSetMemoryInBytes(), equalTo(0l));
|
||||
|
||||
// Now add mapping + children
|
||||
assertAcked(
|
||||
client().admin().indices().preparePutMapping("test").setType("child").setSource("_parent", "type=parent")
|
||||
);
|
||||
|
||||
// index simple data
|
||||
client().prepareIndex("test", "child", "c1").setSource("c_field", "red").setParent("p1").get();
|
||||
client().prepareIndex("test", "child", "c2").setSource("c_field", "yellow").setParent("p1").get();
|
||||
client().prepareIndex("test", "parent", "p2").setSource("p_field", "p_value2").get();
|
||||
client().prepareIndex("test", "child", "c3").setSource("c_field", "blue").setParent("p2").get();
|
||||
client().prepareIndex("test", "child", "c4").setSource("c_field", "red").setParent("p2").get();
|
||||
refresh();
|
||||
ensureSearchable("test");
|
||||
|
||||
if (loadFixedBitSetLazily) {
|
||||
clusterStatsResponse = client().admin().cluster().prepareClusterStats().get();
|
||||
assertThat(clusterStatsResponse.getIndicesStats().getSegments().getFixedBitSetMemoryInBytes(), equalTo(0l));
|
||||
|
||||
// only when querying with has_child the fixed bitsets are loaded
|
||||
SearchResponse searchResponse = client().prepareSearch("test")
|
||||
// Use setShortCircuitCutoff(0), otherwise the parent filter isn't used.
|
||||
.setQuery(hasChildQuery("child", termQuery("c_field", "blue")).setShortCircuitCutoff(0))
|
||||
.get();
|
||||
assertNoFailures(searchResponse);
|
||||
assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
|
||||
}
|
||||
clusterStatsResponse = client().admin().cluster().prepareClusterStats().get();
|
||||
assertThat(clusterStatsResponse.getIndicesStats().getSegments().getFixedBitSetMemoryInBytes(), greaterThan(0l));
|
||||
|
||||
assertAcked(client().admin().indices().prepareDelete("test"));
|
||||
clusterStatsResponse = client().admin().cluster().prepareClusterStats().get();
|
||||
assertThat(clusterStatsResponse.getIndicesStats().getSegments().getFixedBitSetMemoryInBytes(), equalTo(0l));
|
||||
}
|
||||
|
||||
@Test
|
||||
// See: https://github.com/elasticsearch/elasticsearch/issues/3290
|
||||
public void testCachingBug_withFqueryFilter() throws Exception {
|
||||
@ -719,7 +777,7 @@ public class SimpleChildQuerySearchTests extends ElasticsearchIntegrationTest {
|
||||
client().prepareIndex("test", "child", "1").setParent("1").setSource("c_field", 1).get();
|
||||
client().admin().indices().prepareFlush("test").get();
|
||||
|
||||
client().prepareIndex("test", "type1", "1").setSource("p_field", "p_value1").get();
|
||||
client().prepareIndex("test", "type1", "1").setSource("p_field", 1).get();
|
||||
client().admin().indices().prepareFlush("test").get();
|
||||
|
||||
SearchResponse searchResponse = client().prepareSearch("test")
|
||||
|
@ -133,6 +133,7 @@ public final class ExternalTestCluster extends TestCluster {
|
||||
|
||||
assertThat("Fielddata size must be 0 on node: " + stats.getNode(), stats.getIndices().getFieldData().getMemorySizeInBytes(), equalTo(0l));
|
||||
assertThat("Filter cache size must be 0 on node: " + stats.getNode(), stats.getIndices().getFilterCache().getMemorySizeInBytes(), equalTo(0l));
|
||||
assertThat("FixedBitSet cache size must be 0 on node: " + stats.getNode(), stats.getIndices().getSegments().getFixedBitSetMemoryInBytes(), equalTo(0l));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1542,6 +1542,7 @@ public final class InternalTestCluster extends TestCluster {
|
||||
NodeStats stats = nodeService.stats(CommonStatsFlags.ALL, false, false, false, false, false, false, false, false, false);
|
||||
assertThat("Fielddata size must be 0 on node: " + stats.getNode(), stats.getIndices().getFieldData().getMemorySizeInBytes(), equalTo(0l));
|
||||
assertThat("Filter cache size must be 0 on node: " + stats.getNode(), stats.getIndices().getFilterCache().getMemorySizeInBytes(), equalTo(0l));
|
||||
assertThat("FixedBitSet cache size must be 0 on node: " + stats.getNode(), stats.getIndices().getSegments().getFixedBitSetMemoryInBytes(), equalTo(0l));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import org.elasticsearch.common.util.BigArrays;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.cache.docset.DocSetCache;
|
||||
import org.elasticsearch.index.cache.filter.FilterCache;
|
||||
import org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldDataService;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.mapper.FieldMappers;
|
||||
@ -69,6 +70,7 @@ public class TestSearchContext extends SearchContext {
|
||||
final IndexService indexService;
|
||||
final FilterCache filterCache;
|
||||
final IndexFieldDataService indexFieldDataService;
|
||||
final FixedBitSetFilterCache fixedBitSetFilterCache;
|
||||
final ThreadPool threadPool;
|
||||
|
||||
ContextIndexSearcher searcher;
|
||||
@ -80,8 +82,9 @@ public class TestSearchContext extends SearchContext {
|
||||
this.pageCacheRecycler = pageCacheRecycler;
|
||||
this.bigArrays = bigArrays.withCircuitBreaking();
|
||||
this.indexService = indexService;
|
||||
this.filterCache = filterCache;
|
||||
this.indexFieldDataService = indexFieldDataService;
|
||||
this.filterCache = indexService.cache().filter();
|
||||
this.indexFieldDataService = indexService.fieldData();
|
||||
this.fixedBitSetFilterCache = indexService.fixedBitSetFilterCache();
|
||||
this.threadPool = threadPool;
|
||||
}
|
||||
|
||||
@ -92,6 +95,7 @@ public class TestSearchContext extends SearchContext {
|
||||
this.filterCache = null;
|
||||
this.indexFieldDataService = null;
|
||||
this.threadPool = null;
|
||||
this.fixedBitSetFilterCache = null;
|
||||
}
|
||||
|
||||
public void setTypes(String... types) {
|
||||
@ -321,6 +325,11 @@ public class TestSearchContext extends SearchContext {
|
||||
return filterCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FixedBitSetFilterCache fixedBitSetFilterCache() {
|
||||
return fixedBitSetFilterCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocSetCache docSetCache() {
|
||||
return null;
|
||||
|
Loading…
x
Reference in New Issue
Block a user