1 package org.apache.lucene.util;
3 import org.junit.BeforeClass;
6 * Licensed to the Apache Software Foundation (ASF) under one or more
7 * contributor license agreements. See the NOTICE file distributed with
8 * this work for additional information regarding copyright ownership.
9 * The ASF licenses this file to You under the Apache License, Version 2.0
10 * (the "License"); you may not use this file except in compliance with
11 * the License. You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
22 import java.nio.CharBuffer;
23 import java.nio.ByteBuffer;
25 public class TestIndexableBinaryStringTools extends LuceneTestCase {
26 private static int NUM_RANDOM_TESTS;
27 private static int MAX_RANDOM_BINARY_LENGTH;
30 public static void beforeClass() throws Exception {
31 NUM_RANDOM_TESTS = atLeast(200);
32 MAX_RANDOM_BINARY_LENGTH = atLeast(300);
35 /** @deprecated remove this test for Lucene 4.0 */
37 public void testSingleBinaryRoundTripNIO() {
38 byte[] binary = new byte[]
39 { (byte)0x23, (byte)0x98, (byte)0x13, (byte)0xE4, (byte)0x76, (byte)0x41,
40 (byte)0xB2, (byte)0xC9, (byte)0x7F, (byte)0x0A, (byte)0xA6, (byte)0xD8 };
42 ByteBuffer binaryBuf = ByteBuffer.wrap(binary);
43 CharBuffer encoded = IndexableBinaryStringTools.encode(binaryBuf);
44 ByteBuffer decoded = IndexableBinaryStringTools.decode(encoded);
45 assertEquals("Round trip decode/decode returned different results:"
46 + System.getProperty("line.separator")
47 + "original: " + binaryDumpNIO(binaryBuf)
48 + System.getProperty("line.separator")
49 + " encoded: " + charArrayDumpNIO(encoded)
50 + System.getProperty("line.separator")
51 + " decoded: " + binaryDumpNIO(decoded),
55 public void testSingleBinaryRoundTrip() {
56 byte[] binary = new byte[] { (byte) 0x23, (byte) 0x98, (byte) 0x13,
57 (byte) 0xE4, (byte) 0x76, (byte) 0x41, (byte) 0xB2, (byte) 0xC9,
58 (byte) 0x7F, (byte) 0x0A, (byte) 0xA6, (byte) 0xD8 };
60 int encodedLen = IndexableBinaryStringTools.getEncodedLength(binary, 0,
62 char encoded[] = new char[encodedLen];
63 IndexableBinaryStringTools.encode(binary, 0, binary.length, encoded, 0,
66 int decodedLen = IndexableBinaryStringTools.getDecodedLength(encoded, 0,
68 byte decoded[] = new byte[decodedLen];
69 IndexableBinaryStringTools.decode(encoded, 0, encoded.length, decoded, 0,
72 assertEquals("Round trip decode/decode returned different results:"
73 + System.getProperty("line.separator") + "original: "
74 + binaryDump(binary, binary.length)
75 + System.getProperty("line.separator") + " encoded: "
76 + charArrayDump(encoded, encoded.length)
77 + System.getProperty("line.separator") + " decoded: "
78 + binaryDump(decoded, decoded.length),
79 binaryDump(binary, binary.length), binaryDump(decoded, decoded.length));
82 /** @deprecated remove this test for Lucene 4.0 */
84 public void testEncodedSortabilityNIO() {
85 byte[] originalArray1 = new byte[MAX_RANDOM_BINARY_LENGTH];
86 ByteBuffer originalBuf1 = ByteBuffer.wrap(originalArray1);
87 char[] originalString1 = new char[MAX_RANDOM_BINARY_LENGTH];
88 CharBuffer originalStringBuf1 = CharBuffer.wrap(originalString1);
89 char[] encoded1 = new char[IndexableBinaryStringTools.getEncodedLength(originalBuf1)];
90 CharBuffer encodedBuf1 = CharBuffer.wrap(encoded1);
91 byte[] original2 = new byte[MAX_RANDOM_BINARY_LENGTH];
92 ByteBuffer originalBuf2 = ByteBuffer.wrap(original2);
93 char[] originalString2 = new char[MAX_RANDOM_BINARY_LENGTH];
94 CharBuffer originalStringBuf2 = CharBuffer.wrap(originalString2);
95 char[] encoded2 = new char[IndexableBinaryStringTools.getEncodedLength(originalBuf2)];
96 CharBuffer encodedBuf2 = CharBuffer.wrap(encoded2);
97 for (int testNum = 0 ; testNum < NUM_RANDOM_TESTS ; ++testNum) {
98 int numBytes1 = random.nextInt(MAX_RANDOM_BINARY_LENGTH - 1) + 1; // Min == 1
99 originalBuf1.limit(numBytes1);
100 originalStringBuf1.limit(numBytes1);
102 for (int byteNum = 0 ; byteNum < numBytes1 ; ++byteNum) {
103 int randomInt = random.nextInt(0x100);
104 originalArray1[byteNum] = (byte) randomInt;
105 originalString1[byteNum] = (char)randomInt;
108 int numBytes2 = random.nextInt(MAX_RANDOM_BINARY_LENGTH - 1) + 1; // Min == 1
109 originalBuf2.limit(numBytes2);
110 originalStringBuf2.limit(numBytes2);
111 for (int byteNum = 0 ; byteNum < numBytes2 ; ++byteNum) {
112 int randomInt = random.nextInt(0x100);
113 original2[byteNum] = (byte)randomInt;
114 originalString2[byteNum] = (char)randomInt;
116 int originalComparison = originalStringBuf1.compareTo(originalStringBuf2);
117 originalComparison = originalComparison < 0 ? -1 : originalComparison > 0 ? 1 : 0;
119 IndexableBinaryStringTools.encode(originalBuf1, encodedBuf1);
120 IndexableBinaryStringTools.encode(originalBuf2, encodedBuf2);
122 int encodedComparison = encodedBuf1.compareTo(encodedBuf2);
123 encodedComparison = encodedComparison < 0 ? -1 : encodedComparison > 0 ? 1 : 0;
125 assertEquals("Test #" + (testNum + 1)
126 + ": Original bytes and encoded chars compare differently:"
127 + System.getProperty("line.separator")
128 + " binary 1: " + binaryDumpNIO(originalBuf1)
129 + System.getProperty("line.separator")
130 + " binary 2: " + binaryDumpNIO(originalBuf2)
131 + System.getProperty("line.separator")
132 + "encoded 1: " + charArrayDumpNIO(encodedBuf1)
133 + System.getProperty("line.separator")
134 + "encoded 2: " + charArrayDumpNIO(encodedBuf2)
135 + System.getProperty("line.separator"),
136 originalComparison, encodedComparison);
140 public void testEncodedSortability() {
141 byte[] originalArray1 = new byte[MAX_RANDOM_BINARY_LENGTH];
142 char[] originalString1 = new char[MAX_RANDOM_BINARY_LENGTH];
143 char[] encoded1 = new char[MAX_RANDOM_BINARY_LENGTH * 10];
144 byte[] original2 = new byte[MAX_RANDOM_BINARY_LENGTH];
145 char[] originalString2 = new char[MAX_RANDOM_BINARY_LENGTH];
146 char[] encoded2 = new char[MAX_RANDOM_BINARY_LENGTH * 10];
148 for (int testNum = 0; testNum < NUM_RANDOM_TESTS; ++testNum) {
149 int numBytes1 = random.nextInt(MAX_RANDOM_BINARY_LENGTH - 1) + 1; // Min == 1
151 for (int byteNum = 0; byteNum < numBytes1; ++byteNum) {
152 int randomInt = random.nextInt(0x100);
153 originalArray1[byteNum] = (byte) randomInt;
154 originalString1[byteNum] = (char) randomInt;
157 int numBytes2 = random.nextInt(MAX_RANDOM_BINARY_LENGTH - 1) + 1; // Min == 1
159 for (int byteNum = 0; byteNum < numBytes2; ++byteNum) {
160 int randomInt = random.nextInt(0x100);
161 original2[byteNum] = (byte) randomInt;
162 originalString2[byteNum] = (char) randomInt;
164 int originalComparison = new String(originalString1, 0, numBytes1)
165 .compareTo(new String(originalString2, 0, numBytes2));
166 originalComparison = originalComparison < 0 ? -1
167 : originalComparison > 0 ? 1 : 0;
169 int encodedLen1 = IndexableBinaryStringTools.getEncodedLength(
170 originalArray1, 0, numBytes1);
171 if (encodedLen1 > encoded1.length)
172 encoded1 = new char[ArrayUtil.oversize(encodedLen1, RamUsageEstimator.NUM_BYTES_CHAR)];
173 IndexableBinaryStringTools.encode(originalArray1, 0, numBytes1, encoded1,
176 int encodedLen2 = IndexableBinaryStringTools.getEncodedLength(original2,
178 if (encodedLen2 > encoded2.length)
179 encoded2 = new char[ArrayUtil.oversize(encodedLen2, RamUsageEstimator.NUM_BYTES_CHAR)];
180 IndexableBinaryStringTools.encode(original2, 0, numBytes2, encoded2, 0,
183 int encodedComparison = new String(encoded1, 0, encodedLen1)
184 .compareTo(new String(encoded2, 0, encodedLen2));
185 encodedComparison = encodedComparison < 0 ? -1
186 : encodedComparison > 0 ? 1 : 0;
188 assertEquals("Test #" + (testNum + 1)
189 + ": Original bytes and encoded chars compare differently:"
190 + System.getProperty("line.separator") + " binary 1: "
191 + binaryDump(originalArray1, numBytes1)
192 + System.getProperty("line.separator") + " binary 2: "
193 + binaryDump(original2, numBytes2)
194 + System.getProperty("line.separator") + "encoded 1: "
195 + charArrayDump(encoded1, encodedLen1)
196 + System.getProperty("line.separator") + "encoded 2: "
197 + charArrayDump(encoded2, encodedLen2)
198 + System.getProperty("line.separator"), originalComparison,
203 /** @deprecated remove this test for Lucene 4.0 */
205 public void testEmptyInputNIO() {
206 byte[] binary = new byte[0];
207 CharBuffer encoded = IndexableBinaryStringTools.encode(ByteBuffer.wrap(binary));
208 ByteBuffer decoded = IndexableBinaryStringTools.decode(encoded);
209 assertNotNull("decode() returned null", decoded);
210 assertEquals("decoded empty input was not empty", decoded.limit(), 0);
213 public void testEmptyInput() {
214 byte[] binary = new byte[0];
216 int encodedLen = IndexableBinaryStringTools.getEncodedLength(binary, 0,
218 char[] encoded = new char[encodedLen];
219 IndexableBinaryStringTools.encode(binary, 0, binary.length, encoded, 0,
222 int decodedLen = IndexableBinaryStringTools.getDecodedLength(encoded, 0,
224 byte[] decoded = new byte[decodedLen];
225 IndexableBinaryStringTools.decode(encoded, 0, encoded.length, decoded, 0,
228 assertEquals("decoded empty input was not empty", decoded.length, 0);
231 /** @deprecated remove this test for Lucene 4.0 */
233 public void testAllNullInputNIO() {
234 byte[] binary = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
235 ByteBuffer binaryBuf = ByteBuffer.wrap(binary);
236 CharBuffer encoded = IndexableBinaryStringTools.encode(binaryBuf);
237 assertNotNull("encode() returned null", encoded);
238 ByteBuffer decodedBuf = IndexableBinaryStringTools.decode(encoded);
239 assertNotNull("decode() returned null", decodedBuf);
240 assertEquals("Round trip decode/decode returned different results:"
241 + System.getProperty("line.separator")
242 + " original: " + binaryDumpNIO(binaryBuf)
243 + System.getProperty("line.separator")
244 + "decodedBuf: " + binaryDumpNIO(decodedBuf),
245 binaryBuf, decodedBuf);
248 public void testAllNullInput() {
249 byte[] binary = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
251 int encodedLen = IndexableBinaryStringTools.getEncodedLength(binary, 0,
253 char encoded[] = new char[encodedLen];
254 IndexableBinaryStringTools.encode(binary, 0, binary.length, encoded, 0,
257 int decodedLen = IndexableBinaryStringTools.getDecodedLength(encoded, 0,
259 byte[] decoded = new byte[decodedLen];
260 IndexableBinaryStringTools.decode(encoded, 0, encoded.length, decoded, 0,
263 assertEquals("Round trip decode/decode returned different results:"
264 + System.getProperty("line.separator") + " original: "
265 + binaryDump(binary, binary.length)
266 + System.getProperty("line.separator") + "decodedBuf: "
267 + binaryDump(decoded, decoded.length),
268 binaryDump(binary, binary.length), binaryDump(decoded, decoded.length));
271 /** @deprecated remove this test for Lucene 4.0 */
273 public void testRandomBinaryRoundTripNIO() {
274 byte[] binary = new byte[MAX_RANDOM_BINARY_LENGTH];
275 ByteBuffer binaryBuf = ByteBuffer.wrap(binary);
276 char[] encoded = new char[IndexableBinaryStringTools.getEncodedLength(binaryBuf)];
277 CharBuffer encodedBuf = CharBuffer.wrap(encoded);
278 byte[] decoded = new byte[MAX_RANDOM_BINARY_LENGTH];
279 ByteBuffer decodedBuf = ByteBuffer.wrap(decoded);
280 for (int testNum = 0 ; testNum < NUM_RANDOM_TESTS ; ++testNum) {
281 int numBytes = random.nextInt(MAX_RANDOM_BINARY_LENGTH - 1) + 1 ; // Min == 1
282 binaryBuf.limit(numBytes);
283 for (int byteNum = 0 ; byteNum < numBytes ; ++byteNum) {
284 binary[byteNum] = (byte)random.nextInt(0x100);
286 IndexableBinaryStringTools.encode(binaryBuf, encodedBuf);
287 IndexableBinaryStringTools.decode(encodedBuf, decodedBuf);
288 assertEquals("Test #" + (testNum + 1)
289 + ": Round trip decode/decode returned different results:"
290 + System.getProperty("line.separator")
291 + " original: " + binaryDumpNIO(binaryBuf)
292 + System.getProperty("line.separator")
293 + "encodedBuf: " + charArrayDumpNIO(encodedBuf)
294 + System.getProperty("line.separator")
295 + "decodedBuf: " + binaryDumpNIO(decodedBuf),
296 binaryBuf, decodedBuf);
300 public void testRandomBinaryRoundTrip() {
301 byte[] binary = new byte[MAX_RANDOM_BINARY_LENGTH];
302 char[] encoded = new char[MAX_RANDOM_BINARY_LENGTH * 10];
303 byte[] decoded = new byte[MAX_RANDOM_BINARY_LENGTH];
304 for (int testNum = 0; testNum < NUM_RANDOM_TESTS; ++testNum) {
305 int numBytes = random.nextInt(MAX_RANDOM_BINARY_LENGTH - 1) + 1; // Min == 1
307 for (int byteNum = 0; byteNum < numBytes; ++byteNum) {
308 binary[byteNum] = (byte) random.nextInt(0x100);
311 int encodedLen = IndexableBinaryStringTools.getEncodedLength(binary, 0,
313 if (encoded.length < encodedLen)
314 encoded = new char[ArrayUtil.oversize(encodedLen, RamUsageEstimator.NUM_BYTES_CHAR)];
315 IndexableBinaryStringTools.encode(binary, 0, numBytes, encoded, 0,
318 int decodedLen = IndexableBinaryStringTools.getDecodedLength(encoded, 0,
320 IndexableBinaryStringTools.decode(encoded, 0, encodedLen, decoded, 0,
323 assertEquals("Test #" + (testNum + 1)
324 + ": Round trip decode/decode returned different results:"
325 + System.getProperty("line.separator") + " original: "
326 + binaryDump(binary, numBytes) + System.getProperty("line.separator")
327 + "encodedBuf: " + charArrayDump(encoded, encodedLen)
328 + System.getProperty("line.separator") + "decodedBuf: "
329 + binaryDump(decoded, decodedLen), binaryDump(binary, numBytes),
330 binaryDump(decoded, decodedLen));
334 /** @deprecated remove this method for Lucene 4.0 */
336 public String binaryDumpNIO(ByteBuffer binaryBuf) {
337 return binaryDump(binaryBuf.array(),
338 binaryBuf.limit() - binaryBuf.arrayOffset());
341 public String binaryDump(byte[] binary, int numBytes) {
342 StringBuilder buf = new StringBuilder();
343 for (int byteNum = 0 ; byteNum < numBytes ; ++byteNum) {
344 String hex = Integer.toHexString(binary[byteNum] & 0xFF);
345 if (hex.length() == 1) {
348 buf.append(hex.toUpperCase());
349 if (byteNum < numBytes - 1) {
353 return buf.toString();
355 /** @deprecated remove this method for Lucene 4.0 */
357 public String charArrayDumpNIO(CharBuffer charBuf) {
358 return charArrayDump(charBuf.array(),
359 charBuf.limit() - charBuf.arrayOffset());
362 public String charArrayDump(char[] charArray, int numBytes) {
363 StringBuilder buf = new StringBuilder();
364 for (int charNum = 0 ; charNum < numBytes ; ++charNum) {
365 String hex = Integer.toHexString(charArray[charNum]);
366 for (int digit = 0 ; digit < 4 - hex.length() ; ++digit) {
369 buf.append(hex.toUpperCase());
370 if (charNum < numBytes - 1) {
374 return buf.toString();