001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.solr.util.test;
017:
018: import org.apache.solr.util.NumberUtils;
019: import org.apache.solr.util.BCDUtils;
020:
021: import java.util.Random;
022:
023: /**
024: * @author yonik
025: */
026:
027: public class TestNumberUtils {
028:
029: private static String arrstr(char[] arr, int start, int end) {
030: String str = "[";
031: for (int i = start; i < end; i++)
032: str += arr[i] + "(" + (int) arr[i] + "),";
033: return str + "]";
034: }
035:
036: static Random rng = new Random();
037:
038: static int[] special = { 0, 10, 100, 1000, 10000,
039: Integer.MAX_VALUE, Integer.MIN_VALUE };
040:
041: static int getSpecial() {
042: int i = rng.nextInt();
043: int j = rng.nextInt();
044: if ((i & 0x10) != 0)
045: return j;
046: return special[(j & 0x7fffffff) % special.length]
047: * ((i & 0x20) == 0 ? 1 : -1) + ((i & 0x03) - 1);
048: }
049:
050: static long[] lspecial = { 0, 10, 100, 1000, 10000, 2, 4, 8, 256,
051: 16384, 32768, 65536, Integer.MAX_VALUE, Integer.MIN_VALUE,
052: Long.MAX_VALUE, Long.MIN_VALUE };
053:
054: static long getLongSpecial() {
055: int i = rng.nextInt();
056: long j = rng.nextLong();
057: if ((i & 0x10) != 0)
058: return j;
059: return lspecial[((int) j & 0x7fffffff) % special.length]
060: * ((i & 0x20) == 0 ? 1 : -1) + ((i & 0x03) - 1);
061: }
062:
063: static float[] fspecial = { 0, 1, 2, 4, 8, 256, 16384, 32768,
064: 65536, .1f, .25f, Float.NEGATIVE_INFINITY,
065: Float.POSITIVE_INFINITY, Float.MIN_VALUE, Float.MAX_VALUE };
066:
067: static float getFloatSpecial() {
068: int i = rng.nextInt();
069: int j = rng.nextInt();
070: float f = Float.intBitsToFloat(j);
071: if (f != f)
072: f = 0; // get rid of NaN for comparison purposes
073: if ((i & 0x10) != 0)
074: return f;
075: return fspecial[(j & 0x7fffffff) % fspecial.length]
076: * ((i & 0x20) == 0 ? 1 : -1) + ((i & 0x03) - 1);
077: }
078:
079: static double[] dspecial = { 0, 1, 2, 4, 8, 256, 16384, 32768,
080: 65536, .1, .25, Float.NEGATIVE_INFINITY,
081: Float.POSITIVE_INFINITY, Float.MIN_VALUE, Float.MAX_VALUE,
082: Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
083: Double.MIN_VALUE, Double.MAX_VALUE };
084:
085: static double getDoubleSpecial() {
086: int i = rng.nextInt();
087: long j = rng.nextLong();
088: double f = Double.longBitsToDouble(j);
089: if (f != f)
090: f = 0; // get rid of NaN for comparison purposes
091: if ((i & 0x10) != 0)
092: return f;
093: return dspecial[((int) j & 0x7fffffff) % dspecial.length]
094: * ((i & 0x20) == 0 ? 1 : -1) + ((i & 0x03) - 1);
095: }
096:
097: public static void test(Comparable n1, Comparable n2, Converter conv) {
098: String s1 = n1.toString();
099: String s2 = n2.toString();
100: String v1 = conv.toInternal(s1);
101: String v2 = conv.toInternal(s2);
102: String out1 = conv.toExternal(v1);
103: String out2 = conv.toExternal(v2);
104:
105: int c1 = n1.compareTo(n2);
106: int c2 = v1.compareTo(v2);
107: if (c1 == 0 && !(c2 == 0) || c1 < 0 && !(c2 < 0) || c1 > 0
108: && !(c2 > 0) || !out1.equals(s1) || !out2.equals(s2)) {
109: System.out.println("Comparison error:" + s1 + "," + s2);
110: System.out.print("v1=");
111: for (int ii = 0; ii < v1.length(); ii++) {
112: System.out.print(" " + (int) v1.charAt(ii));
113: }
114: System.out.print("\nv2=");
115: for (int ii = 0; ii < v2.length(); ii++) {
116: System.out.print(" " + (int) v2.charAt(ii));
117: }
118: System.out.println("\nout1='" + out1 + "', out2='" + out2
119: + "'");
120: }
121: }
122:
123: public static void main(String[] args)
124: throws ClassNotFoundException, IllegalAccessException,
125: InstantiationException {
126: int iter = 1000000;
127: int arrsz = 100000;
128: int ret = 0;
129: int num = 0;
130:
131: String test = "b100";
132: String clazz = "NoClass";
133:
134: for (int argnum = 0; argnum < args.length; argnum++) {
135: String arg = args[argnum];
136: if ("-t".equals(arg)) {
137: test = args[++argnum];
138: }
139: if ("-i".equals(arg)) {
140: iter = Integer.parseInt(args[++argnum]);
141: }
142: if ("-a".equals(arg)) {
143: arrsz = Integer.parseInt(args[++argnum]);
144: }
145: if ("-c".equals(arg)) {
146: clazz = args[++argnum];
147: }
148: if ("-r".equals(arg)) {
149: rng.setSeed(Long.parseLong(args[++argnum]));
150: }
151: ;
152: if ("-n".equals(arg)) {
153: num = Integer.parseInt(args[++argnum]);
154: }
155: ;
156:
157: }
158:
159: // Converter conv = (Converter)(Class.forName(clazz).newInstance());
160: Class cls = null;
161: try {
162: cls = Class.forName(clazz);
163: } catch (Exception e) {
164: cls = Class.forName("solr.util.test." + clazz);
165: }
166: Converter conv = (Converter) cls.newInstance();
167:
168: long startTime = System.currentTimeMillis();
169:
170: if ("ispecial".equals(test)) {
171: for (int i = 0; i < iter; i++) {
172: Integer i1 = getSpecial();
173: Integer i2 = getSpecial();
174: test(i1, i2, conv);
175: }
176: } else if ("lspecial".equals(test)) {
177: for (int i = 0; i < iter; i++) {
178: Long f1 = getLongSpecial();
179: Long f2 = getLongSpecial();
180: test(f1, f2, conv);
181: }
182: } else if ("fspecial".equals(test)) {
183: for (int i = 0; i < iter; i++) {
184: Float f1 = getFloatSpecial();
185: Float f2 = getFloatSpecial();
186: test(f1, f2, conv);
187: }
188: } else if ("dspecial".equals(test)) {
189: for (int i = 0; i < iter; i++) {
190: Double f1 = getDoubleSpecial();
191: Double f2 = getDoubleSpecial();
192: test(f1, f2, conv);
193: }
194: } else if ("10kout".equals(test)) {
195: String n = Integer.toString(num);
196: char[] arr = new char[n.length()];
197: char[] arr2 = new char[n.length() + 1];
198: n.getChars(0, n.length(), arr, 0);
199: for (int i = 0; i < iter; i++) {
200: ret += BCDUtils.base10toBase100SortableInt(arr, 0,
201: arr.length, arr2, arr2.length);
202: }
203:
204: } else if ("internal".equals(test) || "external".equals(test)) {
205: int min = -1000000;
206: int max = 1000000;
207: String[] arr = new String[arrsz];
208: String[] internal = new String[arrsz];
209:
210: if ("external".equals(test)) {
211: for (int i = 0; i < arrsz; i++) {
212: int val = rng.nextInt();
213: // todo - move to between min and max...
214: arr[i] = Integer.toString(rng.nextInt());
215: internal[i] = conv.toInternal(arr[i]);
216: }
217: for (int i = 0; i < iter; i++) {
218: int slot = i % arrsz;
219: arr[slot] = conv.toExternal(internal[slot]);
220: ret += arr[slot].length();
221: }
222: } else {
223: for (int i = 0; i < arrsz; i++) {
224: int val = rng.nextInt();
225: // todo - move to between min and max...
226: arr[i] = Integer.toString(rng.nextInt());
227: }
228: for (int i = 0; i < iter; i++) {
229: int slot = i % arrsz;
230: internal[slot] = conv.toInternal(arr[slot]);
231: ret += internal[slot].length();
232: }
233: }
234: } else if ("itest".equals(test) || "ltest".equals(test)
235: || "ftest".equals(test)) {
236: long internalLen = 0;
237: long externalLen = 0;
238: for (int i = 0; i < iter; i++) {
239: Comparable n1 = null, n2 = null;
240:
241: if ("itest".equals(test)) {
242: Integer i1 = rng.nextInt();
243: Integer i2 = rng.nextInt();
244:
245: // concentrate on small numbers for a while
246: // to try and hit boundary cases 0,1,-1,100,-100,etc
247: if (i < 10000) {
248: i1 = (i1 % 250) - 125;
249: i2 = (i2 % 250) - 125;
250: } else if (i < 500000) {
251: i1 = (i1 % 25000) - 12500;
252: i2 = (i2 % 25000) - 12500;
253: }
254:
255: n1 = i1;
256: n2 = i2;
257: } else if ("ltest".equals(test)) {
258: Long i1 = rng.nextLong();
259: Long i2 = rng.nextLong();
260:
261: // concentrate on small numbers for a while
262: // to try and hit boundary cases 0,1,-1,100,-100,etc
263: if (i < 10000) {
264: i1 = (long) (i1 % 250) - 125;
265: i2 = (long) (i2 % 250) - 125;
266: } else if (i < 500000) {
267: i1 = (long) (i1 % 25000) - 12500;
268: i2 = (long) (i2 % 25000) - 12500;
269: }
270:
271: n1 = i1;
272: n2 = i2;
273: } else if ("ftest".equals(test)) {
274: Float i1;
275: Float i2;
276: if (i < 10000) {
277: i1 = (float) (rng.nextInt() % 250) - 125;
278: i2 = (float) (rng.nextInt() % 250) - 125;
279: } else if (i < 300000) {
280: i1 = (float) (rng.nextInt() % 2500) - 1250;
281: i2 = (float) (rng.nextInt() % 2500) - 1250;
282: } else if (i < 500000) {
283: i1 = rng.nextFloat() / rng.nextFloat();
284: i2 = rng.nextFloat() / rng.nextFloat();
285: } else {
286: i1 = Float.intBitsToFloat(rng.nextInt());
287: i2 = Float.intBitsToFloat(rng.nextInt());
288: }
289: n1 = i1;
290: n2 = i2;
291: }
292: String s1 = n1.toString();
293: String s2 = n2.toString();
294: String v1 = conv.toInternal(s1);
295: String v2 = conv.toInternal(s2);
296: String out1 = conv.toExternal(v1);
297: String out2 = conv.toExternal(v2);
298:
299: externalLen += s1.length();
300: internalLen += v1.length();
301:
302: int c1 = n1.compareTo(n2);
303: int c2 = v1.compareTo(v2);
304: if (c1 == 0 && !(c2 == 0) || c1 < 0 && !(c2 < 0)
305: || c1 > 0 && !(c2 > 0) || !out1.equals(s1)
306: || !out2.equals(s2)) {
307: System.out.println("Comparison error:" + s1 + ","
308: + s2);
309: System.out.print("v1=");
310: for (int ii = 0; ii < v1.length(); ii++) {
311: System.out.print(" " + (int) v1.charAt(ii));
312: }
313: System.out.print("\nv2=");
314: for (int ii = 0; ii < v2.length(); ii++) {
315: System.out.print(" " + (int) v2.charAt(ii));
316: }
317: System.out.println("\nout1='" + out1 + "', out2='"
318: + out2 + "'");
319:
320: }
321: }
322: }
323:
324: /******************
325: int sz=20;
326: char[] arr1 = new char[sz];
327: char[] arr2 = new char[sz];
328: char[] arr3 = new char[sz];
329: if ("noconv".equals(test)) {
330: for (int i=0; i<iter; i++) {
331: int val = rng.nextInt();
332: String istr = Integer.toString(val);
333: int n = istr.length();
334: Integer.toString(val).getChars(0, n, arr1, 0);
335: String nStr = new String(arr1,0,n);
336: if (!nStr.equals(istr)) {
337: System.out.println("ERROR! input="+istr+" output="+nStr);
338: System.out.println(arrstr(arr1,0,n));
339: }
340: }
341: } else if ("b100".equals(test)) {
342: for (int i=0; i<iter; i++) {
343: int val = rng.nextInt();
344: String istr = Integer.toString(val);
345: int n = istr.length();
346: Integer.toString(val).getChars(0, n, arr1, 0);
347:
348: int b100_start = NumberUtils.base10toBase100(arr1,0,n,arr2,sz);
349: int b10_len = NumberUtils.base100toBase10(arr2,b100_start,sz,arr3,0);
350:
351: String nStr = new String(arr3,0,b10_len);
352: if (!nStr.equals(istr)) {
353: System.out.println("ERROR! input="+istr+" output="+nStr);
354: System.out.println(arrstr(arr1,0,n));
355: System.out.println(arrstr(arr2,b100_start,sz));
356: System.out.println(arrstr(arr3,0,b10_len));
357: }
358:
359: }
360: } else if ("b100sParse".equals(test)) {
361: int min=-1000000; int max=1000000;
362: String[] arr = new String[arrsz];
363: String[] internal = new String[arrsz];
364: for (int i=0; i<arrsz; i++) {
365: int val = rng.nextInt();
366: // todo - move to between min and max...
367: arr[i] = Integer.toString(rng.nextInt());
368: }
369: for (int i=0; i<iter; i++) {
370: int slot=i%arrsz;
371: internal[slot] = NumberUtils.base10toBase100SortableInt(arr[i%arrsz]);
372: ret += internal[slot].length();
373: }
374: } else if ("intParse".equals(test)) {
375: int min=-1000000; int max=1000000;
376: String[] arr = new String[arrsz];
377: String[] internal = new String[arrsz];
378: for (int i=0; i<arrsz; i++) {
379: int val = rng.nextInt();
380: // todo - move to between min and max...
381: arr[i] = Integer.toString(rng.nextInt());
382: }
383: for (int i=0; i<iter; i++) {
384: int slot=i%arrsz;
385: int val = Integer.parseInt(arr[i%arrsz]);
386: String sval = Integer.toString(val);
387: internal[slot] = sval;
388: ret += internal[slot].length();
389: }
390: } else if ("b100s".equals(test)) {
391: for (int i=0; i<iter; i++) {
392: Integer i1 = rng.nextInt();
393: Integer i2 = rng.nextInt();
394:
395: // concentrate on small numbers for a while
396: // to try and hit boundary cases 0,1,-1,100,-100,etc
397: if (iter < 10000) {
398: i1 = (i1 % 250)-125;
399: i2 = (i2 % 250)-125;
400: } else if (iter < 500000) {
401: i1 = (i1 % 25000)-12500;
402: i2 = (i2 % 25000)-12500;
403: }
404:
405: String s1=Integer.toString(i1);
406: String s2=Integer.toString(i2);
407: String v1 = NumberUtils.base10toBase10kSortableInt(s1);
408: String v2 = NumberUtils.base10toBase10kSortableInt(s2);
409: String out1=NumberUtils.base10kSortableIntToBase10(v1);
410: String out2=NumberUtils.base10kSortableIntToBase10(v2);
411:
412: int c1 = i1.compareTo(i2);
413: int c2 = v1.compareTo(v2);
414: if (c1==0 && c2 !=0 || c1 < 0 && c2 >= 0 || c1 > 0 && c2 <=0
415: || !out1.equals(s1) || !out2.equals(s2))
416: {
417: System.out.println("Comparison error:"+s1+","+s2);
418: System.out.print("v1=");
419: for (int ii=0; ii<v1.length(); ii++) {
420: System.out.print(" " + (int)v1.charAt(ii));
421: }
422: System.out.print("\nv2=");
423: for (int ii=0; ii<v2.length(); ii++) {
424: System.out.print(" " + (int)v2.charAt(ii));
425: }
426: System.out.println("\nout1='"+out1+"', out2='" + out2 + "'");
427:
428: }
429:
430:
431:
432:
433:
434: }
435: }
436: ****/
437:
438: long endTime = System.currentTimeMillis();
439: System.out.println("time=" + (endTime - startTime));
440: System.out.println("ret=" + ret);
441: }
442: }
443:
444: interface Converter {
445: String toInternal(String val);
446:
447: String toExternal(String val);
448: }
449:
450: class Int2Int implements Converter {
451: public String toInternal(String val) {
452: return Integer.toString(Integer.parseInt(val));
453: }
454:
455: public String toExternal(String val) {
456: return Integer.toString(Integer.parseInt(val));
457: }
458: }
459:
460: class SortInt implements Converter {
461: public String toInternal(String val) {
462: return NumberUtils.int2sortableStr(val);
463: }
464:
465: public String toExternal(String val) {
466: return NumberUtils.SortableStr2int(val);
467: }
468: }
469:
470: class SortLong implements Converter {
471: public String toInternal(String val) {
472: return NumberUtils.long2sortableStr(val);
473: }
474:
475: public String toExternal(String val) {
476: return NumberUtils.SortableStr2long(val);
477: }
478: }
479:
480: class Float2Float implements Converter {
481: public String toInternal(String val) {
482: return Float.toString(Float.parseFloat(val));
483: }
484:
485: public String toExternal(String val) {
486: return Float.toString(Float.parseFloat(val));
487: }
488: }
489:
490: class SortFloat implements Converter {
491: public String toInternal(String val) {
492: return NumberUtils.float2sortableStr(val);
493: }
494:
495: public String toExternal(String val) {
496: return NumberUtils.SortableStr2floatStr(val);
497: }
498: }
499:
500: class SortDouble implements Converter {
501: public String toInternal(String val) {
502: return NumberUtils.double2sortableStr(val);
503: }
504:
505: public String toExternal(String val) {
506: return NumberUtils.SortableStr2doubleStr(val);
507: }
508: }
509:
510: class Base100S implements Converter {
511: public String toInternal(String val) {
512: return BCDUtils.base10toBase100SortableInt(val);
513: }
514:
515: public String toExternal(String val) {
516: return BCDUtils.base100SortableIntToBase10(val);
517: }
518: }
519:
520: class Base10kS implements Converter {
521: public String toInternal(String val) {
522: return BCDUtils.base10toBase10kSortableInt(val);
523: }
524:
525: public String toExternal(String val) {
526: return BCDUtils.base10kSortableIntToBase10(val);
527: }
528: }
|