SOLR-10499: facet.heatmap DocSet to Bits optimizations

This commit is contained in:
David Smiley 2017-04-20 17:46:28 -04:00
parent fb8fd77fa5
commit 991196216d
2 changed files with 24 additions and 20 deletions

View File

@ -184,6 +184,9 @@ Optimizations
instance if it already is modifiable, otherwise creates a new ModifiableSolrParams instance.
(Jörg Rathlev via Koji)
* SOLR-10499: facet.heatmap is now significantly faster when the docset (base query) matches everything and there are no
deleted docs. It's also faster when the docset matches a small fraction of the index or none. (David Smiley)
Bug Fixes
----------------------
* SOLR-10281: ADMIN_PATHS is duplicated in two places and inconsistent. This can cause automatic

View File

@ -32,6 +32,9 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.lucene.util.FixedBitSet;
import org.apache.solr.search.DocIterator;
import org.apache.solr.search.SolrIndexSearcher;
import org.locationtech.spatial4j.context.SpatialContext;
import org.locationtech.spatial4j.shape.Shape;
import org.apache.lucene.spatial.prefix.HeatmapFacetCounter;
@ -134,32 +137,13 @@ public class SpatialHeatmapFacets {
gridLevel = strategy.getGrid().getLevelForDistance(distErr);
}
// Turn docSet into Bits
Bits topAcceptDocs;
if (docSet instanceof BitDocSet) {
BitDocSet set = (BitDocSet) docSet;
topAcceptDocs = set.getBits();
} else {
topAcceptDocs = new Bits() {
@Override
public boolean get(int index) {
return docSet.exists(index);
}
@Override
public int length() {
return rb.req.getSearcher().maxDoc();
}
};
}
//Compute!
final HeatmapFacetCounter.Heatmap heatmap;
try {
heatmap = HeatmapFacetCounter.calcFacets(
strategy,
rb.req.getSearcher().getTopReaderContext(),
topAcceptDocs,
getTopAcceptDocs(docSet, rb.req.getSearcher()), // turn DocSet into Bits
boundsShape,
gridLevel,
params.getFieldInt(fieldKey, FacetParams.FACET_HEATMAP_MAX_CELLS, 100_000) // will throw if exceeded
@ -190,6 +174,23 @@ public class SpatialHeatmapFacets {
return result;
}
private static Bits getTopAcceptDocs(DocSet docSet, SolrIndexSearcher searcher) throws IOException {
if (searcher.getLiveDocs() == docSet) {
return null; // means match everything (all live docs). This can speedup things a lot.
} else if (docSet.size() == 0) {
return new Bits.MatchNoBits(searcher.maxDoc()); // can speedup things a lot
} else if (docSet instanceof BitDocSet) {
return ((BitDocSet) docSet).getBits();
} else {
// TODO DocSetBase.calcBits ought to be at DocSet level?
FixedBitSet bits = new FixedBitSet(searcher.maxDoc());
for (DocIterator iter = docSet.iterator(); iter.hasNext();) {
bits.set(iter.nextDoc());
}
return bits;
}
}
private static void formatCountsAndAddToNL(String fieldKey, ResponseBuilder rb, SolrParams params,
int columns, int rows, int[] counts, NamedList<Object> result) {
final String format = params.getFieldParam(fieldKey, FacetParams.FACET_HEATMAP_FORMAT, FORMAT_INTS2D);