Use CacheRecycler when resolving parent docs in TopChildrenQuery.

This commit is contained in:
Martijn van Groningen 2013-02-04 12:46:30 +01:00
parent 9c3a86875b
commit 8109d13733
3 changed files with 58 additions and 4 deletions

View File

@ -44,6 +44,7 @@ public class CacheRecycler {
shortIntHashMap.clear();
longIntHashMap.clear();
objectIntHashMap.clear();
intObjectHashMap.clear();
objectFloatHashMap.clear();
objectArray.clear();
intArray.clear();
@ -396,6 +397,34 @@ public class CacheRecycler {
ref.add(map);
}
// ------ TIntObjectHashMap -----
private static SoftWrapper<Queue<TIntObjectHashMap>> intObjectHashMap = new SoftWrapper<Queue<TIntObjectHashMap>>();
@SuppressWarnings({"unchecked"})
public static <T> TIntObjectHashMap<T> popIntObjectMap() {
Queue<TIntObjectHashMap> ref = intObjectHashMap.get();
if (ref == null) {
return new TIntObjectHashMap<T>();
}
TIntObjectHashMap<T> map = ref.poll();
if (map == null) {
return new TIntObjectHashMap<T>();
}
return map;
}
public static <T> void pushIntObjectMap(TIntObjectHashMap<T> map) {
Queue<TIntObjectHashMap> ref = intObjectHashMap.get();
if (ref == null) {
ref = ConcurrentCollections.newQueue();
intObjectHashMap.set(ref);
}
map.clear();
ref.add(map);
}
// ------ TObjectFloatHashMap -----
private static SoftWrapper<Queue<TObjectFloatHashMap>> objectFloatHashMap = new SoftWrapper<Queue<TObjectFloatHashMap>>();

View File

@ -32,7 +32,10 @@ import org.elasticsearch.common.trove.ExtTHashMap;
import org.elasticsearch.search.internal.SearchContext;
import java.io.IOException;
import java.util.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import java.util.Set;
/**
* A query that evaluates the top matching child documents (based on the score) in order to determine what
@ -124,7 +127,7 @@ public class TopChildrenQuery extends Query implements SearchContext.Rewrite {
int resolveParentDocuments(TopDocs topDocs, SearchContext context) {
int parentHitsResolved = 0;
Map<Object, TIntObjectHashMap<ParentDoc>> parentDocsPerReader = new HashMap<Object, TIntObjectHashMap<ParentDoc>>();
ExtTHashMap<Object, TIntObjectHashMap<ParentDoc>> parentDocsPerReader = CacheRecycler.popHashMap();
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
int readerIndex = ReaderUtil.subIndex(scoreDoc.doc, context.searcher().getIndexReader().leaves());
AtomicReaderContext subContext = context.searcher().getIndexReader().leaves().get(readerIndex);
@ -146,7 +149,7 @@ public class TopChildrenQuery extends Query implements SearchContext.Rewrite {
TIntObjectHashMap<ParentDoc> readerParentDocs = parentDocsPerReader.get(indexReader.getCoreCacheKey());
if (readerParentDocs == null) {
readerParentDocs = new TIntObjectHashMap<ParentDoc>();
readerParentDocs = CacheRecycler.popIntObjectMap();
parentDocsPerReader.put(indexReader.getCoreCacheKey(), readerParentDocs);
}
@ -174,8 +177,9 @@ public class TopChildrenQuery extends Query implements SearchContext.Rewrite {
ParentDoc[] values = entry.getValue().values(new ParentDoc[entry.getValue().size()]);
Arrays.sort(values, PARENT_DOC_COMP);
parentDocs.put(entry.getKey(), values);
CacheRecycler.pushIntObjectMap(entry.getValue());
}
CacheRecycler.pushHashMap(parentDocsPerReader);
return parentHitsResolved;
}

View File

@ -279,6 +279,27 @@ public class ChildSearchBenchmark {
}
System.out.println("--> top_children Query Avg: " + (totalQueryTime / QUERY_COUNT) + "ms");
System.out.println("--> Running top_children query, with match_all as child query");
// run parent child score query
for (int j = 0; j < QUERY_WARMUP; j++) {
SearchResponse searchResponse = client.prepareSearch(indexName).setQuery(topChildrenQuery("child", matchAllQuery())).execute().actionGet();
// we expect to have mismatch on hits here
// if (searchResponse.hits().totalHits() != COUNT) {
// System.err.println("mismatch on hits");
// }
}
totalQueryTime = 0;
for (int j = 0; j < QUERY_COUNT; j++) {
SearchResponse searchResponse = client.prepareSearch(indexName).setQuery(topChildrenQuery("child", matchAllQuery())).execute().actionGet();
// we expect to have mismatch on hits here
// if (searchResponse.hits().totalHits() != COUNT) {
// System.err.println("mismatch on hits");
// }
totalQueryTime += searchResponse.tookInMillis();
}
System.out.println("--> top_children, with match_all Query Avg: " + (totalQueryTime / QUERY_COUNT) + "ms");
statsResponse = client.admin().cluster().prepareNodesStats()
.setJvm(true).setIndices(true).execute().actionGet();