improve multi value field cache handling both in terms of memory usage and GC behavior

This commit is contained in:
kimchy 2011-01-10 20:58:31 +02:00
parent 233ed1f8c6
commit 89314f29a7
1 changed files with 85 additions and 47 deletions

View File

@ -86,98 +86,136 @@ public class MultiValueGeoPointFieldData extends GeoPointFieldData {
}
@Override public boolean hasValue(int docId) {
return ordinals[docId] != null;
for (int[] ordinal : ordinals) {
if (ordinal[docId] != 0) {
return true;
}
}
return false;
}
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
int[] docOrders = ordinals[docId];
if (docOrders == null) {
return;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
proc.onValue(docId, GeoHashUtils.encode(lat[loc], lon[loc]));
}
for (int docOrder : docOrders) {
proc.onValue(docId, GeoHashUtils.encode(lat[docOrder], lon[docOrder]));
}
}
@Override public GeoPoint value(int docId) {
int[] docOrders = ordinals[docId];
if (docOrders == null) {
return null;
}
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
GeoPoint point = valuesCache.get().get();
int loc = docOrders[0];
point.latlon(lat[loc], lon[loc]);
return point;
}
}
return null;
}
@Override public GeoPoint[] values(int docId) {
int[] docOrders = ordinals[docId];
if (docOrders == null) {
int length = 0;
for (int[] ordinal : ordinals) {
if (ordinal[docId] != 0) {
length++;
}
}
if (length == 0) {
return EMPTY_ARRAY;
}
GeoPoint[] points;
if (docOrders.length < VALUE_CACHE_SIZE) {
points = valuesArrayCache.get().get()[docOrders.length];
for (int i = 0; i < docOrders.length; i++) {
int loc = docOrders[i];
points[i].latlon(lat[loc], lon[loc]);
if (length < VALUE_CACHE_SIZE) {
points = valuesArrayCache.get().get()[length];
int i = 0;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
points[i++].latlon(lat[loc], lon[loc]);
}
}
} else {
points = new GeoPoint[docOrders.length];
for (int i = 0; i < docOrders.length; i++) {
int loc = docOrders[i];
points[i] = new GeoPoint(lat[loc], lon[loc]);
points = new GeoPoint[length];
int i = 0;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
points[i++] = new GeoPoint(lat[loc], lon[loc]);
}
}
}
return points;
}
@Override public double latValue(int docId) {
int[] docOrders = ordinals[docId];
if (docOrders == null) {
return 0;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
return lat[loc];
}
return lat[docOrders[0]];
}
return 0;
}
@Override public double lonValue(int docId) {
int[] docOrders = ordinals[docId];
if (docOrders == null) {
return 0;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
return lon[loc];
}
return lon[docOrders[0]];
}
return 0;
}
@Override public double[] latValues(int docId) {
int[] docOrders = ordinals[docId];
if (docOrders == null) {
int length = 0;
for (int[] ordinal : ordinals) {
if (ordinal[docId] != 0) {
length++;
}
}
if (length == 0) {
return DoubleFieldData.EMPTY_DOUBLE_ARRAY;
}
double[] doubles;
if (docOrders.length < VALUE_CACHE_SIZE) {
doubles = valuesLatCache.get().get()[docOrders.length];
if (length < VALUE_CACHE_SIZE) {
doubles = valuesLatCache.get().get()[length];
} else {
doubles = new double[docOrders.length];
doubles = new double[length];
}
int i = 0;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
doubles[i++] = lat[loc];
}
for (int i = 0; i < docOrders.length; i++) {
doubles[i] = lat[docOrders[i]];
}
return doubles;
}
@Override public double[] lonValues(int docId) {
int[] docOrders = ordinals[docId];
if (docOrders == null) {
int length = 0;
for (int[] ordinal : ordinals) {
if (ordinal[docId] != 0) {
length++;
}
}
if (length == 0) {
return DoubleFieldData.EMPTY_DOUBLE_ARRAY;
}
double[] doubles;
if (docOrders.length < VALUE_CACHE_SIZE) {
doubles = valuesLonCache.get().get()[docOrders.length];
if (length < VALUE_CACHE_SIZE) {
doubles = valuesLonCache.get().get()[length];
} else {
doubles = new double[docOrders.length];
doubles = new double[length];
}
int i = 0;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
doubles[i++] = lon[loc];
}
for (int i = 0; i < docOrders.length; i++) {
doubles[i] = lon[docOrders[i]];
}
return doubles;
}