LUCENE-7259: speed up MatchingPoints cost estimation

This commit is contained in:
Robert Muir 2016-04-27 12:01:44 -04:00
parent 3b4ec73595
commit ebd120465a
4 changed files with 30 additions and 3 deletions

View File

@ -108,6 +108,11 @@ abstract class LatLonPointBoxQuery extends Query {
values.intersect(field,
new IntersectVisitor() {
@Override
public void grow(int count) {
result.grow(count);
}
@Override
public void visit(int docID) {
result.add(docID);

View File

@ -121,6 +121,11 @@ final class LatLonPointDistanceQuery extends Query {
values.intersect(field,
new IntersectVisitor() {
@Override
public void grow(int count) {
result.grow(count);
}
@Override
public void visit(int docID) {
result.add(docID);

View File

@ -114,6 +114,11 @@ final class LatLonPointInPolygonQuery extends Query {
values.intersect(field,
new IntersectVisitor() {
@Override
public void grow(int count) {
result.grow(count);
}
@Override
public void visit(int docID) {
result.add(docID);

View File

@ -30,6 +30,9 @@ import org.apache.lucene.util.SparseFixedBitSet;
* Add matches with ({@link #add(int)}) and call {@link #iterator()} for
* an iterator over the results.
* <p>
* <b>NOTE:</b> it is required that you implement the optional {@code grow()}
* method in your IntersectVisitor, this is used for cost computation.
* <p>
* This implementation currently optimizes bitset structure (sparse vs dense)
* and {@link DocIdSetIterator#cost()} (cardinality) based on index statistics.
* This API may change as point values evolves.
@ -76,15 +79,24 @@ final class MatchingPoints {
*/
public void add(int doc) {
bits.set(doc);
counter++;
}
/**
* Grows cardinality counter by the given amount.
*/
public void grow(int amount) {
counter += amount;
}
/**
* Returns an iterator over the recorded matches.
*/
public DocIdSetIterator iterator() {
// if single-valued (docCount == numPoints), then this is exact
// otherwise its approximate based on field stats
// ensure caller implements the grow() api
assert counter > 0 || bits.cardinality() == 0 : "the IntersectVisitor is missing grow()";
// if single-valued (docCount == numPoints), then we know 1 point == 1 doc
// otherwise we approximate based on field stats
return new BitSetIterator(bits, (long) (counter * (docCount / (double) numPoints)));
}
}