diff --git a/java/Makefile b/java/Makefile index 214dc6aef..03277906d 100644 --- a/java/Makefile +++ b/java/Makefile @@ -112,6 +112,7 @@ JAVA_TESTS = \ org.rocksdb.BlobOptionsTest\ org.rocksdb.BlockBasedTableConfigTest\ org.rocksdb.BuiltinComparatorTest\ + org.rocksdb.BytewiseComparatorRegressionTest\ org.rocksdb.util.BytewiseComparatorTest\ org.rocksdb.util.BytewiseComparatorIntTest\ org.rocksdb.CheckPointTest\ diff --git a/java/src/test/java/org/rocksdb/BytewiseComparatorRegressionTest.java b/java/src/test/java/org/rocksdb/BytewiseComparatorRegressionTest.java new file mode 100644 index 000000000..90682eae7 --- /dev/null +++ b/java/src/test/java/org/rocksdb/BytewiseComparatorRegressionTest.java @@ -0,0 +1,126 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under both the GPLv2 (found in the +// COPYING file in the root directory) and Apache 2.0 License +// (found in the LICENSE.Apache file in the root directory). + +package org.rocksdb; + +import static org.junit.Assert.assertArrayEquals; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.rocksdb.util.BytewiseComparator; + +/** + * This test confirms that the following issues were in fact resolved + * by a change made between 6.2.2 and 6.22.1, + * to wit {@link ...} + * which as part of its effect, changed the Java bytewise comparators. + * + * {@link ...} + * {@link ...} + */ +public class BytewiseComparatorRegressionTest { + @ClassRule + public static final RocksNativeLibraryResource ROCKS_NATIVE_LIBRARY_RESOURCE = + new RocksNativeLibraryResource(); + + @Rule public TemporaryFolder dbFolder = new TemporaryFolder(); + + @Rule public TemporaryFolder temporarySSTFolder = new TemporaryFolder(); + + private final static byte[][] testData = {{10, -11, 13}, {10, 11, 12}, {10, 11, 14}}; + private final static byte[][] orderedData = {{10, 11, 12}, {10, 11, 14}, {10, -11, 13}}; + + /** + * {@link ...} + */ + @Test + public void testJavaComparator() throws RocksDBException { + final BytewiseComparator comparator = new BytewiseComparator(new ComparatorOptions()); + performTest(new Options().setCreateIfMissing(true).setComparator(comparator)); + } + + @Test + public void testDefaultComparator() throws RocksDBException { + performTest(new Options().setCreateIfMissing(true)); + } + + /** + * {@link ...} + */ + @Test + public void testCppComparator() throws RocksDBException { + performTest(new Options().setCreateIfMissing(true).setComparator( + BuiltinComparator.BYTEWISE_COMPARATOR)); + } + + private void performTest(final Options options) throws RocksDBException { + try (final RocksDB db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath())) { + for (final byte[] item : testData) { + db.put(item, item); + } + try (final RocksIterator iterator = db.newIterator()) { + iterator.seekToFirst(); + final ArrayList result = new ArrayList<>(); + while (iterator.isValid()) { + result.add(iterator.key()); + iterator.next(); + } + assertArrayEquals(orderedData, result.toArray()); + } + } + } + + private byte[] hexToByte(final String hexString) { + final byte[] bytes = new byte[hexString.length() / 2]; + if (bytes.length * 2 < hexString.length()) { + throw new RuntimeException("Hex string has odd length: " + hexString); + } + + for (int i = 0; i < bytes.length; i++) { + final int firstDigit = toDigit(hexString.charAt(i + i)); + final int secondDigit = toDigit(hexString.charAt(i + i + 1)); + bytes[i] = (byte) ((firstDigit << 4) + secondDigit); + } + + return bytes; + } + + private int toDigit(final char hexChar) { + final int digit = Character.digit(hexChar, 16); + if (digit == -1) { + throw new IllegalArgumentException("Invalid Hexadecimal Character: " + hexChar); + } + return digit; + } + + /** + * {@link ...} + * + * @throws RocksDBException if something goes wrong, or if the regression occurs + * @throws IOException if we can't make the temporary file + */ + @Test + public void testSST() throws RocksDBException, IOException { + final File tempSSTFile = temporarySSTFolder.newFile("test_file_with_weird_keys.sst"); + + final EnvOptions envOpts = new EnvOptions(); + final Options opts = new Options(); + final SstFileWriter writer = + new SstFileWriter(envOpts, opts, new BytewiseComparator(new ComparatorOptions())); + writer.open(tempSSTFile.getAbsolutePath()); + final byte[] gKey = + hexToByte("000000293030303030303030303030303030303030303032303736343730696E666F33"); + final byte[] wKey = + hexToByte("0000008d3030303030303030303030303030303030303030303437363433696e666f34"); + writer.add(new Slice(gKey), new Slice("dummyV1")); + writer.add(new Slice(wKey), new Slice("dummyV2")); + writer.finish(); + } +}