mirror of https://github.com/apache/lucene.git
LUCENE-7130: fold optimizations from LatLonPoint to GeoPointField
This commit is contained in:
parent
1e5f74a02b
commit
5385c8d92f
|
@ -104,12 +104,12 @@ final class LatLonPointDistanceQuery extends Query {
|
|||
|
||||
// compute a maximum partial haversin: unless our box is crazy, we can use this bound
|
||||
// to reject edge cases faster in matches()
|
||||
final double minPartialDistance;
|
||||
final double maxPartialDistance;
|
||||
if (box.maxLon - longitude < 90 && longitude - box.minLon < 90) {
|
||||
minPartialDistance = Math.max(SloppyMath.haversinSortKey(latitude, longitude, latitude, box.maxLon),
|
||||
maxPartialDistance = Math.max(SloppyMath.haversinSortKey(latitude, longitude, latitude, box.maxLon),
|
||||
SloppyMath.haversinSortKey(latitude, longitude, box.maxLat, longitude));
|
||||
} else {
|
||||
minPartialDistance = Double.POSITIVE_INFINITY;
|
||||
maxPartialDistance = Double.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
return new ConstantScoreWeight(this) {
|
||||
|
@ -235,7 +235,7 @@ final class LatLonPointDistanceQuery extends Query {
|
|||
|
||||
// first check the partial distance, if its more than that, it can't be <= radiusMeters
|
||||
double h1 = SloppyMath.haversinSortKey(latitude, longitude, docLatitude, docLongitude);
|
||||
if (h1 > minPartialDistance) {
|
||||
if (h1 > maxPartialDistance) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,11 +29,23 @@ final class GeoPointDistanceQueryImpl extends GeoPointInBBoxQueryImpl {
|
|||
private final GeoPointDistanceQuery distanceQuery;
|
||||
private final double centerLon;
|
||||
|
||||
// optimization, maximum partial haversin needed to be a candidate
|
||||
private final double maxPartialDistance;
|
||||
|
||||
GeoPointDistanceQueryImpl(final String field, final TermEncoding termEncoding, final GeoPointDistanceQuery q,
|
||||
final double centerLonUnwrapped, final GeoRect bbox) {
|
||||
super(field, termEncoding, bbox.minLat, bbox.maxLat, bbox.minLon, bbox.maxLon);
|
||||
distanceQuery = q;
|
||||
centerLon = centerLonUnwrapped;
|
||||
|
||||
// unless our box is crazy, we can use this bound
|
||||
// to reject edge cases faster in postFilter()
|
||||
if (bbox.maxLon - centerLon < 90 && centerLon - bbox.minLon < 90) {
|
||||
maxPartialDistance = Math.max(SloppyMath.haversinSortKey(distanceQuery.centerLat, centerLon, distanceQuery.centerLat, bbox.maxLon),
|
||||
SloppyMath.haversinSortKey(distanceQuery.centerLat, centerLon, bbox.maxLat, centerLon));
|
||||
} else {
|
||||
maxPartialDistance = Double.POSITIVE_INFINITY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -65,8 +77,7 @@ final class GeoPointDistanceQueryImpl extends GeoPointInBBoxQueryImpl {
|
|||
|
||||
@Override
|
||||
protected boolean cellWithin(final double minLat, final double maxLat, final double minLon, final double maxLon) {
|
||||
// TODO: we call cellCrosses because of how the termsEnum logic works, helps us avoid some haversin() calls here.
|
||||
if (cellCrosses(minLat, maxLat, minLon, maxLon) && maxLon - centerLon < 90 && centerLon - minLon < 90 &&
|
||||
if (maxLon - centerLon < 90 && centerLon - minLon < 90 &&
|
||||
SloppyMath.haversinMeters(distanceQuery.centerLat, centerLon, minLat, minLon) <= distanceQuery.radiusMeters &&
|
||||
SloppyMath.haversinMeters(distanceQuery.centerLat, centerLon, minLat, maxLon) <= distanceQuery.radiusMeters &&
|
||||
SloppyMath.haversinMeters(distanceQuery.centerLat, centerLon, maxLat, minLon) <= distanceQuery.radiusMeters &&
|
||||
|
@ -90,7 +101,19 @@ final class GeoPointDistanceQueryImpl extends GeoPointInBBoxQueryImpl {
|
|||
*/
|
||||
@Override
|
||||
protected boolean postFilter(final double lat, final double lon) {
|
||||
return SloppyMath.haversinMeters(distanceQuery.centerLat, centerLon, lat, lon) <= distanceQuery.radiusMeters;
|
||||
// check bbox
|
||||
if (lat < minLat || lat > maxLat || lon < minLon || lon > maxLon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// first check the partial distance, if its more than that, it can't be <= radiusMeters
|
||||
double h1 = SloppyMath.haversinSortKey(distanceQuery.centerLat, centerLon, lat, lon);
|
||||
if (h1 > maxPartialDistance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// fully confirm with part 2:
|
||||
return SloppyMath.haversinMeters(h1) <= distanceQuery.radiusMeters;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,8 +99,10 @@ final class GeoPointPrefixTermsEnum extends GeoPointTermsEnum {
|
|||
maxLon = mortonUnhashLon(currEnd);
|
||||
maxLat = mortonUnhashLat(currEnd);
|
||||
|
||||
isWithin = false;
|
||||
// within or a boundary
|
||||
if ((isWithin = within(minLat, maxLat, minLon, maxLon) == true) || boundary(minLat, maxLat, minLon, maxLon) == true) {
|
||||
if (boundary(minLat, maxLat, minLon, maxLon) == true) {
|
||||
isWithin = within(minLat, maxLat, minLon, maxLon);
|
||||
final int m;
|
||||
if (isWithin == false || (m = shift % GeoPointField.PRECISION_STEP) == 0) {
|
||||
setNextRange(isWithin == false);
|
||||
|
|
Loading…
Reference in New Issue