mirror of https://github.com/apache/lucene.git
LUCENE-7117, LUCENE-7118: Remove multidimensional arrays from PointRangeQuery
This commit is contained in:
parent
cc01ba39cd
commit
51b109620b
|
@ -173,7 +173,7 @@ public final class BinaryPoint extends Field {
|
|||
* @return a query matching documents within this range.
|
||||
*/
|
||||
public static Query newRangeQuery(String field, byte[][] lowerValue, byte[][] upperValue) {
|
||||
return new PointRangeQuery(field, lowerValue, upperValue) {
|
||||
return new PointRangeQuery(field, pack(lowerValue).bytes, pack(upperValue).bytes, lowerValue.length) {
|
||||
@Override
|
||||
protected String toString(int dimension, byte[] value) {
|
||||
assert value != null;
|
||||
|
|
|
@ -126,16 +126,6 @@ public final class DoublePoint extends Field {
|
|||
return result.toString();
|
||||
}
|
||||
|
||||
/** Encode n-dimensional double point into binary encoding */
|
||||
private static byte[][] encode(double value[]) {
|
||||
byte[][] encoded = new byte[value.length][];
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
encoded[i] = new byte[Double.BYTES];
|
||||
encodeDimension(value[i], encoded[i], 0);
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
// public helper methods (e.g. for queries)
|
||||
|
||||
/** Encode single double dimension */
|
||||
|
@ -207,7 +197,7 @@ public final class DoublePoint extends Field {
|
|||
*/
|
||||
public static Query newRangeQuery(String field, double[] lowerValue, double[] upperValue) {
|
||||
PointRangeQuery.checkArgs(field, lowerValue, upperValue);
|
||||
return new PointRangeQuery(field, encode(lowerValue), encode(upperValue)) {
|
||||
return new PointRangeQuery(field, pack(lowerValue).bytes, pack(upperValue).bytes, lowerValue.length) {
|
||||
@Override
|
||||
protected String toString(int dimension, byte[] value) {
|
||||
return Double.toString(decodeDimension(value, 0));
|
||||
|
|
|
@ -126,16 +126,6 @@ public final class FloatPoint extends Field {
|
|||
return result.toString();
|
||||
}
|
||||
|
||||
/** Encode n-dimensional float values into binary encoding */
|
||||
private static byte[][] encode(float value[]) {
|
||||
byte[][] encoded = new byte[value.length][];
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
encoded[i] = new byte[Float.BYTES];
|
||||
encodeDimension(value[i], encoded[i], 0);
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
// public helper methods (e.g. for queries)
|
||||
|
||||
/** Encode single float dimension */
|
||||
|
@ -207,7 +197,7 @@ public final class FloatPoint extends Field {
|
|||
*/
|
||||
public static Query newRangeQuery(String field, float[] lowerValue, float[] upperValue) {
|
||||
PointRangeQuery.checkArgs(field, lowerValue, upperValue);
|
||||
return new PointRangeQuery(field, encode(lowerValue), encode(upperValue)) {
|
||||
return new PointRangeQuery(field, pack(lowerValue).bytes, pack(upperValue).bytes, lowerValue.length) {
|
||||
@Override
|
||||
protected String toString(int dimension, byte[] value) {
|
||||
return Float.toString(decodeDimension(value, 0));
|
||||
|
|
|
@ -125,16 +125,6 @@ public final class IntPoint extends Field {
|
|||
result.append('>');
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/** Encode n-dimensional integer values into binary encoding */
|
||||
private static byte[][] encode(int value[]) {
|
||||
byte[][] encoded = new byte[value.length][];
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
encoded[i] = new byte[Integer.BYTES];
|
||||
encodeDimension(value[i], encoded[i], 0);
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
// public helper methods (e.g. for queries)
|
||||
|
||||
|
@ -205,7 +195,7 @@ public final class IntPoint extends Field {
|
|||
*/
|
||||
public static Query newRangeQuery(String field, int[] lowerValue, int[] upperValue) {
|
||||
PointRangeQuery.checkArgs(field, lowerValue, upperValue);
|
||||
return new PointRangeQuery(field, encode(lowerValue), encode(upperValue)) {
|
||||
return new PointRangeQuery(field, pack(lowerValue).bytes, pack(upperValue).bytes, lowerValue.length) {
|
||||
@Override
|
||||
protected String toString(int dimension, byte[] value) {
|
||||
return Integer.toString(decodeDimension(value, 0));
|
||||
|
|
|
@ -126,16 +126,6 @@ public final class LongPoint extends Field {
|
|||
return result.toString();
|
||||
}
|
||||
|
||||
/** Encode n-dimensional long values into binary encoding */
|
||||
private static byte[][] encode(long value[]) {
|
||||
byte[][] encoded = new byte[value.length][];
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
encoded[i] = new byte[Long.BYTES];
|
||||
encodeDimension(value[i], encoded[i], 0);
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
// public helper methods (e.g. for queries)
|
||||
|
||||
/** Encode single long dimension */
|
||||
|
@ -205,7 +195,7 @@ public final class LongPoint extends Field {
|
|||
*/
|
||||
public static Query newRangeQuery(String field, long[] lowerValue, long[] upperValue) {
|
||||
PointRangeQuery.checkArgs(field, lowerValue, upperValue);
|
||||
return new PointRangeQuery(field, encode(lowerValue), encode(upperValue)) {
|
||||
return new PointRangeQuery(field, pack(lowerValue).bytes, pack(upperValue).bytes, lowerValue.length) {
|
||||
@Override
|
||||
protected String toString(int dimension, byte[] value) {
|
||||
return Long.toString(decodeDimension(value, 0));
|
||||
|
|
|
@ -47,8 +47,8 @@ public abstract class PointRangeQuery extends Query {
|
|||
final String field;
|
||||
final int numDims;
|
||||
final int bytesPerDim;
|
||||
final byte[][] lowerPoint;
|
||||
final byte[][] upperPoint;
|
||||
final byte[] lowerPoint;
|
||||
final byte[] upperPoint;
|
||||
|
||||
/**
|
||||
* Expert: create a multidimensional range query for point values.
|
||||
|
@ -56,40 +56,26 @@ public abstract class PointRangeQuery extends Query {
|
|||
* @param field field name. must not be {@code null}.
|
||||
* @param lowerPoint lower portion of the range (inclusive).
|
||||
* @param upperPoint upper portion of the range (inclusive).
|
||||
* @param numDims number of dimensions.
|
||||
* @throws IllegalArgumentException if {@code field} is null, or if {@code lowerValue.length != upperValue.length}
|
||||
*/
|
||||
protected PointRangeQuery(String field, byte[][] lowerPoint, byte[][] upperPoint) {
|
||||
protected PointRangeQuery(String field, byte[] lowerPoint, byte[] upperPoint, int numDims) {
|
||||
checkArgs(field, lowerPoint, upperPoint);
|
||||
this.field = field;
|
||||
if (lowerPoint.length == 0) {
|
||||
throw new IllegalArgumentException("lowerPoint has length of zero");
|
||||
}
|
||||
this.numDims = lowerPoint.length;
|
||||
|
||||
if (upperPoint.length != numDims) {
|
||||
if (lowerPoint.length % numDims != 0) {
|
||||
throw new IllegalArgumentException("lowerPoint is not a fixed multiple of numDims");
|
||||
}
|
||||
if (upperPoint.length != upperPoint.length) {
|
||||
throw new IllegalArgumentException("lowerPoint has length=" + numDims + " but upperPoint has different length=" + upperPoint.length);
|
||||
}
|
||||
this.numDims = numDims;
|
||||
this.bytesPerDim = lowerPoint.length / numDims;
|
||||
|
||||
this.lowerPoint = lowerPoint;
|
||||
this.upperPoint = upperPoint;
|
||||
|
||||
if (lowerPoint[0] == null) {
|
||||
throw new IllegalArgumentException("lowerPoint[0] is null");
|
||||
}
|
||||
this.bytesPerDim = lowerPoint[0].length;
|
||||
for (int i = 0; i < numDims; i++) {
|
||||
if (lowerPoint[i] == null) {
|
||||
throw new IllegalArgumentException("lowerPoint[" + i + "] is null");
|
||||
}
|
||||
if (upperPoint[i] == null) {
|
||||
throw new IllegalArgumentException("upperPoint[" + i + "] is null");
|
||||
}
|
||||
if (lowerPoint[i].length != bytesPerDim) {
|
||||
throw new IllegalArgumentException("all dimensions must have same bytes length, but saw " + bytesPerDim + " and " + lowerPoint[i].length);
|
||||
}
|
||||
if (upperPoint[i].length != bytesPerDim) {
|
||||
throw new IllegalArgumentException("all dimensions must have same bytes length, but saw " + bytesPerDim + " and " + upperPoint[i].length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,8 +102,7 @@ public abstract class PointRangeQuery extends Query {
|
|||
|
||||
return new ConstantScoreWeight(this) {
|
||||
|
||||
private DocIdSet buildMatchingDocIdSet(LeafReader reader, PointValues values,
|
||||
byte[] packedLower, byte[] packedUpper) throws IOException {
|
||||
private DocIdSet buildMatchingDocIdSet(LeafReader reader, PointValues values) throws IOException {
|
||||
DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc());
|
||||
|
||||
values.intersect(field,
|
||||
|
@ -137,11 +122,11 @@ public abstract class PointRangeQuery extends Query {
|
|||
public void visit(int docID, byte[] packedValue) {
|
||||
for(int dim=0;dim<numDims;dim++) {
|
||||
int offset = dim*bytesPerDim;
|
||||
if (StringHelper.compare(bytesPerDim, packedValue, offset, packedLower, offset) < 0) {
|
||||
if (StringHelper.compare(bytesPerDim, packedValue, offset, lowerPoint, offset) < 0) {
|
||||
// Doc's value is too low, in this dimension
|
||||
return;
|
||||
}
|
||||
if (StringHelper.compare(bytesPerDim, packedValue, offset, packedUpper, offset) > 0) {
|
||||
if (StringHelper.compare(bytesPerDim, packedValue, offset, upperPoint, offset) > 0) {
|
||||
// Doc's value is too high, in this dimension
|
||||
return;
|
||||
}
|
||||
|
@ -159,13 +144,13 @@ public abstract class PointRangeQuery extends Query {
|
|||
for(int dim=0;dim<numDims;dim++) {
|
||||
int offset = dim*bytesPerDim;
|
||||
|
||||
if (StringHelper.compare(bytesPerDim, minPackedValue, offset, packedUpper, offset) > 0 ||
|
||||
StringHelper.compare(bytesPerDim, maxPackedValue, offset, packedLower, offset) < 0) {
|
||||
if (StringHelper.compare(bytesPerDim, minPackedValue, offset, upperPoint, offset) > 0 ||
|
||||
StringHelper.compare(bytesPerDim, maxPackedValue, offset, lowerPoint, offset) < 0) {
|
||||
return Relation.CELL_OUTSIDE_QUERY;
|
||||
}
|
||||
|
||||
crosses |= StringHelper.compare(bytesPerDim, minPackedValue, offset, packedLower, offset) < 0 ||
|
||||
StringHelper.compare(bytesPerDim, maxPackedValue, offset, packedUpper, offset) > 0;
|
||||
crosses |= StringHelper.compare(bytesPerDim, minPackedValue, offset, lowerPoint, offset) < 0 ||
|
||||
StringHelper.compare(bytesPerDim, maxPackedValue, offset, upperPoint, offset) > 0;
|
||||
}
|
||||
|
||||
if (crosses) {
|
||||
|
@ -197,16 +182,6 @@ public abstract class PointRangeQuery extends Query {
|
|||
if (bytesPerDim != fieldInfo.getPointNumBytes()) {
|
||||
throw new IllegalArgumentException("field=\"" + field + "\" was indexed with bytesPerDim=" + fieldInfo.getPointNumBytes() + " but this query has bytesPerDim=" + bytesPerDim);
|
||||
}
|
||||
int bytesPerDim = fieldInfo.getPointNumBytes();
|
||||
|
||||
byte[] packedLower = new byte[numDims * bytesPerDim];
|
||||
byte[] packedUpper = new byte[numDims * bytesPerDim];
|
||||
|
||||
// Carefully pack lower and upper bounds
|
||||
for(int dim=0;dim<numDims;dim++) {
|
||||
System.arraycopy(lowerPoint[dim], 0, packedLower, dim*bytesPerDim, bytesPerDim);
|
||||
System.arraycopy(upperPoint[dim], 0, packedUpper, dim*bytesPerDim, bytesPerDim);
|
||||
}
|
||||
|
||||
boolean allDocsMatch;
|
||||
if (values.getDocCount(field) == reader.maxDoc()) {
|
||||
|
@ -215,8 +190,8 @@ public abstract class PointRangeQuery extends Query {
|
|||
allDocsMatch = true;
|
||||
for (int i = 0; i < numDims; ++i) {
|
||||
int offset = i * bytesPerDim;
|
||||
if (StringHelper.compare(bytesPerDim, packedLower, offset, fieldPackedLower, offset) > 0
|
||||
|| StringHelper.compare(bytesPerDim, packedUpper, offset, fieldPackedUpper, offset) < 0) {
|
||||
if (StringHelper.compare(bytesPerDim, lowerPoint, offset, fieldPackedLower, offset) > 0
|
||||
|| StringHelper.compare(bytesPerDim, upperPoint, offset, fieldPackedUpper, offset) < 0) {
|
||||
allDocsMatch = false;
|
||||
break;
|
||||
}
|
||||
|
@ -230,7 +205,7 @@ public abstract class PointRangeQuery extends Query {
|
|||
// all docs have a value and all points are within bounds, so everything matches
|
||||
iterator = DocIdSetIterator.all(reader.maxDoc());
|
||||
} else {
|
||||
iterator = buildMatchingDocIdSet(reader, values, packedLower, packedUpper).iterator();
|
||||
iterator = buildMatchingDocIdSet(reader, values).iterator();
|
||||
}
|
||||
|
||||
return new ConstantScoreScorer(this, score(), iterator);
|
||||
|
@ -263,15 +238,12 @@ public abstract class PointRangeQuery extends Query {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Cannot use Arrays.equals here, because it in turn uses byte[].equals
|
||||
// to compare each value, which only uses "=="
|
||||
for(int dim=0;dim<numDims;dim++) {
|
||||
if (Arrays.equals(lowerPoint[dim], q.lowerPoint[dim]) == false) {
|
||||
return false;
|
||||
}
|
||||
if (Arrays.equals(upperPoint[dim], q.upperPoint[dim]) == false) {
|
||||
return false;
|
||||
}
|
||||
if (!Arrays.equals(lowerPoint, q.lowerPoint)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Arrays.equals(upperPoint, q.upperPoint)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -290,11 +262,13 @@ public abstract class PointRangeQuery extends Query {
|
|||
if (i > 0) {
|
||||
sb.append(',');
|
||||
}
|
||||
|
||||
int startOffset = bytesPerDim * i;
|
||||
|
||||
sb.append('[');
|
||||
sb.append(toString(i, lowerPoint[i]));
|
||||
sb.append(toString(i, Arrays.copyOfRange(lowerPoint, startOffset, startOffset + bytesPerDim)));
|
||||
sb.append(" TO ");
|
||||
sb.append(toString(i, upperPoint[i]));
|
||||
sb.append(toString(i, Arrays.copyOfRange(upperPoint, startOffset, startOffset + bytesPerDim)));
|
||||
sb.append(']');
|
||||
}
|
||||
|
||||
|
|
|
@ -1896,82 +1896,112 @@ public class TestPointQueries extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testPointRangeEquals() {
|
||||
Query q = IntPoint.newRangeQuery("a", 0, 1000);
|
||||
assertEquals(q, IntPoint.newRangeQuery("a", 0, 1000));
|
||||
assertFalse(q.equals(IntPoint.newRangeQuery("a", 1, 1000)));
|
||||
Query q1 = IntPoint.newRangeQuery("a", 0, 1000);
|
||||
Query q2 = IntPoint.newRangeQuery("a", 0, 1000);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(IntPoint.newRangeQuery("a", 1, 1000)));
|
||||
|
||||
q = LongPoint.newRangeQuery("a", 0, 1000);
|
||||
assertEquals(q, LongPoint.newRangeQuery("a", 0, 1000));
|
||||
assertFalse(q.equals(LongPoint.newRangeQuery("a", 1, 1000)));
|
||||
q1 = LongPoint.newRangeQuery("a", 0, 1000);
|
||||
q2 = LongPoint.newRangeQuery("a", 0, 1000);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(LongPoint.newRangeQuery("a", 1, 1000)));
|
||||
|
||||
q = FloatPoint.newRangeQuery("a", 0, 1000);
|
||||
assertEquals(q, FloatPoint.newRangeQuery("a", 0, 1000));
|
||||
assertFalse(q.equals(FloatPoint.newRangeQuery("a", 1, 1000)));
|
||||
q1 = FloatPoint.newRangeQuery("a", 0, 1000);
|
||||
q2 = FloatPoint.newRangeQuery("a", 0, 1000);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(FloatPoint.newRangeQuery("a", 1, 1000)));
|
||||
|
||||
q = DoublePoint.newRangeQuery("a", 0, 1000);
|
||||
assertEquals(q, DoublePoint.newRangeQuery("a", 0, 1000));
|
||||
assertFalse(q.equals(DoublePoint.newRangeQuery("a", 1, 1000)));
|
||||
q1 = DoublePoint.newRangeQuery("a", 0, 1000);
|
||||
q2 = DoublePoint.newRangeQuery("a", 0, 1000);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(DoublePoint.newRangeQuery("a", 1, 1000)));
|
||||
|
||||
byte[] zeros = new byte[5];
|
||||
byte[] ones = new byte[5];
|
||||
Arrays.fill(ones, (byte) 0xff);
|
||||
q = BinaryPoint.newRangeQuery("a", new byte[][] {zeros}, new byte[][] {ones});
|
||||
assertEquals(q, BinaryPoint.newRangeQuery("a", new byte[][] {zeros}, new byte[][] {ones}));
|
||||
q1 = BinaryPoint.newRangeQuery("a", new byte[][] {zeros}, new byte[][] {ones});
|
||||
q2 = BinaryPoint.newRangeQuery("a", new byte[][] {zeros}, new byte[][] {ones});
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
byte[] other = ones.clone();
|
||||
other[2] = (byte) 5;
|
||||
assertFalse(q.equals(BinaryPoint.newRangeQuery("a", new byte[][] {zeros}, new byte[][] {other})));
|
||||
assertFalse(q1.equals(BinaryPoint.newRangeQuery("a", new byte[][] {zeros}, new byte[][] {other})));
|
||||
}
|
||||
|
||||
public void testPointExactEquals() {
|
||||
Query q = IntPoint.newExactQuery("a", 1000);
|
||||
assertEquals(q, IntPoint.newExactQuery("a", 1000));
|
||||
assertFalse(q.equals(IntPoint.newExactQuery("a", 1)));
|
||||
Query q1 = IntPoint.newExactQuery("a", 1000);
|
||||
Query q2 = IntPoint.newExactQuery("a", 1000);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(IntPoint.newExactQuery("a", 1)));
|
||||
|
||||
q = LongPoint.newExactQuery("a", 1000);
|
||||
assertEquals(q, LongPoint.newExactQuery("a", 1000));
|
||||
assertFalse(q.equals(LongPoint.newExactQuery("a", 1)));
|
||||
q1 = LongPoint.newExactQuery("a", 1000);
|
||||
q2 = LongPoint.newExactQuery("a", 1000);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(LongPoint.newExactQuery("a", 1)));
|
||||
|
||||
q = FloatPoint.newExactQuery("a", 1000);
|
||||
assertEquals(q, FloatPoint.newExactQuery("a", 1000));
|
||||
assertFalse(q.equals(FloatPoint.newExactQuery("a", 1)));
|
||||
q1 = FloatPoint.newExactQuery("a", 1000);
|
||||
q2 = FloatPoint.newExactQuery("a", 1000);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(FloatPoint.newExactQuery("a", 1)));
|
||||
|
||||
q = DoublePoint.newExactQuery("a", 1000);
|
||||
assertEquals(q, DoublePoint.newExactQuery("a", 1000));
|
||||
assertFalse(q.equals(DoublePoint.newExactQuery("a", 1)));
|
||||
q1 = DoublePoint.newExactQuery("a", 1000);
|
||||
q2 = DoublePoint.newExactQuery("a", 1000);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(DoublePoint.newExactQuery("a", 1)));
|
||||
|
||||
byte[] ones = new byte[5];
|
||||
Arrays.fill(ones, (byte) 0xff);
|
||||
q = BinaryPoint.newExactQuery("a", ones);
|
||||
assertEquals(q, BinaryPoint.newExactQuery("a", ones));
|
||||
q1 = BinaryPoint.newExactQuery("a", ones);
|
||||
q2 = BinaryPoint.newExactQuery("a", ones);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
byte[] other = ones.clone();
|
||||
other[2] = (byte) 5;
|
||||
assertFalse(q.equals(BinaryPoint.newExactQuery("a", other)));
|
||||
assertFalse(q1.equals(BinaryPoint.newExactQuery("a", other)));
|
||||
}
|
||||
|
||||
public void testPointInSetEquals() {
|
||||
Query q = IntPoint.newSetQuery("a", 0, 1000, 17);
|
||||
assertEquals(q, IntPoint.newSetQuery("a", 17, 0, 1000));
|
||||
assertFalse(q.equals(IntPoint.newSetQuery("a", 1, 17, 1000)));
|
||||
Query q1 = IntPoint.newSetQuery("a", 0, 1000, 17);
|
||||
Query q2 = IntPoint.newSetQuery("a", 17, 0, 1000);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(IntPoint.newSetQuery("a", 1, 17, 1000)));
|
||||
|
||||
q = LongPoint.newSetQuery("a", 0, 1000, 17);
|
||||
assertEquals(q, LongPoint.newSetQuery("a", 17, 0, 1000));
|
||||
assertFalse(q.equals(LongPoint.newSetQuery("a", 1, 17, 1000)));
|
||||
q1 = LongPoint.newSetQuery("a", 0, 1000, 17);
|
||||
q2 = LongPoint.newSetQuery("a", 17, 0, 1000);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(LongPoint.newSetQuery("a", 1, 17, 1000)));
|
||||
|
||||
q = FloatPoint.newSetQuery("a", 0, 1000, 17);
|
||||
assertEquals(q, FloatPoint.newSetQuery("a", 17, 0, 1000));
|
||||
assertFalse(q.equals(FloatPoint.newSetQuery("a", 1, 17, 1000)));
|
||||
q1 = FloatPoint.newSetQuery("a", 0, 1000, 17);
|
||||
q2 = FloatPoint.newSetQuery("a", 17, 0, 1000);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(FloatPoint.newSetQuery("a", 1, 17, 1000)));
|
||||
|
||||
q = DoublePoint.newSetQuery("a", 0, 1000, 17);
|
||||
assertEquals(q, DoublePoint.newSetQuery("a", 17, 0, 1000));
|
||||
assertFalse(q.equals(DoublePoint.newSetQuery("a", 1, 17, 1000)));
|
||||
q1 = DoublePoint.newSetQuery("a", 0, 1000, 17);
|
||||
q2 = DoublePoint.newSetQuery("a", 17, 0, 1000);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(DoublePoint.newSetQuery("a", 1, 17, 1000)));
|
||||
|
||||
byte[] zeros = new byte[5];
|
||||
byte[] ones = new byte[5];
|
||||
Arrays.fill(ones, (byte) 0xff);
|
||||
q = BinaryPoint.newSetQuery("a", new byte[][] {zeros, ones});
|
||||
assertEquals(q, BinaryPoint.newSetQuery("a", new byte[][] {zeros, ones}));
|
||||
q1 = BinaryPoint.newSetQuery("a", new byte[][] {zeros, ones});
|
||||
q2 = BinaryPoint.newSetQuery("a", new byte[][] {zeros, ones});
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
byte[] other = ones.clone();
|
||||
other[2] = (byte) 5;
|
||||
assertFalse(q.equals(BinaryPoint.newSetQuery("a", new byte[][] {zeros, other})));
|
||||
assertFalse(q1.equals(BinaryPoint.newSetQuery("a", new byte[][] {zeros, other})));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,16 +129,6 @@ public class BigIntegerPoint extends Field {
|
|||
result.append('>');
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/** sugar: Encode n-dimensional BigInteger values into binary encoding */
|
||||
private static byte[][] encode(BigInteger value[]) {
|
||||
byte[][] encoded = new byte[value.length][];
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
encoded[i] = new byte[BYTES];
|
||||
encodeDimension(value[i], encoded[i], 0);
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
// public helper methods (e.g. for queries)
|
||||
|
||||
|
@ -212,7 +202,7 @@ public class BigIntegerPoint extends Field {
|
|||
*/
|
||||
public static Query newRangeQuery(String field, BigInteger[] lowerValue, BigInteger[] upperValue) {
|
||||
PointRangeQuery.checkArgs(field, lowerValue, upperValue);
|
||||
return new PointRangeQuery(field, BigIntegerPoint.encode(lowerValue), BigIntegerPoint.encode(upperValue)) {
|
||||
return new PointRangeQuery(field, pack(lowerValue).bytes, pack(upperValue).bytes, lowerValue.length) {
|
||||
@Override
|
||||
protected String toString(int dimension, byte[] value) {
|
||||
return BigIntegerPoint.decodeDimension(value, 0).toString();
|
||||
|
|
|
@ -196,11 +196,7 @@ public class InetAddressPoint extends Field {
|
|||
*/
|
||||
public static Query newRangeQuery(String field, InetAddress lowerValue, InetAddress upperValue) {
|
||||
PointRangeQuery.checkArgs(field, lowerValue, upperValue);
|
||||
byte[][] lowerBytes = new byte[1][];
|
||||
lowerBytes[0] = encode(lowerValue);
|
||||
byte[][] upperBytes = new byte[1][];
|
||||
upperBytes[0] = encode(upperValue);
|
||||
return new PointRangeQuery(field, lowerBytes, upperBytes) {
|
||||
return new PointRangeQuery(field, encode(lowerValue), encode(upperValue), 1) {
|
||||
@Override
|
||||
protected String toString(int dimension, byte[] value) {
|
||||
return decode(value).getHostAddress(); // for ranges, the range itself is already bracketed
|
||||
|
|
|
@ -206,13 +206,11 @@ public class LatLonPoint extends Field {
|
|||
return decodeLongitude(NumericUtils.sortableBytesToInt(src, offset));
|
||||
}
|
||||
|
||||
/** sugar encodes a single point as a 2D byte array */
|
||||
private static byte[][] encode(double latitude, double longitude) {
|
||||
byte[][] bytes = new byte[2][];
|
||||
bytes[0] = new byte[4];
|
||||
NumericUtils.intToSortableBytes(encodeLatitude(latitude), bytes[0], 0);
|
||||
bytes[1] = new byte[4];
|
||||
NumericUtils.intToSortableBytes(encodeLongitude(longitude), bytes[1], 0);
|
||||
/** sugar encodes a single point as a byte array */
|
||||
private static byte[] encode(double latitude, double longitude) {
|
||||
byte[] bytes = new byte[2 * Integer.BYTES];
|
||||
NumericUtils.intToSortableBytes(encodeLatitude(latitude), bytes, 0);
|
||||
NumericUtils.intToSortableBytes(encodeLongitude(longitude), bytes, Integer.BYTES);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
@ -251,8 +249,8 @@ public class LatLonPoint extends Field {
|
|||
* @throws IllegalArgumentException if {@code field} is null, or the box has invalid coordinates.
|
||||
*/
|
||||
public static Query newBoxQuery(String field, double minLatitude, double maxLatitude, double minLongitude, double maxLongitude) {
|
||||
byte[][] lower = encode(minLatitude, minLongitude);
|
||||
byte[][] upper = encode(maxLatitude, maxLongitude);
|
||||
byte[] lower = encode(minLatitude, minLongitude);
|
||||
byte[] upper = encode(maxLatitude, maxLongitude);
|
||||
// Crosses date line: we just rewrite into OR of two bboxes, with longitude as an open range:
|
||||
if (maxLongitude < minLongitude) {
|
||||
// Disable coord here because a multi-valued doc could match both rects and get unfairly boosted:
|
||||
|
@ -260,19 +258,15 @@ public class LatLonPoint extends Field {
|
|||
q.setDisableCoord(true);
|
||||
|
||||
// E.g.: maxLon = -179, minLon = 179
|
||||
byte[][] leftOpen = new byte[2][];
|
||||
leftOpen[0] = lower[0];
|
||||
byte[] leftOpen = lower.clone();
|
||||
// leave longitude open
|
||||
leftOpen[1] = new byte[Integer.BYTES];
|
||||
NumericUtils.intToSortableBytes(Integer.MIN_VALUE, leftOpen[1], 0);
|
||||
NumericUtils.intToSortableBytes(Integer.MIN_VALUE, leftOpen, Integer.BYTES);
|
||||
Query left = newBoxInternal(field, leftOpen, upper);
|
||||
q.add(new BooleanClause(left, BooleanClause.Occur.SHOULD));
|
||||
|
||||
byte[][] rightOpen = new byte[2][];
|
||||
rightOpen[0] = upper[0];
|
||||
byte[] rightOpen = upper.clone();
|
||||
// leave longitude open
|
||||
rightOpen[1] = new byte[Integer.BYTES];
|
||||
NumericUtils.intToSortableBytes(Integer.MAX_VALUE, rightOpen[1], 0);
|
||||
NumericUtils.intToSortableBytes(Integer.MAX_VALUE, rightOpen, Integer.BYTES);
|
||||
Query right = newBoxInternal(field, lower, rightOpen);
|
||||
q.add(new BooleanClause(right, BooleanClause.Occur.SHOULD));
|
||||
return new ConstantScoreQuery(q.build());
|
||||
|
@ -281,8 +275,8 @@ public class LatLonPoint extends Field {
|
|||
}
|
||||
}
|
||||
|
||||
private static Query newBoxInternal(String field, byte[][] min, byte[][] max) {
|
||||
return new PointRangeQuery(field, min, max) {
|
||||
private static Query newBoxInternal(String field, byte[] min, byte[] max) {
|
||||
return new PointRangeQuery(field, min, max, 2) {
|
||||
@Override
|
||||
protected String toString(int dimension, byte[] value) {
|
||||
if (dimension == 0) {
|
||||
|
|
|
@ -96,16 +96,22 @@ public class TestBigIntegerPoint extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testQueryEquals() throws Exception {
|
||||
Query q = BigIntegerPoint.newRangeQuery("a", BigInteger.valueOf(0), BigInteger.valueOf(1000));
|
||||
assertEquals(q, BigIntegerPoint.newRangeQuery("a", BigInteger.valueOf(0), BigInteger.valueOf(1000)));
|
||||
assertFalse(q.equals(BigIntegerPoint.newRangeQuery("a", BigInteger.valueOf(1), BigInteger.valueOf(1000))));
|
||||
Query q1 = BigIntegerPoint.newRangeQuery("a", BigInteger.valueOf(0), BigInteger.valueOf(1000));
|
||||
Query q2 = BigIntegerPoint.newRangeQuery("a", BigInteger.valueOf(0), BigInteger.valueOf(1000));
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(BigIntegerPoint.newRangeQuery("a", BigInteger.valueOf(1), BigInteger.valueOf(1000))));
|
||||
|
||||
q = BigIntegerPoint.newExactQuery("a", BigInteger.valueOf(1000));
|
||||
assertEquals(q, BigIntegerPoint.newExactQuery("a", BigInteger.valueOf(1000)));
|
||||
assertFalse(q.equals(BigIntegerPoint.newExactQuery("a", BigInteger.valueOf(1))));
|
||||
q1 = BigIntegerPoint.newExactQuery("a", BigInteger.valueOf(1000));
|
||||
q2 = BigIntegerPoint.newExactQuery("a", BigInteger.valueOf(1000));
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(BigIntegerPoint.newExactQuery("a", BigInteger.valueOf(1))));
|
||||
|
||||
q = BigIntegerPoint.newSetQuery("a", BigInteger.valueOf(0), BigInteger.valueOf(1000), BigInteger.valueOf(17));
|
||||
assertEquals(q, BigIntegerPoint.newSetQuery("a", BigInteger.valueOf(17), BigInteger.valueOf(0), BigInteger.valueOf(1000)));
|
||||
assertFalse(q.equals(BigIntegerPoint.newSetQuery("a", BigInteger.valueOf(1), BigInteger.valueOf(17), BigInteger.valueOf(1000))));
|
||||
q1 = BigIntegerPoint.newSetQuery("a", BigInteger.valueOf(0), BigInteger.valueOf(1000), BigInteger.valueOf(17));
|
||||
q2 = BigIntegerPoint.newSetQuery("a", BigInteger.valueOf(17), BigInteger.valueOf(0), BigInteger.valueOf(1000));
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(BigIntegerPoint.newSetQuery("a", BigInteger.valueOf(1), BigInteger.valueOf(17), BigInteger.valueOf(1000))));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,21 +92,29 @@ public class TestInetAddressPoint extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testQueryEquals() throws Exception {
|
||||
Query q = InetAddressPoint.newRangeQuery("a", InetAddress.getByName("1.2.3.3"), InetAddress.getByName("1.2.3.5"));
|
||||
assertEquals(q, InetAddressPoint.newRangeQuery("a", InetAddress.getByName("1.2.3.3"), InetAddress.getByName("1.2.3.5")));
|
||||
assertFalse(q.equals(InetAddressPoint.newRangeQuery("a", InetAddress.getByName("1.2.3.3"), InetAddress.getByName("1.2.3.7"))));
|
||||
Query q1 = InetAddressPoint.newRangeQuery("a", InetAddress.getByName("1.2.3.3"), InetAddress.getByName("1.2.3.5"));
|
||||
Query q2 = InetAddressPoint.newRangeQuery("a", InetAddress.getByName("1.2.3.3"), InetAddress.getByName("1.2.3.5"));
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(InetAddressPoint.newRangeQuery("a", InetAddress.getByName("1.2.3.3"), InetAddress.getByName("1.2.3.7"))));
|
||||
|
||||
q = InetAddressPoint.newPrefixQuery("a", InetAddress.getByName("1.2.3.3"), 16);
|
||||
assertEquals(q, InetAddressPoint.newPrefixQuery("a", InetAddress.getByName("1.2.3.3"), 16));
|
||||
assertFalse(q.equals(InetAddressPoint.newPrefixQuery("a", InetAddress.getByName("1.1.3.5"), 16)));
|
||||
assertFalse(q.equals(InetAddressPoint.newPrefixQuery("a", InetAddress.getByName("1.2.3.5"), 24)));
|
||||
q1 = InetAddressPoint.newPrefixQuery("a", InetAddress.getByName("1.2.3.3"), 16);
|
||||
q2 = InetAddressPoint.newPrefixQuery("a", InetAddress.getByName("1.2.3.3"), 16);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(InetAddressPoint.newPrefixQuery("a", InetAddress.getByName("1.1.3.5"), 16)));
|
||||
assertFalse(q1.equals(InetAddressPoint.newPrefixQuery("a", InetAddress.getByName("1.2.3.5"), 24)));
|
||||
|
||||
q = InetAddressPoint.newExactQuery("a", InetAddress.getByName("1.2.3.3"));
|
||||
assertEquals(q, InetAddressPoint.newExactQuery("a", InetAddress.getByName("1.2.3.3")));
|
||||
assertFalse(q.equals(InetAddressPoint.newExactQuery("a", InetAddress.getByName("1.2.3.5"))));
|
||||
q1 = InetAddressPoint.newExactQuery("a", InetAddress.getByName("1.2.3.3"));
|
||||
q2 = InetAddressPoint.newExactQuery("a", InetAddress.getByName("1.2.3.3"));
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(InetAddressPoint.newExactQuery("a", InetAddress.getByName("1.2.3.5"))));
|
||||
|
||||
q = InetAddressPoint.newSetQuery("a", InetAddress.getByName("1.2.3.3"), InetAddress.getByName("1.2.3.5"));
|
||||
assertEquals(q, InetAddressPoint.newSetQuery("a", InetAddress.getByName("1.2.3.3"), InetAddress.getByName("1.2.3.5")));
|
||||
assertFalse(q.equals(InetAddressPoint.newSetQuery("a", InetAddress.getByName("1.2.3.3"), InetAddress.getByName("1.2.3.7"))));
|
||||
q1 = InetAddressPoint.newSetQuery("a", InetAddress.getByName("1.2.3.3"), InetAddress.getByName("1.2.3.5"));
|
||||
q2 = InetAddressPoint.newSetQuery("a", InetAddress.getByName("1.2.3.3"), InetAddress.getByName("1.2.3.5"));
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(InetAddressPoint.newSetQuery("a", InetAddress.getByName("1.2.3.3"), InetAddress.getByName("1.2.3.7"))));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,21 +186,27 @@ public class TestLatLonPoint extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testQueryEquals() throws Exception {
|
||||
Query q = LatLonPoint.newBoxQuery("field", 50, 70, -40, 20);
|
||||
assertEquals(q, LatLonPoint.newBoxQuery("field", 50, 70, -40, 20));
|
||||
assertFalse(q.equals(LatLonPoint.newBoxQuery("field", 50, 70, -40, 10)));
|
||||
Query q1 = LatLonPoint.newBoxQuery("field", 50, 70, -40, 20);
|
||||
Query q2 = LatLonPoint.newBoxQuery("field", 50, 70, -40, 20);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(LatLonPoint.newBoxQuery("field", 50, 70, -40, 10)));
|
||||
|
||||
q = LatLonPoint.newDistanceQuery("field", 50, 70, 10000);
|
||||
assertEquals(q, LatLonPoint.newDistanceQuery("field", 50, 70, 10000));
|
||||
assertFalse(q.equals(LatLonPoint.newDistanceQuery("field", 50, 70, 11000)));
|
||||
assertFalse(q.equals(LatLonPoint.newDistanceQuery("field", 50, 60, 10000)));
|
||||
q1 = LatLonPoint.newDistanceQuery("field", 50, 70, 10000);
|
||||
q2 = LatLonPoint.newDistanceQuery("field", 50, 70, 10000);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(LatLonPoint.newDistanceQuery("field", 50, 70, 11000)));
|
||||
assertFalse(q1.equals(LatLonPoint.newDistanceQuery("field", 50, 60, 10000)));
|
||||
|
||||
|
||||
double[] polyLats1 = new double[] {30, 40, 40, 30, 30};
|
||||
double[] polyLons1 = new double[] {90, 90, -40, -40, 90};
|
||||
double[] polyLats2 = new double[] {20, 40, 40, 20, 20};
|
||||
q = LatLonPoint.newPolygonQuery("field", polyLats1, polyLons1);
|
||||
assertEquals(q, LatLonPoint.newPolygonQuery("field", polyLats1, polyLons1));
|
||||
assertFalse(q.equals(LatLonPoint.newPolygonQuery("field", polyLats2, polyLons1)));
|
||||
q1 = LatLonPoint.newPolygonQuery("field", polyLats1, polyLons1);
|
||||
q2 = LatLonPoint.newPolygonQuery("field", polyLats1, polyLons1);
|
||||
assertEquals(q1, q2);
|
||||
assertEquals(q1.hashCode(), q2.hashCode());
|
||||
assertFalse(q1.equals(LatLonPoint.newPolygonQuery("field", polyLats2, polyLons1)));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue