mirror of https://github.com/apache/lucene.git
LUCENE-7234: Add InetAddressPoint.nextUp/nextDown
This commit is contained in:
parent
2724b99b5c
commit
91fd163112
|
@ -19,6 +19,9 @@ New Features
|
||||||
* LUCENE-7069: Add LatLonPoint.nearest, to find nearest N points to a
|
* LUCENE-7069: Add LatLonPoint.nearest, to find nearest N points to a
|
||||||
provided query point (Mike McCandless)
|
provided query point (Mike McCandless)
|
||||||
|
|
||||||
|
* LUCENE-7234: Added InetAddressPoint.nextDown/nextUp to easily generate range
|
||||||
|
queries with excluded bounds. (Adrien Grand)
|
||||||
|
|
||||||
API Changes
|
API Changes
|
||||||
|
|
||||||
* LUCENE-7184: Refactor LatLonPoint encoding methods to new GeoEncodingUtils
|
* LUCENE-7184: Refactor LatLonPoint encoding methods to new GeoEncodingUtils
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.lucene.search.PointInSetQuery;
|
||||||
import org.apache.lucene.search.PointRangeQuery;
|
import org.apache.lucene.search.PointRangeQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
|
import org.apache.lucene.util.NumericUtils;
|
||||||
import org.apache.lucene.util.StringHelper;
|
import org.apache.lucene.util.StringHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,6 +66,53 @@ public class InetAddressPoint extends Field {
|
||||||
TYPE.freeze();
|
TYPE.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The minimum value that an ip address can hold. */
|
||||||
|
public static final InetAddress MIN_VALUE;
|
||||||
|
/** The maximum value that an ip address can hold. */
|
||||||
|
public static final InetAddress MAX_VALUE;
|
||||||
|
static {
|
||||||
|
MIN_VALUE = decode(new byte[BYTES]);
|
||||||
|
byte[] maxValueBytes = new byte[BYTES];
|
||||||
|
Arrays.fill(maxValueBytes, (byte) 0xFF);
|
||||||
|
MAX_VALUE = decode(maxValueBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link InetAddress} that compares immediately greater than
|
||||||
|
* {@code address}.
|
||||||
|
* @throws ArithmeticException if the provided address is the
|
||||||
|
* {@link #MAX_VALUE maximum ip address}
|
||||||
|
*/
|
||||||
|
public static InetAddress nextUp(InetAddress address) {
|
||||||
|
if (address.equals(MAX_VALUE)) {
|
||||||
|
throw new ArithmeticException("Overflow: there is no greater InetAddress than "
|
||||||
|
+ address.getHostAddress());
|
||||||
|
}
|
||||||
|
byte[] delta = new byte[BYTES];
|
||||||
|
delta[BYTES-1] = 1;
|
||||||
|
byte[] nextUpBytes = new byte[InetAddressPoint.BYTES];
|
||||||
|
NumericUtils.add(InetAddressPoint.BYTES, 0, encode(address), delta, nextUpBytes);
|
||||||
|
return decode(nextUpBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link InetAddress} that compares immediately less than
|
||||||
|
* {@code address}.
|
||||||
|
* @throws ArithmeticException if the provided address is the
|
||||||
|
* {@link #MIN_VALUE minimum ip address}
|
||||||
|
*/
|
||||||
|
public static InetAddress nextDown(InetAddress address) {
|
||||||
|
if (address.equals(MIN_VALUE)) {
|
||||||
|
throw new ArithmeticException("Underflow: there is no smaller InetAddress than "
|
||||||
|
+ address.getHostAddress());
|
||||||
|
}
|
||||||
|
byte[] delta = new byte[BYTES];
|
||||||
|
delta[BYTES-1] = 1;
|
||||||
|
byte[] nextDownBytes = new byte[InetAddressPoint.BYTES];
|
||||||
|
NumericUtils.subtract(InetAddressPoint.BYTES, 0, encode(address), delta, nextDownBytes);
|
||||||
|
return decode(nextDownBytes);
|
||||||
|
}
|
||||||
|
|
||||||
/** Change the values of this field */
|
/** Change the values of this field */
|
||||||
public void setInetAddressValue(InetAddress value) {
|
public void setInetAddressValue(InetAddress value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
@ -187,6 +235,12 @@ public class InetAddressPoint extends Field {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a range query for network addresses.
|
* Create a range query for network addresses.
|
||||||
|
* <p>
|
||||||
|
* You can have half-open ranges (which are in fact </≤ or >/≥ queries)
|
||||||
|
* by setting {@code lowerValue = InetAddressPoint.MIN_VALUE} or
|
||||||
|
* {@code upperValue = InetAddressPoint.MAX_VALUE}.
|
||||||
|
* <p> Ranges are inclusive. For exclusive ranges, pass {@code InetAddressPoint#nextUp(lowerValue)}
|
||||||
|
* or {@code InetAddressPoint#nexDown(upperValue)}.
|
||||||
*
|
*
|
||||||
* @param field field name. must not be {@code null}.
|
* @param field field name. must not be {@code null}.
|
||||||
* @param lowerValue lower portion of the range (inclusive). must not be null.
|
* @param lowerValue lower portion of the range (inclusive). must not be null.
|
||||||
|
|
|
@ -131,4 +131,46 @@ public class TestInetAddressPoint extends LuceneTestCase {
|
||||||
InetAddressPoint.newRangeQuery("a", InetAddress.getByName("2001::a000:0"), InetAddress.getByName("2001::afff:ffff")),
|
InetAddressPoint.newRangeQuery("a", InetAddress.getByName("2001::a000:0"), InetAddress.getByName("2001::afff:ffff")),
|
||||||
InetAddressPoint.newPrefixQuery("a", InetAddress.getByName("2001::a6bd:fc80"), 100));
|
InetAddressPoint.newPrefixQuery("a", InetAddress.getByName("2001::a6bd:fc80"), 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testNextUp() throws Exception {
|
||||||
|
assertEquals(InetAddress.getByName("::1"),
|
||||||
|
InetAddressPoint.nextUp(InetAddress.getByName("::")));
|
||||||
|
|
||||||
|
assertEquals(InetAddress.getByName("::1:0"),
|
||||||
|
InetAddressPoint.nextUp(InetAddress.getByName("::ffff")));
|
||||||
|
|
||||||
|
assertEquals(InetAddress.getByName("1.2.4.0"),
|
||||||
|
InetAddressPoint.nextUp(InetAddress.getByName("1.2.3.255")));
|
||||||
|
|
||||||
|
assertEquals(InetAddress.getByName("0.0.0.0"),
|
||||||
|
InetAddressPoint.nextUp(InetAddress.getByName("::fffe:ffff:ffff")));
|
||||||
|
|
||||||
|
assertEquals(InetAddress.getByName("::1:0:0:0"),
|
||||||
|
InetAddressPoint.nextUp(InetAddress.getByName("255.255.255.255")));
|
||||||
|
|
||||||
|
ArithmeticException e = expectThrows(ArithmeticException.class,
|
||||||
|
() -> InetAddressPoint.nextUp(InetAddress.getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
|
||||||
|
assertEquals("Overflow: there is no greater InetAddress than ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNextDown() throws Exception {
|
||||||
|
assertEquals(InetAddress.getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe"),
|
||||||
|
InetAddressPoint.nextDown(InetAddress.getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
|
||||||
|
|
||||||
|
assertEquals(InetAddress.getByName("::ffff"),
|
||||||
|
InetAddressPoint.nextDown(InetAddress.getByName("::1:0")));
|
||||||
|
|
||||||
|
assertEquals(InetAddress.getByName("1.2.3.255"),
|
||||||
|
InetAddressPoint.nextDown(InetAddress.getByName("1.2.4.0")));
|
||||||
|
|
||||||
|
assertEquals(InetAddress.getByName("::fffe:ffff:ffff"),
|
||||||
|
InetAddressPoint.nextDown(InetAddress.getByName("0.0.0.0")));
|
||||||
|
|
||||||
|
assertEquals(InetAddress.getByName("255.255.255.255"),
|
||||||
|
InetAddressPoint.nextDown(InetAddress.getByName("::1:0:0:0")));
|
||||||
|
|
||||||
|
ArithmeticException e = expectThrows(ArithmeticException.class,
|
||||||
|
() -> InetAddressPoint.nextDown(InetAddress.getByName("::")));
|
||||||
|
assertEquals("Underflow: there is no smaller InetAddress than 0:0:0:0:0:0:0:0", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue