Skip to content

Commit

Permalink
Add access to internal representation of geo_point doc values (#86800)
Browse files Browse the repository at this point in the history
Refactors GeoPoint docvalues wrappers to expose the internal SortedNumericDocValues
  • Loading branch information
iverase committed May 20, 2022
1 parent 8a1ef1f commit 2e992fd
Show file tree
Hide file tree
Showing 16 changed files with 129 additions and 265 deletions.
12 changes: 12 additions & 0 deletions server/src/main/java/org/elasticsearch/common/geo/GeoPoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,18 @@ public String getGeohash() {
return Geohash.stringEncode(lon, lat);
}

/** Return the point in Lucene encoded format used to stored points as doc values */
public long getEncoded() {
final int latitudeEncoded = GeoEncodingUtils.encodeLatitude(this.lat);
final int longitudeEncoded = GeoEncodingUtils.encodeLongitude(this.lon);
return (((long) latitudeEncoded) << 32) | (longitudeEncoded & 0xFFFFFFFFL);
}

/** reset the point using Lucene encoded format used to stored points as doc values */
public GeoPoint resetFromEncoded(long encoded) {
return reset(GeoEncodingUtils.decodeLatitude((int) (encoded >>> 32)), GeoEncodingUtils.decodeLongitude((int) encoded));
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.index.SortedSetDocValues;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.geo.GeoPoint;

import java.io.IOException;
import java.util.ArrayList;
Expand Down Expand Up @@ -58,27 +57,6 @@ public static SortedNumericDoubleValues emptySortedNumericDoubles() {
return singleton(emptyNumericDouble());
}

public static GeoPointValues emptyGeoPoint() {
return new GeoPointValues() {
@Override
public boolean advanceExact(int doc) throws IOException {
return false;
}

@Override
public GeoPoint geoPointValue() {
throw new UnsupportedOperationException();
}
};
}

/**
* Return a {@link SortedNumericDoubleValues} that doesn't contain any value.
*/
public static MultiGeoPointValues emptyMultiGeoPoints() {
return singleton(emptyGeoPoint());
}

/**
* Returns a {@link DocValueBits} representing all documents from <code>values</code> that have a value.
*/
Expand Down Expand Up @@ -234,23 +212,12 @@ public static NumericDoubleValues unwrapSingleton(SortedNumericDoubleValues valu
return null;
}

/**
* Returns a multi-valued view over the provided {@link GeoPointValues}.
*/
public static MultiGeoPointValues singleton(GeoPointValues values) {
return new SingletonMultiGeoPointValues(values);
}

/**
* Returns a single-valued view of the {@link MultiGeoPointValues},
* if it was previously wrapped with {@link #singleton(GeoPointValues)},
* or null.
* if the wrapped {@link SortedNumericDocValues} is a singleton.
*/
public static GeoPointValues unwrapSingleton(MultiGeoPointValues values) {
if (values instanceof SingletonMultiGeoPointValues) {
return ((SingletonMultiGeoPointValues) values).getGeoPointValues();
}
return null;
return values.getGeoPointValues();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,16 @@

package org.elasticsearch.index.fielddata;

import org.apache.lucene.geo.GeoEncodingUtils;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.script.GeoPointFieldScript;

import java.util.Arrays;

public final class GeoPointScriptDocValues extends MultiGeoPointValues {
public final class GeoPointScriptDocValues extends AbstractSortedNumericDocValues {
private final GeoPointFieldScript script;
private final GeoPoint point;
private int cursor;

GeoPointScriptDocValues(GeoPointFieldScript script) {
this.script = script;
this.point = new GeoPoint();
}

@Override
Expand All @@ -41,10 +37,7 @@ public int docValueCount() {
}

@Override
public GeoPoint nextValue() {
final long value = script.values()[cursor++];
final int lat = (int) (value >>> 32);
final int lon = (int) (value & 0xFFFFFFFF);
return point.reset(GeoEncodingUtils.decodeLatitude(lat), GeoEncodingUtils.decodeLongitude(lon));
public long nextValue() {
return script.values()[cursor++];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package org.elasticsearch.index.fielddata;

import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.search.SortField;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.index.fielddata.plain.AbstractLeafGeoPointFieldData;
Expand Down Expand Up @@ -92,7 +93,7 @@ public LeafGeoPointFieldData load(LeafReaderContext context) {
GeoPointFieldScript script = leafFactory.newInstance(context);
return new AbstractLeafGeoPointFieldData(toScriptFieldFactory) {
@Override
public MultiGeoPointValues getGeoPointValues() {
public SortedNumericDocValues getSortedNumericDocValues() {
return new GeoPointScriptDocValues(script);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,36 @@

package org.elasticsearch.index.fielddata;

import org.apache.lucene.index.NumericDocValues;
import org.elasticsearch.common.geo.GeoPoint;

import java.io.IOException;

/**
* Per-document geo-point values.
*/
public abstract class GeoPointValues {
public final class GeoPointValues {

private final GeoPoint point = new GeoPoint();
private final NumericDocValues values;

GeoPointValues(NumericDocValues values) {
this.values = values;
}

/**
* Advance this instance to the given document id
* @return true if there is a value for this document
*/
public abstract boolean advanceExact(int doc) throws IOException;
public boolean advanceExact(int doc) throws IOException {
return values.advanceExact(doc);
}

/**
* Get the {@link GeoPoint} associated with the current document.
* The returned {@link GeoPoint} might be reused across calls.
*/
public abstract GeoPoint geoPointValue();

public GeoPoint geoPointValue() throws IOException {
return point.resetFromEncoded(values.longValue());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,25 @@
*/
package org.elasticsearch.index.fielddata;

import org.apache.lucene.index.SortedNumericDocValues;

/**
* {@link LeafFieldData} specialization for geo points.
*/
public interface LeafGeoPointFieldData extends LeafFieldData {
public abstract class LeafGeoPointFieldData implements LeafFieldData {

/**
* Return geo-point values.
*/
MultiGeoPointValues getGeoPointValues();
public final MultiGeoPointValues getGeoPointValues() {
return new MultiGeoPointValues(getSortedNumericDocValues());
}

/**
* Return the internal representation of geo_point doc values as a {@link SortedNumericDocValues}.
* A point is encoded as a long that can be decoded by using
* {@link org.elasticsearch.common.geo.GeoPoint#resetFromEncoded(long)}
*/
public abstract SortedNumericDocValues getSortedNumericDocValues();

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
*/
package org.elasticsearch.index.fielddata;

import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.index.SortedNumericDocValues;
import org.elasticsearch.common.geo.GeoPoint;

import java.io.IOException;
Expand All @@ -26,23 +29,32 @@
* The set of values associated with a document might contain duplicates and
* comes in a non-specified order.
*/
public abstract class MultiGeoPointValues {
public final class MultiGeoPointValues {

private final GeoPoint point = new GeoPoint();
private final SortedNumericDocValues numericValues;

/**
* Creates a new {@link MultiGeoPointValues} instance
*/
protected MultiGeoPointValues() {}
public MultiGeoPointValues(SortedNumericDocValues numericValues) {
this.numericValues = numericValues;
}

/**
* Advance this instance to the given document id
* @return true if there is a value for this document
*/
public abstract boolean advanceExact(int doc) throws IOException;
public boolean advanceExact(int doc) throws IOException {
return numericValues.advanceExact(doc);
}

/**
* Return the number of geo points the current document has.
*/
public abstract int docValueCount();
public int docValueCount() {
return numericValues.docValueCount();
}

/**
* Return the next value associated with the current document. This must not be
Expand All @@ -52,6 +64,16 @@ protected MultiGeoPointValues() {}
*
* @return the next value for the current docID set to {@link #advanceExact(int)}.
*/
public abstract GeoPoint nextValue() throws IOException;
public GeoPoint nextValue() throws IOException {
return point.resetFromEncoded(numericValues.nextValue());
}

/**
* Returns a single-valued view of the {@link MultiGeoPointValues} if possible, otherwise null.
*/
GeoPointValues getGeoPointValues() {
final NumericDocValues singleton = DocValues.unwrapSingleton(numericValues);
return singleton != null ? new GeoPointValues(singleton) : null;
}

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,14 @@
*/
package org.elasticsearch.index.fielddata.plain;

import org.apache.lucene.util.Accountable;
import org.elasticsearch.index.fielddata.FieldData;
import org.elasticsearch.index.fielddata.LeafGeoPointFieldData;
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
import org.elasticsearch.script.field.DocValuesScriptFieldFactory;
import org.elasticsearch.script.field.ToScriptFieldFactory;

import java.util.Collection;
import java.util.Collections;

public abstract class AbstractLeafGeoPointFieldData implements LeafGeoPointFieldData {
public abstract class AbstractLeafGeoPointFieldData extends LeafGeoPointFieldData {

protected final ToScriptFieldFactory<MultiGeoPointValues> toScriptFieldFactory;

Expand All @@ -35,27 +31,4 @@ public final SortedBinaryDocValues getBytesValues() {
public DocValuesScriptFieldFactory getScriptFieldFactory(String name) {
return toScriptFieldFactory.getScriptFieldFactory(getGeoPointValues(), name);
}

public static LeafGeoPointFieldData empty(final int maxDoc, ToScriptFieldFactory<MultiGeoPointValues> toScriptFieldFactory) {
return new AbstractLeafGeoPointFieldData(toScriptFieldFactory) {

@Override
public long ramBytesUsed() {
return 0;
}

@Override
public Collection<Accountable> getChildResources() {
return Collections.emptyList();
}

@Override
public void close() {}

@Override
public MultiGeoPointValues getGeoPointValues() {
return FieldData.emptyMultiGeoPoints();
}
};
}
}

0 comments on commit 2e992fd

Please sign in to comment.