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:
Erik Hatcher 2004-11-23 21:07:49 +00:00
parent 6bf1504200
commit d0623a8e13
3 changed files with 213 additions and 1 deletions

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);
}
}