use static classes for docsets instead of inner classes to make sure we don't rely on hotspot to inline field lookups

This commit is contained in:
Shay Banon 2011-08-17 04:20:43 +03:00
parent 451c87f486
commit 55f62eca8a
4 changed files with 244 additions and 177 deletions

View File

@ -66,7 +66,23 @@ public class GeoBoundingBoxFilter extends Filter {
//checks to see if bounding box crosses 180 degrees
if (topLeft.lon > bottomRight.lon) {
return new GetDocSet(reader.maxDoc()) {
return new LeftGeoBoundingBoxDocSet(reader.maxDoc(), fieldData, topLeft, bottomRight);
} else {
return new RightGeoBoundingBoxDocSet(reader.maxDoc(), fieldData, topLeft, bottomRight);
}
}
public static class LeftGeoBoundingBoxDocSet extends GetDocSet {
private final GeoPointFieldData fieldData;
private final Point topLeft;
private final Point bottomRight;
public LeftGeoBoundingBoxDocSet(int maxDoc, GeoPointFieldData fieldData, Point topLeft, Point bottomRight) {
super(maxDoc);
this.fieldData = fieldData;
this.topLeft = topLeft;
this.bottomRight = bottomRight;
}
@Override public boolean isCacheable() {
// not cacheable for several reasons:
@ -102,9 +118,19 @@ public class GeoBoundingBoxFilter extends Filter {
}
return false;
}
};
} else {
return new GetDocSet(reader.maxDoc()) {
}
public static class RightGeoBoundingBoxDocSet extends GetDocSet {
private final GeoPointFieldData fieldData;
private final Point topLeft;
private final Point bottomRight;
public RightGeoBoundingBoxDocSet(int maxDoc, GeoPointFieldData fieldData, Point topLeft, Point bottomRight) {
super(maxDoc);
this.fieldData = fieldData;
this.topLeft = topLeft;
this.bottomRight = bottomRight;
}
@Override public boolean isCacheable() {
// not cacheable for several reasons:
@ -138,8 +164,6 @@ public class GeoBoundingBoxFilter extends Filter {
}
return false;
}
};
}
}
public static class Point {

View File

@ -78,36 +78,7 @@ public class GeoDistanceFilter extends Filter {
@Override public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
final GeoPointFieldData fieldData = (GeoPointFieldData) fieldDataCache.cache(GeoPointFieldDataType.TYPE, reader, fieldName);
return new GetDocSet(reader.maxDoc()) {
@Override public boolean isCacheable() {
// not cacheable for several reasons:
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
// 2. Its already fast without in mem bitset, since it works with field data
return false;
}
@Override public boolean get(int doc) throws IOException {
if (!fieldData.hasValue(doc)) {
return false;
}
if (fieldData.multiValued()) {
double[] lats = fieldData.latValues(doc);
double[] lons = fieldData.lonValues(doc);
for (int i = 0; i < lats.length; i++) {
double d = geoDistance.calculate(lat, lon, lats[i], lons[i], DistanceUnit.MILES);
if (d < distance) {
return true;
}
}
return false;
} else {
double d = geoDistance.calculate(lat, lon, fieldData.latValue(doc), fieldData.lonValue(doc), DistanceUnit.MILES);
return d < distance;
}
}
};
return new GeoDistanceDocSet(reader.maxDoc(), geoDistance, fieldData, lat, lon, distance);
}
@Override
@ -140,4 +111,49 @@ public class GeoDistanceFilter extends Filter {
result = 31 * result + (fieldName != null ? fieldName.hashCode() : 0);
return result;
}
public static class GeoDistanceDocSet extends GetDocSet {
private final GeoDistance geoDistance;
private final GeoPointFieldData fieldData;
private final double lat;
private final double lon;
private final double distance;
public GeoDistanceDocSet(int maxDoc, GeoDistance geoDistance, GeoPointFieldData fieldData, double lat, double lon, double distance) {
super(maxDoc);
this.geoDistance = geoDistance;
this.fieldData = fieldData;
this.lat = lat;
this.lon = lon;
this.distance = distance;
}
@Override public boolean isCacheable() {
// not cacheable for several reasons:
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
// 2. Its already fast without in mem bitset, since it works with field data
return false;
}
@Override public boolean get(int doc) throws IOException {
if (!fieldData.hasValue(doc)) {
return false;
}
if (fieldData.multiValued()) {
double[] lats = fieldData.latValues(doc);
double[] lons = fieldData.lonValues(doc);
for (int i = 0; i < lats.length; i++) {
double d = geoDistance.calculate(lat, lon, lats[i], lons[i], DistanceUnit.MILES);
if (d < distance) {
return true;
}
}
return false;
} else {
double d = geoDistance.calculate(lat, lon, fieldData.latValue(doc), fieldData.lonValue(doc), DistanceUnit.MILES);
return d < distance;
}
}
}
}

View File

@ -37,7 +37,6 @@ import java.io.IOException;
public class GeoDistanceRangeFilter extends Filter {
private final double lat;
private final double lon;
private final double inclusiveLowerPoint; // in miles
@ -90,39 +89,7 @@ public class GeoDistanceRangeFilter extends Filter {
@Override public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
final GeoPointFieldData fieldData = (GeoPointFieldData) fieldDataCache.cache(GeoPointFieldDataType.TYPE, reader, fieldName);
return new GetDocSet(reader.maxDoc()) {
@Override public boolean isCacheable() {
// not cacheable for several reasons:
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
// 2. Its already fast without in mem bitset, since it works with field data
return false;
}
@Override public boolean get(int doc) throws IOException {
if (!fieldData.hasValue(doc)) {
return false;
}
if (fieldData.multiValued()) {
double[] lats = fieldData.latValues(doc);
double[] lons = fieldData.lonValues(doc);
for (int i = 0; i < lats.length; i++) {
double d = geoDistance.calculate(lat, lon, lats[i], lons[i], DistanceUnit.MILES);
if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) {
return true;
}
}
return false;
} else {
double d = geoDistance.calculate(lat, lon, fieldData.latValue(doc), fieldData.lonValue(doc), DistanceUnit.MILES);
if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) {
return true;
}
return false;
}
}
};
return new GeoDistanceRangeDocSet(reader.maxDoc(), fieldData, geoDistance, lat, lon, inclusiveLowerPoint, inclusiveUpperPoint);
}
@Override
@ -158,4 +125,55 @@ public class GeoDistanceRangeFilter extends Filter {
result = 31 * result + (fieldName != null ? fieldName.hashCode() : 0);
return result;
}
public static class GeoDistanceRangeDocSet extends GetDocSet {
private final GeoPointFieldData fieldData;
private final GeoDistance geoDistance;
private final double lat;
private final double lon;
private final double inclusiveLowerPoint; // in miles
private final double inclusiveUpperPoint; // in miles
public GeoDistanceRangeDocSet(int maxDoc, GeoPointFieldData fieldData, GeoDistance geoDistance, double lat, double lon, double inclusiveLowerPoint, double inclusiveUpperPoint) {
super(maxDoc);
this.fieldData = fieldData;
this.geoDistance = geoDistance;
this.lat = lat;
this.lon = lon;
this.inclusiveLowerPoint = inclusiveLowerPoint;
this.inclusiveUpperPoint = inclusiveUpperPoint;
}
@Override public boolean isCacheable() {
// not cacheable for several reasons:
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
// 2. Its already fast without in mem bitset, since it works with field data
return false;
}
@Override public boolean get(int doc) throws IOException {
if (!fieldData.hasValue(doc)) {
return false;
}
if (fieldData.multiValued()) {
double[] lats = fieldData.latValues(doc);
double[] lons = fieldData.lonValues(doc);
for (int i = 0; i < lats.length; i++) {
double d = geoDistance.calculate(lat, lon, lats[i], lons[i], DistanceUnit.MILES);
if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) {
return true;
}
}
return false;
} else {
double d = geoDistance.calculate(lat, lon, fieldData.latValue(doc), fieldData.lonValue(doc), DistanceUnit.MILES);
if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) {
return true;
}
return false;
}
}
}
}

View File

@ -56,8 +56,18 @@ public class GeoPolygonFilter extends Filter {
@Override public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
final GeoPointFieldData fieldData = (GeoPointFieldData) fieldDataCache.cache(GeoPointFieldDataType.TYPE, reader, fieldName);
return new GeoPolygonDocSet(reader.maxDoc(), fieldData, points);
}
return new GetDocSet(reader.maxDoc()) {
public static class GeoPolygonDocSet extends GetDocSet {
private final GeoPointFieldData fieldData;
private final Point[] points;
public GeoPolygonDocSet(int maxDoc, GeoPointFieldData fieldData, Point[] points) {
super(maxDoc);
this.fieldData = fieldData;
this.points = points;
}
@Override public boolean isCacheable() {
// not cacheable for several reasons:
@ -86,8 +96,6 @@ public class GeoPolygonFilter extends Filter {
}
return false;
}
};
}
private static boolean pointInPolygon(Point[] points, double lat, double lon) {
int i;
@ -106,6 +114,7 @@ public class GeoPolygonFilter extends Filter {
}
return inPoly;
}
}
public static class Point {
public double lat;