Tests for ComparatorOptions, Comparator and DirectComparator, and by

proxy we also exercise Slice and DirectSlice
This commit is contained in:
Adam Retter 2014-09-25 14:12:02 +01:00
parent 5e25274110
commit c63494fb61
7 changed files with 340 additions and 2 deletions

View File

@ -46,7 +46,9 @@ test: java
java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.ReadOnlyTest
java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.ReadOptionsTest
java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.StatisticsCollectorTest
@rm -rf /tmp/rocksdbjni_*
java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.ComparatorOptionsTest
java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.ComparatorTest
java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.DirectComparatorTest
db_bench: java
javac org/rocksdb/benchmark/*.java

View File

@ -14,7 +14,7 @@ package org.rocksdb;
* @see org.rocksdb.Comparator
* @see org.rocksdb.DirectComparator
*/
abstract class AbstractComparator<T extends AbstractSlice> extends RocksObject {
public abstract class AbstractComparator<T extends AbstractSlice> extends RocksObject {
public abstract String name();

View File

@ -0,0 +1,166 @@
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.
package org.rocksdb.test;
import org.rocksdb.*;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Random;
import static org.rocksdb.test.Types.byteToInt;
import static org.rocksdb.test.Types.intToByte;
/**
* Abstract tests for both Comparator and DirectComparator
*/
public abstract class AbstractComparatorTest {
/**
* Get a comparator which will expect Integer keys
* and determine an ascending order
*
* @return An integer ascending order key comparator
*/
public abstract AbstractComparator getAscendingIntKeyComparator();
/**
* Test which stores random keys into the database
* using an @see getAscendingIntKeyComparator
* it then checks that these keys are read back in
* ascending order
*
* @param db_path A path where we can store database
* files temporarily
*/
public void testRoundtrip(final Path db_path) throws IOException {
Options opt = null;
RocksDB db = null;
try {
opt = new Options();
opt.setCreateIfMissing(true);
opt.setComparator(getAscendingIntKeyComparator());
// store 10,000 random integer keys
final int ITERATIONS = 10000;
db = RocksDB.open(opt, db_path.toString());
final Random random = new Random();
for(int i = 0; i < ITERATIONS; i++) {
final byte key[] = intToByte(random.nextInt());
if(i > 0 && db.get(key) != null) { // does key already exist (avoid duplicates)
i--; // generate a different key
} else {
db.put(key, "value".getBytes());
}
}
db.close();
// re-open db and read from start to end
// integer keys should be in ascending
// order as defined by SimpleIntComparator
db = RocksDB.open(opt, db_path.toString());
final RocksIterator it = db.newIterator();
it.seekToFirst();
int lastKey = Integer.MIN_VALUE;
int count = 0;
for(it.seekToFirst(); it.isValid(); it.next()) {
final int thisKey = byteToInt(it.key());
assert(thisKey > lastKey);
lastKey = thisKey;
count++;
}
db.close();
assert(count == ITERATIONS);
} catch (final RocksDBException e) {
System.err.format("[ERROR]: %s%n", e);
e.printStackTrace();
} finally {
if(db != null) {
db.close();
}
if(opt != null) {
opt.dispose();
}
removeDb(db_path); // cleanup after ourselves!
}
}
/**
* Compares integer keys
* so that they are in ascending order
*
* @param a 4-bytes representing an integer key
* @param b 4-bytes representing an integer key
*
* @return negative if a < b, 0 if a == b, positive otherwise
*/
protected final int compareIntKeys(final byte[] a, final byte[] b) {
final int iA = byteToInt(a);
final int iB = byteToInt(b);
// protect against int key calculation overflow
final double diff = (double)iA - iB;
final int result;
if(diff < Integer.MIN_VALUE) {
result = Integer.MIN_VALUE;
} else if(diff > Integer.MAX_VALUE) {
result = Integer.MAX_VALUE;
} else {
result = (int)diff;
}
return result;
}
/**
* Utility method for deleting database files
*
* @param db_path The path to the database to remove
* from the filesystem
*/
private static void removeDb(final Path db_path) throws IOException {
Files.walkFileTree(db_path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs)
throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(final Path file, IOException exc)
throws IOException {
// try to delete the file anyway, even if its attributes
// could not be read, since delete-only access is
// theoretically possible
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(final Path dir, IOException exc)
throws IOException {
if (exc == null) {
Files.delete(dir);
return FileVisitResult.CONTINUE;
} else {
// directory iteration failed; propagate exception
throw exc;
}
}
});
}
}

View File

@ -0,0 +1,34 @@
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.
package org.rocksdb.test;
import org.rocksdb.ComparatorOptions;
import org.rocksdb.RocksDB;
import java.util.Random;
public class ComparatorOptionsTest {
static {
RocksDB.loadLibrary();
}
public static void main(String[] args) {
final ComparatorOptions copt = new ComparatorOptions();
Random rand = new Random();
{ // UseAdaptiveMutex test
copt.setUseAdaptiveMutex(true);
assert(copt.useAdaptiveMutex() == true);
copt.setUseAdaptiveMutex(false);
assert(copt.useAdaptiveMutex() == false);
}
copt.dispose();
System.out.println("Passed ComparatorOptionsTest");
}
}

View File

@ -0,0 +1,45 @@
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.
package org.rocksdb.test;
import org.rocksdb.*;
import java.io.IOException;
import java.nio.file.FileSystems;
public class ComparatorTest {
private static final String db_path = "/tmp/comparator_db";
static {
RocksDB.loadLibrary();
}
public static void main(String[] args) throws IOException {
final AbstractComparatorTest comparatorTest = new AbstractComparatorTest() {
@Override
public AbstractComparator getAscendingIntKeyComparator() {
return new Comparator(new ComparatorOptions()) {
@Override
public String name() {
return "test.AscendingIntKeyComparator";
}
@Override
public int compare(final Slice a, final Slice b) {
return compareIntKeys(a.data(), b.data());
}
};
}
};
// test the round-tripability of keys written and read with the Comparator
comparatorTest.testRoundtrip(FileSystems.getDefault().getPath(db_path));
System.out.println("Passed ComparatorTest");
}
}

View File

@ -0,0 +1,48 @@
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.
package org.rocksdb.test;
import org.rocksdb.*;
import java.io.IOException;
import java.nio.file.FileSystems;
public class DirectComparatorTest {
private static final String db_path = "/tmp/direct_comparator_db";
static {
RocksDB.loadLibrary();
}
public static void main(String[] args) throws IOException {
final AbstractComparatorTest comparatorTest = new AbstractComparatorTest() {
@Override
public AbstractComparator getAscendingIntKeyComparator() {
return new DirectComparator(new ComparatorOptions()) {
@Override
public String name() {
return "test.AscendingIntKeyDirectComparator";
}
@Override
public int compare(final DirectSlice a, final DirectSlice b) {
final byte ax[] = new byte[4], bx[] = new byte[4];
a.data().get(ax);
b.data().get(bx);
return compareIntKeys(ax, bx);
}
};
}
};
// test the round-tripability of keys written and read with the DirectComparator
comparatorTest.testRoundtrip(FileSystems.getDefault().getPath(db_path));
System.out.println("Passed DirectComparatorTest");
}
}

View File

@ -0,0 +1,43 @@
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.
package org.rocksdb.test;
/**
* Simple type conversion methods
* for use in tests
*/
public class Types {
/**
* Convert first 4 bytes of a byte array to an int
*
* @param data The byte array
*
* @return An integer
*/
public static int byteToInt(final byte data[]) {
return (data[0] & 0xff) |
((data[1] & 0xff) << 8) |
((data[2] & 0xff) << 16) |
((data[3] & 0xff) << 24);
}
/**
* Convert an int to 4 bytes
*
* @param v The int
*
* @return A byte array containing 4 bytes
*/
public static byte[] intToByte(final int v) {
return new byte[] {
(byte)((v >>> 0) & 0xff),
(byte)((v >>> 8) & 0xff),
(byte)((v >>> 16) & 0xff),
(byte)((v >>> 24) & 0xff)
};
}
}