mirror of https://github.com/apache/lucene.git
Add first pass for NumberUtils, adapted from code contributed by Matt Quail.
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@150666 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6bf1504200
commit
d0623a8e13
|
@ -48,7 +48,11 @@ New features
|
|||
9. Added javadocs-internal to build.xml - bug #30360
|
||||
(Paul Elschot via Otis)
|
||||
|
||||
10. Added RangeFilter. (Chris M Hostetter via Erik)
|
||||
10. Added RangeFilter, a more generically useful filter than DateFilter.
|
||||
(Chris M Hostetter via Erik)
|
||||
|
||||
11. Added NumberTools, a utility class indexing numeric fields.
|
||||
(adapted from code contributed by Matt Quail; committed by Erik)
|
||||
|
||||
API Changes
|
||||
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
package org.apache.lucene.document;
|
||||
|
||||
/**
|
||||
* Copyright 2004 The Apache Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Provides support for converting longs to Strings, and back again. The strings
|
||||
* are structured so that lexicographic sorting order is preserved.
|
||||
*
|
||||
* <p>
|
||||
* That is, if l1 is less than l2 for any two longs l1 and l2, then
|
||||
* LongField.longToString(l1) is lexicographically less than
|
||||
* LongField.longToString(l2). (Similarly for "greater than" and "equals".)
|
||||
*
|
||||
* <p>
|
||||
* This class handles <b>all</b> long values (unlike
|
||||
* {@link org.apache.lucene.document.DateField}).
|
||||
*
|
||||
* @author Matt Quail (spud at madbean dot com)
|
||||
*/
|
||||
public class NumberTools {
|
||||
|
||||
private static final int RADIX = 36;
|
||||
|
||||
private static final char NEGATIVE_PREFIX = '-';
|
||||
|
||||
// NB: NEGATIVE_PREFIX must be < POSITIVE_PREFIX
|
||||
private static final char POSITIVE_PREFIX = '0';
|
||||
|
||||
//NB: this must be less than
|
||||
/**
|
||||
* Equivalent to longToString(Long.MIN_VALUE)
|
||||
*/
|
||||
public static final String MIN_STRING_VALUE = NEGATIVE_PREFIX
|
||||
+ "0000000000000";
|
||||
|
||||
/**
|
||||
* Equivalent to longToString(Long.MAX_VALUE)
|
||||
*/
|
||||
public static final String MAX_STRING_VALUE = POSITIVE_PREFIX
|
||||
+ "1y2p0ij32e8e7";
|
||||
|
||||
/**
|
||||
* the length of (all) strings returned by {@link #longToString}
|
||||
*/
|
||||
public static final int STR_SIZE = MIN_STRING_VALUE.length();
|
||||
|
||||
/**
|
||||
* Converts a long to a String suitable for indexing.
|
||||
*/
|
||||
public static String longToString(long l) {
|
||||
|
||||
if (l == Long.MIN_VALUE) {
|
||||
// special case, because long is not symetric around zero
|
||||
return MIN_STRING_VALUE;
|
||||
}
|
||||
|
||||
StringBuffer buf = new StringBuffer(STR_SIZE);
|
||||
|
||||
if (l < 0) {
|
||||
buf.append(NEGATIVE_PREFIX);
|
||||
l = Long.MAX_VALUE + l + 1;
|
||||
} else {
|
||||
buf.append(POSITIVE_PREFIX);
|
||||
}
|
||||
String num = Long.toString(l, RADIX);
|
||||
|
||||
int padLen = STR_SIZE - num.length() - buf.length();
|
||||
while (padLen-- > 0) {
|
||||
buf.append('0');
|
||||
}
|
||||
buf.append(num);
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a String that was returned by {@link #longToString}back to a
|
||||
* long.
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if the input is null
|
||||
* @throws NumberFormatException
|
||||
* if the input does not parse (it was not a String returned by
|
||||
* longToString()).
|
||||
*/
|
||||
public static long stringToLong(String str) {
|
||||
if (str == null) {
|
||||
throw new IllegalArgumentException("string cannot be null");
|
||||
}
|
||||
if (str.length() != STR_SIZE) {
|
||||
throw new NumberFormatException("string is the wrong size");
|
||||
}
|
||||
|
||||
if (str.equals(MIN_STRING_VALUE)) {
|
||||
return Long.MIN_VALUE;
|
||||
}
|
||||
|
||||
char prefix = str.charAt(0);
|
||||
long l = Long.parseLong(str.substring(1), RADIX);
|
||||
|
||||
if (prefix == POSITIVE_PREFIX) {
|
||||
// nop
|
||||
} else if (prefix == NEGATIVE_PREFIX) {
|
||||
l = l - Long.MAX_VALUE - 1;
|
||||
} else {
|
||||
throw new NumberFormatException(
|
||||
"string does not begin with the correct prefix");
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package org.apache.lucene.document;
|
||||
|
||||
/**
|
||||
* Copyright 2004 The Apache Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class TestNumberTools extends TestCase {
|
||||
public void testNearZero() {
|
||||
for (int i = -100; i <= 100; i++) {
|
||||
for (int j = -100; j <= 100; j++) {
|
||||
subtestTwoLongs(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testMax() {
|
||||
// make sure the constants convert to their equivelents
|
||||
assertEquals(Long.MAX_VALUE, NumberTools
|
||||
.stringToLong(NumberTools.MAX_STRING_VALUE));
|
||||
assertEquals(NumberTools.MAX_STRING_VALUE, NumberTools
|
||||
.longToString(Long.MAX_VALUE));
|
||||
|
||||
// test near MAX, too
|
||||
for (long l = Long.MAX_VALUE; l > Long.MAX_VALUE - 10000; l--) {
|
||||
subtestTwoLongs(l, l - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void testMin() {
|
||||
// make sure the constants convert to their equivelents
|
||||
assertEquals(Long.MIN_VALUE, NumberTools
|
||||
.stringToLong(NumberTools.MIN_STRING_VALUE));
|
||||
assertEquals(NumberTools.MIN_STRING_VALUE, NumberTools
|
||||
.longToString(Long.MIN_VALUE));
|
||||
|
||||
// test near MIN, too
|
||||
for (long l = Long.MIN_VALUE; l < Long.MIN_VALUE + 10000; l++) {
|
||||
subtestTwoLongs(l, l + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private static void subtestTwoLongs(long i, long j) {
|
||||
// convert to strings
|
||||
String a = NumberTools.longToString(i);
|
||||
String b = NumberTools.longToString(j);
|
||||
|
||||
// are they the right length?
|
||||
assertEquals(NumberTools.STR_SIZE, a.length());
|
||||
assertEquals(NumberTools.STR_SIZE, b.length());
|
||||
|
||||
// are they the right order?
|
||||
if (i < j) {
|
||||
assertTrue(a.compareTo(b) < 0);
|
||||
} else if (i > j) {
|
||||
assertTrue(a.compareTo(b) > 0);
|
||||
} else {
|
||||
assertEquals(a, b);
|
||||
}
|
||||
|
||||
// can we convert them back to longs?
|
||||
long i2 = NumberTools.stringToLong(a);
|
||||
long j2 = NumberTools.stringToLong(b);
|
||||
|
||||
assertEquals(i, i2);
|
||||
assertEquals(j, j2);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue