mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Squashed 'src/rocksdb2/' content from commit 37c6740
git-subtree-dir: src/rocksdb2 git-subtree-split: 37c6740c383bb9a6ee2747b04f08bc77fcfa10c5
This commit is contained in:
54
java/HISTORY-JAVA.md
Normal file
54
java/HISTORY-JAVA.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# RocksJava Change Log
|
||||
|
||||
## By 06/15/2014
|
||||
### New Features
|
||||
* Added basic Java binding for rocksdb::Env such that multiple RocksDB can share the same thread pool and environment.
|
||||
* Added RestoreBackupableDB
|
||||
|
||||
## By 05/30/2014
|
||||
### Internal Framework Improvement
|
||||
* Added disOwnNativeHandle to RocksObject, which allows a RocksObject to give-up the ownership of its native handle. This method is useful when sharing and transferring the ownership of RocksDB C++ resources.
|
||||
|
||||
## By 05/15/2014
|
||||
### New Features
|
||||
* Added RocksObject --- the base class of all RocksDB classes which holds some RocksDB resources in the C++ side.
|
||||
* Use environmental variable JAVA_HOME in Makefile for RocksJava
|
||||
### Public API changes
|
||||
* Renamed org.rocksdb.Iterator to org.rocksdb.RocksIterator to avoid potential confliction with Java built-in Iterator.
|
||||
|
||||
## By 04/30/2014
|
||||
### New Features
|
||||
* Added Java binding for MultiGet.
|
||||
* Added static method RocksDB.loadLibrary(), which loads necessary library files.
|
||||
* Added Java bindings for 60+ rocksdb::Options.
|
||||
* Added Java binding for BloomFilter.
|
||||
* Added Java binding for ReadOptions.
|
||||
* Added Java binding for memtables.
|
||||
* Added Java binding for sst formats.
|
||||
* Added Java binding for RocksDB Iterator which enables sequential scan operation.
|
||||
* Added Java binding for Statistics
|
||||
* Added Java binding for BackupableDB.
|
||||
|
||||
### DB Benchmark
|
||||
* Added filluniquerandom, readseq benchmark.
|
||||
* 70+ command-line options.
|
||||
* Enabled BloomFilter configuration.
|
||||
|
||||
## By 04/15/2014
|
||||
### New Features
|
||||
* Added Java binding for WriteOptions.
|
||||
* Added Java binding for WriteBatch, which enables batch-write.
|
||||
* Added Java binding for rocksdb::Options.
|
||||
* Added Java binding for block cache.
|
||||
* Added Java version DB Benchmark.
|
||||
|
||||
### DB Benchmark
|
||||
* Added readwhilewriting benchmark.
|
||||
|
||||
### Internal Framework Improvement
|
||||
* Avoid a potential byte-array-copy between c++ and Java in RocksDB.get.
|
||||
* Added SizeUnit in org.rocksdb.util to store consts like KB and GB.
|
||||
|
||||
### 03/28/2014
|
||||
* RocksJava project started.
|
||||
* Added Java binding for RocksDB, which supports Open, Close, Get and Put.
|
||||
34
java/Makefile
Normal file
34
java/Makefile
Normal file
@@ -0,0 +1,34 @@
|
||||
NATIVE_JAVA_CLASSES = org.rocksdb.RocksDB org.rocksdb.Options org.rocksdb.WriteBatch org.rocksdb.WriteBatchInternal org.rocksdb.WriteBatchTest org.rocksdb.WriteOptions org.rocksdb.BackupableDB org.rocksdb.BackupableDBOptions org.rocksdb.Statistics org.rocksdb.RocksIterator org.rocksdb.VectorMemTableConfig org.rocksdb.SkipListMemTableConfig org.rocksdb.HashLinkedListMemTableConfig org.rocksdb.HashSkipListMemTableConfig org.rocksdb.PlainTableConfig org.rocksdb.ReadOptions org.rocksdb.Filter org.rocksdb.BloomFilter org.rocksdb.RestoreOptions org.rocksdb.RestoreBackupableDB org.rocksdb.RocksEnv
|
||||
|
||||
NATIVE_INCLUDE = ./include
|
||||
ROCKSDB_JAR = rocksdbjni.jar
|
||||
|
||||
clean:
|
||||
-find . -name "*.class" -exec rm {} \;
|
||||
-find . -name "hs*.log" -exec rm {} \;
|
||||
rm -f $(ROCKSDB_JAR)
|
||||
|
||||
java:
|
||||
javac org/rocksdb/util/*.java org/rocksdb/*.java
|
||||
@cp ../HISTORY.md ./HISTORY-CPP.md
|
||||
@rm -f ./HISTORY-CPP.md
|
||||
javah -d $(NATIVE_INCLUDE) -jni $(NATIVE_JAVA_CLASSES)
|
||||
|
||||
sample: java
|
||||
javac -cp $(ROCKSDB_JAR) RocksDBSample.java
|
||||
@rm -rf /tmp/rocksdbjni
|
||||
@rm -rf /tmp/rocksdbjni_not_found
|
||||
java -ea -Djava.library.path=.:../ -cp ".:./*" -Xcheck:jni RocksDBSample /tmp/rocksdbjni
|
||||
@rm -rf /tmp/rocksdbjni
|
||||
@rm -rf /tmp/rocksdbjni_not_found
|
||||
|
||||
test: java
|
||||
javac org/rocksdb/test/*.java
|
||||
java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.WriteBatchTest
|
||||
java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.BackupableDBTest
|
||||
java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.OptionsTest
|
||||
java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.ReadOptionsTest
|
||||
java -ea -Djava.library.path=.:../ -cp "$(ROCKSDB_JAR):.:./*" org.rocksdb.test.StatisticsCollectorTest
|
||||
|
||||
db_bench: java
|
||||
javac org/rocksdb/benchmark/*.java
|
||||
259
java/RocksDBSample.java
Normal file
259
java/RocksDBSample.java
Normal file
@@ -0,0 +1,259 @@
|
||||
// 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.
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import org.rocksdb.*;
|
||||
import org.rocksdb.util.SizeUnit;
|
||||
import java.io.IOException;
|
||||
|
||||
public class RocksDBSample {
|
||||
static {
|
||||
RocksDB.loadLibrary();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args.length < 1) {
|
||||
System.out.println("usage: RocksDBSample db_path");
|
||||
return;
|
||||
}
|
||||
String db_path = args[0];
|
||||
String db_path_not_found = db_path + "_not_found";
|
||||
|
||||
System.out.println("RocksDBSample");
|
||||
RocksDB db = null;
|
||||
Options options = new Options();
|
||||
try {
|
||||
db = RocksDB.open(options, db_path_not_found);
|
||||
assert(false);
|
||||
} catch (RocksDBException e) {
|
||||
System.out.format("caught the expceted exception -- %s\n", e);
|
||||
assert(db == null);
|
||||
}
|
||||
|
||||
Filter filter = new BloomFilter(10);
|
||||
options.setCreateIfMissing(true)
|
||||
.createStatistics()
|
||||
.setWriteBufferSize(8 * SizeUnit.KB)
|
||||
.setMaxWriteBufferNumber(3)
|
||||
.setDisableSeekCompaction(true)
|
||||
.setBlockSize(64 * SizeUnit.KB)
|
||||
.setMaxBackgroundCompactions(10)
|
||||
.setFilter(filter)
|
||||
.setCacheNumShardBits(6)
|
||||
.setCompressionType(CompressionType.SNAPPY_COMPRESSION)
|
||||
.setCompactionStyle(CompactionStyle.UNIVERSAL);
|
||||
Statistics stats = options.statisticsPtr();
|
||||
|
||||
assert(options.createIfMissing() == true);
|
||||
assert(options.writeBufferSize() == 8 * SizeUnit.KB);
|
||||
assert(options.maxWriteBufferNumber() == 3);
|
||||
assert(options.disableSeekCompaction() == true);
|
||||
assert(options.blockSize() == 64 * SizeUnit.KB);
|
||||
assert(options.maxBackgroundCompactions() == 10);
|
||||
assert(options.cacheNumShardBits() == 6);
|
||||
assert(options.compressionType() == CompressionType.SNAPPY_COMPRESSION);
|
||||
assert(options.compactionStyle() == CompactionStyle.UNIVERSAL);
|
||||
|
||||
assert(options.memTableFactoryName().equals("SkipListFactory"));
|
||||
options.setMemTableConfig(
|
||||
new HashSkipListMemTableConfig()
|
||||
.setHeight(4)
|
||||
.setBranchingFactor(4)
|
||||
.setBucketCount(2000000));
|
||||
assert(options.memTableFactoryName().equals("HashSkipListRepFactory"));
|
||||
|
||||
options.setMemTableConfig(
|
||||
new HashLinkedListMemTableConfig()
|
||||
.setBucketCount(100000));
|
||||
assert(options.memTableFactoryName().equals("HashLinkedListRepFactory"));
|
||||
|
||||
options.setMemTableConfig(
|
||||
new VectorMemTableConfig().setReservedSize(10000));
|
||||
assert(options.memTableFactoryName().equals("VectorRepFactory"));
|
||||
|
||||
options.setMemTableConfig(new SkipListMemTableConfig());
|
||||
assert(options.memTableFactoryName().equals("SkipListFactory"));
|
||||
|
||||
options.setTableFormatConfig(new PlainTableConfig());
|
||||
assert(options.tableFactoryName().equals("PlainTable"));
|
||||
|
||||
try {
|
||||
db = RocksDB.open(options, db_path_not_found);
|
||||
db.put("hello".getBytes(), "world".getBytes());
|
||||
byte[] value = db.get("hello".getBytes());
|
||||
assert("world".equals(new String(value)));
|
||||
} catch (RocksDBException e) {
|
||||
System.out.format("[ERROR] caught the unexpceted exception -- %s\n", e);
|
||||
assert(db == null);
|
||||
assert(false);
|
||||
}
|
||||
// be sure to release the c++ pointer
|
||||
db.close();
|
||||
|
||||
ReadOptions readOptions = new ReadOptions();
|
||||
readOptions.setFillCache(false);
|
||||
|
||||
try {
|
||||
db = RocksDB.open(options, db_path);
|
||||
db.put("hello".getBytes(), "world".getBytes());
|
||||
byte[] value = db.get("hello".getBytes());
|
||||
System.out.format("Get('hello') = %s\n",
|
||||
new String(value));
|
||||
|
||||
for (int i = 1; i <= 9; ++i) {
|
||||
for (int j = 1; j <= 9; ++j) {
|
||||
db.put(String.format("%dx%d", i, j).getBytes(),
|
||||
String.format("%d", i * j).getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 1; i <= 9; ++i) {
|
||||
for (int j = 1; j <= 9; ++j) {
|
||||
System.out.format("%s ", new String(db.get(
|
||||
String.format("%dx%d", i, j).getBytes())));
|
||||
}
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
value = db.get("1x1".getBytes());
|
||||
assert(value != null);
|
||||
value = db.get("world".getBytes());
|
||||
assert(value == null);
|
||||
value = db.get(readOptions, "world".getBytes());
|
||||
assert(value == null);
|
||||
|
||||
byte[] testKey = "asdf".getBytes();
|
||||
byte[] testValue =
|
||||
"asdfghjkl;'?><MNBVCXZQWERTYUIOP{+_)(*&^%$#@".getBytes();
|
||||
db.put(testKey, testValue);
|
||||
byte[] testResult = db.get(testKey);
|
||||
assert(testResult != null);
|
||||
assert(Arrays.equals(testValue, testResult));
|
||||
assert(new String(testValue).equals(new String(testResult)));
|
||||
testResult = db.get(readOptions, testKey);
|
||||
assert(testResult != null);
|
||||
assert(Arrays.equals(testValue, testResult));
|
||||
assert(new String(testValue).equals(new String(testResult)));
|
||||
|
||||
byte[] insufficientArray = new byte[10];
|
||||
byte[] enoughArray = new byte[50];
|
||||
int len;
|
||||
len = db.get(testKey, insufficientArray);
|
||||
assert(len > insufficientArray.length);
|
||||
len = db.get("asdfjkl;".getBytes(), enoughArray);
|
||||
assert(len == RocksDB.NOT_FOUND);
|
||||
len = db.get(testKey, enoughArray);
|
||||
assert(len == testValue.length);
|
||||
|
||||
len = db.get(readOptions, testKey, insufficientArray);
|
||||
assert(len > insufficientArray.length);
|
||||
len = db.get(readOptions, "asdfjkl;".getBytes(), enoughArray);
|
||||
assert(len == RocksDB.NOT_FOUND);
|
||||
len = db.get(readOptions, testKey, enoughArray);
|
||||
assert(len == testValue.length);
|
||||
|
||||
db.remove(testKey);
|
||||
len = db.get(testKey, enoughArray);
|
||||
assert(len == RocksDB.NOT_FOUND);
|
||||
|
||||
// repeat the test with WriteOptions
|
||||
WriteOptions writeOpts = new WriteOptions();
|
||||
writeOpts.setSync(true);
|
||||
writeOpts.setDisableWAL(true);
|
||||
db.put(writeOpts, testKey, testValue);
|
||||
len = db.get(testKey, enoughArray);
|
||||
assert(len == testValue.length);
|
||||
assert(new String(testValue).equals(
|
||||
new String(enoughArray, 0, len)));
|
||||
writeOpts.dispose();
|
||||
|
||||
try {
|
||||
for (TickerType statsType : TickerType.values()) {
|
||||
stats.getTickerCount(statsType);
|
||||
}
|
||||
System.out.println("getTickerCount() passed.");
|
||||
} catch (Exception e) {
|
||||
System.out.println("Failed in call to getTickerCount()");
|
||||
assert(false); //Should never reach here.
|
||||
}
|
||||
|
||||
try {
|
||||
for (HistogramType histogramType : HistogramType.values()) {
|
||||
HistogramData data = stats.geHistogramData(histogramType);
|
||||
}
|
||||
System.out.println("geHistogramData() passed.");
|
||||
} catch (Exception e) {
|
||||
System.out.println("Failed in call to geHistogramData()");
|
||||
assert(false); //Should never reach here.
|
||||
}
|
||||
|
||||
RocksIterator iterator = db.newIterator();
|
||||
|
||||
boolean seekToFirstPassed = false;
|
||||
for (iterator.seekToFirst(); iterator.isValid(); iterator.next()) {
|
||||
iterator.status();
|
||||
assert(iterator.key() != null);
|
||||
assert(iterator.value() != null);
|
||||
seekToFirstPassed = true;
|
||||
}
|
||||
if(seekToFirstPassed) {
|
||||
System.out.println("iterator seekToFirst tests passed.");
|
||||
}
|
||||
|
||||
boolean seekToLastPassed = false;
|
||||
for (iterator.seekToLast(); iterator.isValid(); iterator.prev()) {
|
||||
iterator.status();
|
||||
assert(iterator.key() != null);
|
||||
assert(iterator.value() != null);
|
||||
seekToLastPassed = true;
|
||||
}
|
||||
|
||||
if(seekToLastPassed) {
|
||||
System.out.println("iterator seekToLastPassed tests passed.");
|
||||
}
|
||||
|
||||
iterator.seekToFirst();
|
||||
iterator.seek(iterator.key());
|
||||
assert(iterator.key() != null);
|
||||
assert(iterator.value() != null);
|
||||
|
||||
System.out.println("iterator seek test passed.");
|
||||
|
||||
iterator.dispose();
|
||||
System.out.println("iterator tests passed.");
|
||||
|
||||
iterator = db.newIterator();
|
||||
List<byte[]> keys = new ArrayList<byte[]>();
|
||||
for (iterator.seekToLast(); iterator.isValid(); iterator.prev()) {
|
||||
keys.add(iterator.key());
|
||||
}
|
||||
iterator.dispose();
|
||||
|
||||
Map<byte[], byte[]> values = db.multiGet(keys);
|
||||
assert(values.size() == keys.size());
|
||||
for(byte[] value1 : values.values()) {
|
||||
assert(value1 != null);
|
||||
}
|
||||
|
||||
values = db.multiGet(new ReadOptions(), keys);
|
||||
assert(values.size() == keys.size());
|
||||
for(byte[] value1 : values.values()) {
|
||||
assert(value1 != null);
|
||||
}
|
||||
} catch (RocksDBException e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
if (db != null) {
|
||||
db.close();
|
||||
}
|
||||
// be sure to dispose c++ pointers
|
||||
options.dispose();
|
||||
readOptions.dispose();
|
||||
filter.dispose();
|
||||
}
|
||||
}
|
||||
1
java/jdb_bench.sh
Executable file
1
java/jdb_bench.sh
Executable file
@@ -0,0 +1 @@
|
||||
java -server -d64 -XX:NewSize=4m -XX:+AggressiveOpts -Djava.library.path=.:../ -cp "rocksdbjni.jar:.:./*" org.rocksdb.benchmark.DbBenchmark $@
|
||||
80
java/org/rocksdb/BackupableDB.java
Normal file
80
java/org/rocksdb/BackupableDB.java
Normal file
@@ -0,0 +1,80 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* A subclass of RocksDB which supports backup-related operations.
|
||||
*
|
||||
* @see BackupableDBOptions
|
||||
*/
|
||||
public class BackupableDB extends RocksDB {
|
||||
/**
|
||||
* Open a BackupableDB under the specified path.
|
||||
* Note that the backup path should be set properly in the
|
||||
* input BackupableDBOptions.
|
||||
*
|
||||
* @param opt options for db.
|
||||
* @param bopt backup related options.
|
||||
* @param the db path for storing data. The path for storing
|
||||
* backup should be specified in the BackupableDBOptions.
|
||||
* @return reference to the opened BackupableDB.
|
||||
*/
|
||||
public static BackupableDB open(
|
||||
Options opt, BackupableDBOptions bopt, String db_path)
|
||||
throws RocksDBException {
|
||||
|
||||
RocksDB db = RocksDB.open(opt, db_path);
|
||||
BackupableDB bdb = new BackupableDB();
|
||||
bdb.open(db.nativeHandle_, bopt.nativeHandle_);
|
||||
|
||||
// Prevent the RocksDB object from attempting to delete
|
||||
// the underly C++ DB object.
|
||||
db.disOwnNativeHandle();
|
||||
|
||||
return bdb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures the state of the database in the latest backup.
|
||||
* Note that this function is not thread-safe.
|
||||
*
|
||||
* @param flushBeforeBackup if true, then all data will be flushed
|
||||
* before creating backup.
|
||||
*/
|
||||
public void createNewBackup(boolean flushBeforeBackup) {
|
||||
createNewBackup(nativeHandle_, flushBeforeBackup);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close the BackupableDB instance and release resource.
|
||||
*
|
||||
* Internally, BackupableDB owns the rocksdb::DB pointer to its
|
||||
* associated RocksDB. The release of that RocksDB pointer is
|
||||
* handled in the destructor of the c++ rocksdb::BackupableDB and
|
||||
* should be transparent to Java developers.
|
||||
*/
|
||||
@Override public synchronized void close() {
|
||||
if (isInitialized()) {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A protected construction that will be used in the static factory
|
||||
* method BackupableDB.open().
|
||||
*/
|
||||
protected BackupableDB() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override protected void finalize() {
|
||||
close();
|
||||
}
|
||||
|
||||
protected native void open(long rocksDBHandle, long backupDBOptionsHandle);
|
||||
protected native void createNewBackup(long handle, boolean flag);
|
||||
}
|
||||
73
java/org/rocksdb/BackupableDBOptions.java
Normal file
73
java/org/rocksdb/BackupableDBOptions.java
Normal file
@@ -0,0 +1,73 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* BackupableDBOptions to control the behavior of a backupable database.
|
||||
* It will be used during the creation of a BackupableDB.
|
||||
*
|
||||
* Note that dispose() must be called before an Options instance
|
||||
* become out-of-scope to release the allocated memory in c++.
|
||||
*
|
||||
* @param path Where to keep the backup files. Has to be different than dbname.
|
||||
Best to set this to dbname_ + "/backups"
|
||||
* @param shareTableFiles If share_table_files == true, backup will assume that
|
||||
* table files with same name have the same contents. This enables
|
||||
* incremental backups and avoids unnecessary data copies. If
|
||||
* share_table_files == false, each backup will be on its own and will not
|
||||
* share any data with other backups. default: true
|
||||
* @param sync If sync == true, we can guarantee you'll get consistent backup
|
||||
* even on a machine crash/reboot. Backup process is slower with sync
|
||||
* enabled. If sync == false, we don't guarantee anything on machine reboot.
|
||||
* However, chances are some of the backups are consistent. Default: true
|
||||
* @param destroyOldData If true, it will delete whatever backups there are
|
||||
* already. Default: false
|
||||
* @param backupLogFiles If false, we won't backup log files. This option can be
|
||||
* useful for backing up in-memory databases where log file are persisted,
|
||||
* but table files are in memory. Default: true
|
||||
* @param backupRateLimit Max bytes that can be transferred in a second during
|
||||
* backup. If 0 or negative, then go as fast as you can. Default: 0
|
||||
* @param restoreRateLimit Max bytes that can be transferred in a second during
|
||||
* restore. If 0 or negative, then go as fast as you can. Default: 0
|
||||
*/
|
||||
public class BackupableDBOptions extends RocksObject {
|
||||
public BackupableDBOptions(String path, boolean shareTableFiles, boolean sync,
|
||||
boolean destroyOldData, boolean backupLogFiles, long backupRateLimit,
|
||||
long restoreRateLimit) {
|
||||
super();
|
||||
|
||||
backupRateLimit = (backupRateLimit <= 0) ? 0 : backupRateLimit;
|
||||
restoreRateLimit = (restoreRateLimit <= 0) ? 0 : restoreRateLimit;
|
||||
|
||||
newBackupableDBOptions(path, shareTableFiles, sync, destroyOldData,
|
||||
backupLogFiles, backupRateLimit, restoreRateLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the BackupableDB directory.
|
||||
*
|
||||
* @return the path to the BackupableDB directory.
|
||||
*/
|
||||
public String backupDir() {
|
||||
assert(isInitialized());
|
||||
return backupDir(nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the memory allocated for the current instance
|
||||
* in the c++ side.
|
||||
*/
|
||||
@Override protected void disposeInternal() {
|
||||
assert(isInitialized());
|
||||
disposeInternal(nativeHandle_);
|
||||
}
|
||||
|
||||
private native void newBackupableDBOptions(String path,
|
||||
boolean shareTableFiles, boolean sync, boolean destroyOldData,
|
||||
boolean backupLogFiles, long backupRateLimit, long restoreRateLimit);
|
||||
private native String backupDir(long handle);
|
||||
private native void disposeInternal(long handle);
|
||||
}
|
||||
37
java/org/rocksdb/BloomFilter.java
Normal file
37
java/org/rocksdb/BloomFilter.java
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* This class creates a new filter policy that uses a bloom filter
|
||||
* with approximately the specified number of bits per key.
|
||||
* A good value for bitsPerKey is 10, which yields a filter
|
||||
* with ~ 1% false positive rate.
|
||||
*
|
||||
* Default value of bits per key is 10.
|
||||
*/
|
||||
public class BloomFilter extends Filter {
|
||||
private static final int DEFAULT_BITS_PER_KEY = 10;
|
||||
private final int bitsPerKey_;
|
||||
|
||||
public BloomFilter() {
|
||||
this(DEFAULT_BITS_PER_KEY);
|
||||
}
|
||||
|
||||
public BloomFilter(int bitsPerKey) {
|
||||
super();
|
||||
bitsPerKey_ = bitsPerKey;
|
||||
|
||||
createNewFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createNewFilter() {
|
||||
createNewFilter0(bitsPerKey_);
|
||||
}
|
||||
|
||||
private native void createNewFilter0(int bitsKeyKey);
|
||||
}
|
||||
22
java/org/rocksdb/CompactionStyle.java
Normal file
22
java/org/rocksdb/CompactionStyle.java
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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;
|
||||
|
||||
public enum CompactionStyle {
|
||||
LEVEL((byte) 0),
|
||||
UNIVERSAL((byte) 1),
|
||||
FIFO((byte) 2);
|
||||
|
||||
private final byte value_;
|
||||
|
||||
private CompactionStyle(byte value) {
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
public byte getValue() {
|
||||
return value_;
|
||||
}
|
||||
}
|
||||
25
java/org/rocksdb/CompressionType.java
Normal file
25
java/org/rocksdb/CompressionType.java
Normal file
@@ -0,0 +1,25 @@
|
||||
// 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;
|
||||
|
||||
public enum CompressionType {
|
||||
NO_COMPRESSION((byte) 0),
|
||||
SNAPPY_COMPRESSION((byte) 1),
|
||||
ZLIB_COMPRESSION((byte) 2),
|
||||
BZLIB2_COMPRESSION((byte) 3),
|
||||
LZ4_COMPRESSION((byte) 4),
|
||||
LZ4HC_COMPRESSION((byte) 5);
|
||||
|
||||
private final byte value_;
|
||||
|
||||
private CompressionType(byte value) {
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
public byte getValue() {
|
||||
return value_;
|
||||
}
|
||||
}
|
||||
31
java/org/rocksdb/Filter.java
Normal file
31
java/org/rocksdb/Filter.java
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* Filters are stored in rocksdb and are consulted automatically
|
||||
* by rocksdb to decide whether or not to read some
|
||||
* information from disk. In many cases, a filter can cut down the
|
||||
* number of disk seeks form a handful to a single disk seek per
|
||||
* DB::Get() call.
|
||||
*/
|
||||
public abstract class Filter extends RocksObject {
|
||||
protected abstract void createNewFilter();
|
||||
|
||||
/**
|
||||
* Deletes underlying C++ filter pointer.
|
||||
*
|
||||
* Note that this function should be called only after all
|
||||
* RocksDB instances referencing the filter are closed.
|
||||
* Otherwise an undefined behavior will occur.
|
||||
*/
|
||||
@Override protected void disposeInternal() {
|
||||
assert(isInitialized());
|
||||
disposeInternal(nativeHandle_);
|
||||
}
|
||||
|
||||
private native void disposeInternal(long handle);
|
||||
}
|
||||
52
java/org/rocksdb/HashLinkedListMemTableConfig.java
Normal file
52
java/org/rocksdb/HashLinkedListMemTableConfig.java
Normal file
@@ -0,0 +1,52 @@
|
||||
package org.rocksdb;
|
||||
|
||||
/**
|
||||
* The config for hash linked list memtable representation
|
||||
* Such memtable contains a fix-sized array of buckets, where
|
||||
* each bucket points to a sorted singly-linked
|
||||
* list (or null if the bucket is empty).
|
||||
*
|
||||
* Note that since this mem-table representation relies on the
|
||||
* key prefix, it is required to invoke one of the usePrefixExtractor
|
||||
* functions to specify how to extract key prefix given a key.
|
||||
* If proper prefix-extractor is not set, then RocksDB will
|
||||
* use the default memtable representation (SkipList) instead
|
||||
* and post a warning in the LOG.
|
||||
*/
|
||||
public class HashLinkedListMemTableConfig extends MemTableConfig {
|
||||
public static final long DEFAULT_BUCKET_COUNT = 50000;
|
||||
|
||||
public HashLinkedListMemTableConfig() {
|
||||
bucketCount_ = DEFAULT_BUCKET_COUNT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of buckets in the fixed-size array used
|
||||
* in the hash linked-list mem-table.
|
||||
*
|
||||
* @param count the number of hash buckets.
|
||||
* @return the reference to the current HashLinkedListMemTableConfig.
|
||||
*/
|
||||
public HashLinkedListMemTableConfig setBucketCount(long count) {
|
||||
bucketCount_ = count;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of buckets that will be used in the memtable
|
||||
* created based on this config.
|
||||
*
|
||||
* @return the number of buckets
|
||||
*/
|
||||
public long bucketCount() {
|
||||
return bucketCount_;
|
||||
}
|
||||
|
||||
@Override protected long newMemTableFactoryHandle() {
|
||||
return newMemTableFactoryHandle(bucketCount_);
|
||||
}
|
||||
|
||||
private native long newMemTableFactoryHandle(long bucketCount);
|
||||
|
||||
private long bucketCount_;
|
||||
}
|
||||
97
java/org/rocksdb/HashSkipListMemTableConfig.java
Normal file
97
java/org/rocksdb/HashSkipListMemTableConfig.java
Normal file
@@ -0,0 +1,97 @@
|
||||
package org.rocksdb;
|
||||
|
||||
/**
|
||||
* The config for hash skip-list mem-table representation.
|
||||
* Such mem-table representation contains a fix-sized array of
|
||||
* buckets, where each bucket points to a skiplist (or null if the
|
||||
* bucket is empty).
|
||||
*
|
||||
* Note that since this mem-table representation relies on the
|
||||
* key prefix, it is required to invoke one of the usePrefixExtractor
|
||||
* functions to specify how to extract key prefix given a key.
|
||||
* If proper prefix-extractor is not set, then RocksDB will
|
||||
* use the default memtable representation (SkipList) instead
|
||||
* and post a warning in the LOG.
|
||||
*/
|
||||
public class HashSkipListMemTableConfig extends MemTableConfig {
|
||||
public static final int DEFAULT_BUCKET_COUNT = 1000000;
|
||||
public static final int DEFAULT_BRANCHING_FACTOR = 4;
|
||||
public static final int DEFAULT_HEIGHT = 4;
|
||||
|
||||
public HashSkipListMemTableConfig() {
|
||||
bucketCount_ = DEFAULT_BUCKET_COUNT;
|
||||
branchingFactor_ = DEFAULT_BRANCHING_FACTOR;
|
||||
height_ = DEFAULT_HEIGHT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of hash buckets used in the hash skiplist memtable.
|
||||
* Default = 1000000.
|
||||
*
|
||||
* @param count the number of hash buckets used in the hash
|
||||
* skiplist memtable.
|
||||
* @return the reference to the current HashSkipListMemTableConfig.
|
||||
*/
|
||||
public HashSkipListMemTableConfig setBucketCount(long count) {
|
||||
bucketCount_ = count;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of hash buckets
|
||||
*/
|
||||
public long bucketCount() {
|
||||
return bucketCount_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the height of the skip list. Default = 4.
|
||||
*
|
||||
* @return the reference to the current HashSkipListMemTableConfig.
|
||||
*/
|
||||
public HashSkipListMemTableConfig setHeight(int height) {
|
||||
height_ = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the height of the skip list.
|
||||
*/
|
||||
public int height() {
|
||||
return height_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the branching factor used in the hash skip-list memtable.
|
||||
* This factor controls the probabilistic size ratio between adjacent
|
||||
* links in the skip list.
|
||||
*
|
||||
* @param bf the probabilistic size ratio between adjacent link
|
||||
* lists in the skip list.
|
||||
* @return the reference to the current HashSkipListMemTableConfig.
|
||||
*/
|
||||
public HashSkipListMemTableConfig setBranchingFactor(int bf) {
|
||||
branchingFactor_ = bf;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return branching factor, the probabilistic size ratio between
|
||||
* adjacent links in the skip list.
|
||||
*/
|
||||
public int branchingFactor() {
|
||||
return branchingFactor_;
|
||||
}
|
||||
|
||||
@Override protected long newMemTableFactoryHandle() {
|
||||
return newMemTableFactoryHandle(
|
||||
bucketCount_, height_, branchingFactor_);
|
||||
}
|
||||
|
||||
private native long newMemTableFactoryHandle(
|
||||
long bucketCount, int height, int branchingFactor);
|
||||
|
||||
private long bucketCount_;
|
||||
private int branchingFactor_;
|
||||
private int height_;
|
||||
}
|
||||
43
java/org/rocksdb/HistogramData.java
Normal file
43
java/org/rocksdb/HistogramData.java
Normal 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;
|
||||
|
||||
public class HistogramData {
|
||||
private final double median_;
|
||||
private final double percentile95_;
|
||||
private final double percentile99_;
|
||||
private final double average_;
|
||||
private final double standardDeviation_;
|
||||
|
||||
public HistogramData(double median, double percentile95,
|
||||
double percentile99, double average, double standardDeviation) {
|
||||
median_ = median;
|
||||
percentile95_ = percentile95;
|
||||
percentile99_ = percentile99;
|
||||
average_ = average;
|
||||
standardDeviation_ = standardDeviation;
|
||||
}
|
||||
|
||||
public double getMedian() {
|
||||
return median_;
|
||||
}
|
||||
|
||||
public double getPercentile95() {
|
||||
return percentile95_;
|
||||
}
|
||||
|
||||
public double getPercentile99() {
|
||||
return percentile99_;
|
||||
}
|
||||
|
||||
public double getAverage() {
|
||||
return average_;
|
||||
}
|
||||
|
||||
public double getStandardDeviation() {
|
||||
return standardDeviation_;
|
||||
}
|
||||
}
|
||||
39
java/org/rocksdb/HistogramType.java
Normal file
39
java/org/rocksdb/HistogramType.java
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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;
|
||||
|
||||
public enum HistogramType {
|
||||
DB_GET(0),
|
||||
DB_WRITE(1),
|
||||
COMPACTION_TIME(2),
|
||||
TABLE_SYNC_MICROS(3),
|
||||
COMPACTION_OUTFILE_SYNC_MICROS(4),
|
||||
WAL_FILE_SYNC_MICROS(5),
|
||||
MANIFEST_FILE_SYNC_MICROS(6),
|
||||
// TIME SPENT IN IO DURING TABLE OPEN
|
||||
TABLE_OPEN_IO_MICROS(7),
|
||||
DB_MULTIGET(8),
|
||||
READ_BLOCK_COMPACTION_MICROS(9),
|
||||
READ_BLOCK_GET_MICROS(10),
|
||||
WRITE_RAW_BLOCK_MICROS(11),
|
||||
|
||||
STALL_L0_SLOWDOWN_COUNT(12),
|
||||
STALL_MEMTABLE_COMPACTION_COUNT(13),
|
||||
STALL_L0_NUM_FILES_COUNT(14),
|
||||
HARD_RATE_LIMIT_DELAY_COUNT(15),
|
||||
SOFT_RATE_LIMIT_DELAY_COUNT(16),
|
||||
NUM_FILES_IN_SINGLE_COMPACTION(17);
|
||||
|
||||
private final int value_;
|
||||
|
||||
private HistogramType(int value) {
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value_;
|
||||
}
|
||||
}
|
||||
27
java/org/rocksdb/MemTableConfig.java
Normal file
27
java/org/rocksdb/MemTableConfig.java
Normal file
@@ -0,0 +1,27 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* MemTableConfig is used to config the internal mem-table of a RocksDB.
|
||||
* It is required for each memtable to have one such sub-class to allow
|
||||
* Java developers to use it.
|
||||
*
|
||||
* To make a RocksDB to use a specific MemTable format, its associated
|
||||
* MemTableConfig should be properly set and passed into Options
|
||||
* via Options.setMemTableFactory() and open the db using that Options.
|
||||
*
|
||||
* @see Options
|
||||
*/
|
||||
public abstract class MemTableConfig {
|
||||
/**
|
||||
* This function should only be called by Options.setMemTableConfig(),
|
||||
* which will create a c++ shared-pointer to the c++ MemTableRepFactory
|
||||
* that associated with the Java MemTableConfig.
|
||||
*
|
||||
* @see Options.setMemTableFactory()
|
||||
*/
|
||||
abstract protected long newMemTableFactoryHandle();
|
||||
}
|
||||
2464
java/org/rocksdb/Options.java
Normal file
2464
java/org/rocksdb/Options.java
Normal file
File diff suppressed because it is too large
Load Diff
123
java/org/rocksdb/PlainTableConfig.java
Normal file
123
java/org/rocksdb/PlainTableConfig.java
Normal file
@@ -0,0 +1,123 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* The config for plain table sst format.
|
||||
*
|
||||
* PlainTable is a RocksDB's SST file format optimized for low query latency
|
||||
* on pure-memory or really low-latency media. It also support prefix
|
||||
* hash feature.
|
||||
*/
|
||||
public class PlainTableConfig extends TableFormatConfig {
|
||||
public static final int VARIABLE_LENGTH = 0;
|
||||
public static final int DEFAULT_BLOOM_BITS_PER_KEY = 10;
|
||||
public static final double DEFAULT_HASH_TABLE_RATIO = 0.75;
|
||||
public static final int DEFAULT_INDEX_SPARSENESS = 16;
|
||||
|
||||
public PlainTableConfig() {
|
||||
keySize_ = VARIABLE_LENGTH;
|
||||
bloomBitsPerKey_ = DEFAULT_BLOOM_BITS_PER_KEY;
|
||||
hashTableRatio_ = DEFAULT_HASH_TABLE_RATIO;
|
||||
indexSparseness_ = DEFAULT_INDEX_SPARSENESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the length of the user key. If it is set to be VARIABLE_LENGTH,
|
||||
* then it indicates the user keys are variable-lengthed. Otherwise,
|
||||
* all the keys need to have the same length in byte.
|
||||
* DEFAULT: VARIABLE_LENGTH
|
||||
*
|
||||
* @param keySize the length of the user key.
|
||||
* @return the reference to the current config.
|
||||
*/
|
||||
public PlainTableConfig setKeySize(int keySize) {
|
||||
keySize_ = keySize;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the specified size of the user key. If VARIABLE_LENGTH,
|
||||
* then it indicates variable-length key.
|
||||
*/
|
||||
public int keySize() {
|
||||
return keySize_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of bits per key used by the internal bloom filter
|
||||
* in the plain table sst format.
|
||||
*
|
||||
* @param bitsPerKey the number of bits per key for bloom filer.
|
||||
* @return the reference to the current config.
|
||||
*/
|
||||
public PlainTableConfig setBloomBitsPerKey(int bitsPerKey) {
|
||||
bloomBitsPerKey_ = bitsPerKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of bits per key used for the bloom filter.
|
||||
*/
|
||||
public int bloomBitsPerKey() {
|
||||
return bloomBitsPerKey_;
|
||||
}
|
||||
|
||||
/**
|
||||
* hashTableRatio is the desired utilization of the hash table used
|
||||
* for prefix hashing. The ideal ratio would be the number of
|
||||
* prefixes / the number of hash buckets. If this value is set to
|
||||
* zero, then hash table will not be used.
|
||||
*
|
||||
* @param ratio the hash table ratio.
|
||||
* @return the reference to the current config.
|
||||
*/
|
||||
public PlainTableConfig setHashTableRatio(double ratio) {
|
||||
hashTableRatio_ = ratio;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hash table ratio.
|
||||
*/
|
||||
public double hashTableRatio() {
|
||||
return hashTableRatio_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Index sparseness determines the index interval for keys inside the
|
||||
* same prefix. This number is equal to the maximum number of linear
|
||||
* search required after hash and binary search. If it's set to 0,
|
||||
* then each key will be indexed.
|
||||
*
|
||||
* @param sparseness the index sparseness.
|
||||
* @return the reference to the current config.
|
||||
*/
|
||||
public PlainTableConfig setIndexSparseness(int sparseness) {
|
||||
indexSparseness_ = sparseness;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the index sparseness.
|
||||
*/
|
||||
public int indexSparseness() {
|
||||
return indexSparseness_;
|
||||
}
|
||||
|
||||
@Override protected long newTableFactoryHandle() {
|
||||
return newTableFactoryHandle(keySize_, bloomBitsPerKey_,
|
||||
hashTableRatio_, indexSparseness_);
|
||||
}
|
||||
|
||||
private native long newTableFactoryHandle(
|
||||
int keySize, int bloomBitsPerKey,
|
||||
double hashTableRatio, int indexSparseness);
|
||||
|
||||
private int keySize_;
|
||||
private int bloomBitsPerKey_;
|
||||
private double hashTableRatio_;
|
||||
private int indexSparseness_;
|
||||
}
|
||||
125
java/org/rocksdb/ReadOptions.java
Normal file
125
java/org/rocksdb/ReadOptions.java
Normal file
@@ -0,0 +1,125 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* The class that controls the get behavior.
|
||||
*
|
||||
* Note that dispose() must be called before an Options instance
|
||||
* become out-of-scope to release the allocated memory in c++.
|
||||
*/
|
||||
public class ReadOptions extends RocksObject {
|
||||
public ReadOptions() {
|
||||
super();
|
||||
newReadOptions();
|
||||
}
|
||||
private native void newReadOptions();
|
||||
|
||||
/**
|
||||
* If true, all data read from underlying storage will be
|
||||
* verified against corresponding checksums.
|
||||
* Default: true
|
||||
*
|
||||
* @return true if checksum verification is on.
|
||||
*/
|
||||
public boolean verifyChecksums() {
|
||||
assert(isInitialized());
|
||||
return verifyChecksums(nativeHandle_);
|
||||
}
|
||||
private native boolean verifyChecksums(long handle);
|
||||
|
||||
/**
|
||||
* If true, all data read from underlying storage will be
|
||||
* verified against corresponding checksums.
|
||||
* Default: true
|
||||
*
|
||||
* @param verifyChecksums if true, then checksum verification
|
||||
* will be performed on every read.
|
||||
* @return the reference to the current ReadOptions.
|
||||
*/
|
||||
public ReadOptions setVerifyChecksums(boolean verifyChecksums) {
|
||||
assert(isInitialized());
|
||||
setVerifyChecksums(nativeHandle_, verifyChecksums);
|
||||
return this;
|
||||
}
|
||||
private native void setVerifyChecksums(
|
||||
long handle, boolean verifyChecksums);
|
||||
|
||||
// TODO(yhchiang): this option seems to be block-based table only.
|
||||
// move this to a better place?
|
||||
/**
|
||||
* Fill the cache when loading the block-based sst formated db.
|
||||
* Callers may wish to set this field to false for bulk scans.
|
||||
* Default: true
|
||||
*
|
||||
* @return true if the fill-cache behavior is on.
|
||||
*/
|
||||
public boolean fillCache() {
|
||||
assert(isInitialized());
|
||||
return fillCache(nativeHandle_);
|
||||
}
|
||||
private native boolean fillCache(long handle);
|
||||
|
||||
/**
|
||||
* Fill the cache when loading the block-based sst formated db.
|
||||
* Callers may wish to set this field to false for bulk scans.
|
||||
* Default: true
|
||||
*
|
||||
* @param fillCache if true, then fill-cache behavior will be
|
||||
* performed.
|
||||
* @return the reference to the current ReadOptions.
|
||||
*/
|
||||
public ReadOptions setFillCache(boolean fillCache) {
|
||||
assert(isInitialized());
|
||||
setFillCache(nativeHandle_, fillCache);
|
||||
return this;
|
||||
}
|
||||
private native void setFillCache(
|
||||
long handle, boolean fillCache);
|
||||
|
||||
/**
|
||||
* Specify to create a tailing iterator -- a special iterator that has a
|
||||
* view of the complete database (i.e. it can also be used to read newly
|
||||
* added data) and is optimized for sequential reads. It will return records
|
||||
* that were inserted into the database after the creation of the iterator.
|
||||
* Default: false
|
||||
* Not supported in ROCKSDB_LITE mode!
|
||||
*
|
||||
* @return true if tailing iterator is enabled.
|
||||
*/
|
||||
public boolean tailing() {
|
||||
assert(isInitialized());
|
||||
return tailing(nativeHandle_);
|
||||
}
|
||||
private native boolean tailing(long handle);
|
||||
|
||||
/**
|
||||
* Specify to create a tailing iterator -- a special iterator that has a
|
||||
* view of the complete database (i.e. it can also be used to read newly
|
||||
* added data) and is optimized for sequential reads. It will return records
|
||||
* that were inserted into the database after the creation of the iterator.
|
||||
* Default: false
|
||||
* Not supported in ROCKSDB_LITE mode!
|
||||
*
|
||||
* @param tailing if true, then tailing iterator will be enabled.
|
||||
* @return the reference to the current ReadOptions.
|
||||
*/
|
||||
public ReadOptions setTailing(boolean tailing) {
|
||||
assert(isInitialized());
|
||||
setTailing(nativeHandle_, tailing);
|
||||
return this;
|
||||
}
|
||||
private native void setTailing(
|
||||
long handle, boolean tailing);
|
||||
|
||||
|
||||
@Override protected void disposeInternal() {
|
||||
assert(isInitialized());
|
||||
disposeInternal(nativeHandle_);
|
||||
}
|
||||
private native void disposeInternal(long handle);
|
||||
|
||||
}
|
||||
84
java/org/rocksdb/RestoreBackupableDB.java
Normal file
84
java/org/rocksdb/RestoreBackupableDB.java
Normal file
@@ -0,0 +1,84 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* This class is used to access information about backups and restore from them.
|
||||
*
|
||||
* Note that dispose() must be called before this instance become out-of-scope
|
||||
* to release the allocated memory in c++.
|
||||
*
|
||||
* @param options Instance of BackupableDBOptions.
|
||||
*/
|
||||
public class RestoreBackupableDB extends RocksObject {
|
||||
public RestoreBackupableDB(BackupableDBOptions options) {
|
||||
super();
|
||||
nativeHandle_ = newRestoreBackupableDB(options.nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore from backup with backup_id
|
||||
* IMPORTANT -- if options_.share_table_files == true and you restore DB
|
||||
* from some backup that is not the latest, and you start creating new
|
||||
* backups from the new DB, they will probably fail.
|
||||
*
|
||||
* Example: Let's say you have backups 1, 2, 3, 4, 5 and you restore 3.
|
||||
* If you add new data to the DB and try creating a new backup now, the
|
||||
* database will diverge from backups 4 and 5 and the new backup will fail.
|
||||
* If you want to create new backup, you will first have to delete backups 4
|
||||
* and 5.
|
||||
*/
|
||||
public void restoreDBFromBackup(long backupId, String dbDir, String walDir,
|
||||
RestoreOptions restoreOptions) throws RocksDBException {
|
||||
restoreDBFromBackup0(nativeHandle_, backupId, dbDir, walDir,
|
||||
restoreOptions.nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore from the latest backup.
|
||||
*/
|
||||
public void restoreDBFromLatestBackup(String dbDir, String walDir,
|
||||
RestoreOptions restoreOptions) throws RocksDBException {
|
||||
restoreDBFromLatestBackup0(nativeHandle_, dbDir, walDir,
|
||||
restoreOptions.nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes old backups, keeping latest numBackupsToKeep alive.
|
||||
*
|
||||
* @param Number of latest backups to keep
|
||||
*/
|
||||
public void purgeOldBackups(int numBackupsToKeep) throws RocksDBException {
|
||||
purgeOldBackups0(nativeHandle_, numBackupsToKeep);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a specific backup.
|
||||
*
|
||||
* @param ID of backup to delete.
|
||||
*/
|
||||
public void deleteBackup(long backupId) throws RocksDBException {
|
||||
deleteBackup0(nativeHandle_, backupId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the memory allocated for the current instance
|
||||
* in the c++ side.
|
||||
*/
|
||||
@Override public synchronized void disposeInternal() {
|
||||
assert(isInitialized());
|
||||
dispose(nativeHandle_);
|
||||
}
|
||||
|
||||
private native long newRestoreBackupableDB(long options);
|
||||
private native void restoreDBFromBackup0(long nativeHandle, long backupId,
|
||||
String dbDir, String walDir, long restoreOptions) throws RocksDBException;
|
||||
private native void restoreDBFromLatestBackup0(long nativeHandle,
|
||||
String dbDir, String walDir, long restoreOptions) throws RocksDBException;
|
||||
private native void purgeOldBackups0(long nativeHandle, int numBackupsToKeep);
|
||||
private native void deleteBackup0(long nativeHandle, long backupId);
|
||||
private native void dispose(long nativeHandle);
|
||||
}
|
||||
37
java/org/rocksdb/RestoreOptions.java
Normal file
37
java/org/rocksdb/RestoreOptions.java
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* RestoreOptions to control the behavior of restore.
|
||||
*
|
||||
* Note that dispose() must be called before this instance become out-of-scope
|
||||
* to release the allocated memory in c++.
|
||||
*
|
||||
* @param If true, restore won't overwrite the existing log files in wal_dir. It
|
||||
* will also move all log files from archive directory to wal_dir. Use this
|
||||
* option in combination with BackupableDBOptions::backup_log_files = false
|
||||
* for persisting in-memory databases.
|
||||
* Default: false
|
||||
*/
|
||||
public class RestoreOptions extends RocksObject {
|
||||
public RestoreOptions(boolean keepLogFiles) {
|
||||
super();
|
||||
nativeHandle_ = newRestoreOptions(keepLogFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the memory allocated for the current instance
|
||||
* in the c++ side.
|
||||
*/
|
||||
@Override public synchronized void disposeInternal() {
|
||||
assert(isInitialized());
|
||||
dispose(nativeHandle_);
|
||||
}
|
||||
|
||||
private native long newRestoreOptions(boolean keepLogFiles);
|
||||
private native void dispose(long handle);
|
||||
}
|
||||
372
java/org/rocksdb/RocksDB.java
Normal file
372
java/org/rocksdb/RocksDB.java
Normal file
@@ -0,0 +1,372 @@
|
||||
// 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;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import org.rocksdb.util.Environment;
|
||||
|
||||
/**
|
||||
* A RocksDB is a persistent ordered map from keys to values. It is safe for
|
||||
* concurrent access from multiple threads without any external synchronization.
|
||||
* All methods of this class could potentially throw RocksDBException, which
|
||||
* indicates sth wrong at the rocksdb library side and the call failed.
|
||||
*/
|
||||
public class RocksDB extends RocksObject {
|
||||
public static final int NOT_FOUND = -1;
|
||||
private static final String[] compressionLibs_ = {
|
||||
"snappy", "z", "bzip2", "lz4", "lz4hc"};
|
||||
|
||||
/**
|
||||
* Loads the necessary library files.
|
||||
* Calling this method twice will have no effect.
|
||||
*/
|
||||
public static synchronized void loadLibrary() {
|
||||
// loading possibly necessary libraries.
|
||||
for (String lib : compressionLibs_) {
|
||||
try {
|
||||
System.loadLibrary(lib);
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
// since it may be optional, we ignore its loading failure here.
|
||||
}
|
||||
}
|
||||
// However, if any of them is required. We will see error here.
|
||||
System.loadLibrary("rocksdbjni");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to load the necessary library files from the given list of
|
||||
* directories.
|
||||
*
|
||||
* @param paths a list of strings where each describes a directory
|
||||
* of a library.
|
||||
*/
|
||||
public static synchronized void loadLibrary(List<String> paths) {
|
||||
for (String lib : compressionLibs_) {
|
||||
for (String path : paths) {
|
||||
try {
|
||||
System.load(path + "/" + Environment.getSharedLibraryName(lib));
|
||||
break;
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
// since they are optional, we ignore loading fails.
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean success = false;
|
||||
UnsatisfiedLinkError err = null;
|
||||
for (String path : paths) {
|
||||
try {
|
||||
System.load(path + "/" + Environment.getJniLibraryName("rocksdbjni"));
|
||||
success = true;
|
||||
break;
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
err = e;
|
||||
}
|
||||
}
|
||||
if (success == false) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The factory constructor of RocksDB that opens a RocksDB instance given
|
||||
* the path to the database using the default options w/ createIfMissing
|
||||
* set to true.
|
||||
*
|
||||
* @param path the path to the rocksdb.
|
||||
* @param status an out value indicating the status of the Open().
|
||||
* @return a rocksdb instance on success, null if the specified rocksdb can
|
||||
* not be opened.
|
||||
*
|
||||
* @see Options.setCreateIfMissing()
|
||||
* @see Options.createIfMissing()
|
||||
*/
|
||||
public static RocksDB open(String path) throws RocksDBException {
|
||||
RocksDB db = new RocksDB();
|
||||
|
||||
// This allows to use the rocksjni default Options instead of
|
||||
// the c++ one.
|
||||
Options options = new Options();
|
||||
return open(options, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* The factory constructor of RocksDB that opens a RocksDB instance given
|
||||
* the path to the database using the specified options and db path.
|
||||
*
|
||||
* Options instance *should* not be disposed before all DBs using this options
|
||||
* instance have been closed. If user doesn't call options dispose explicitly,
|
||||
* then this options instance will be GC'd automatically.
|
||||
*
|
||||
* Options instance can be re-used to open multiple DBs if DB statistics is
|
||||
* not used. If DB statistics are required, then its recommended to open DB
|
||||
* with new Options instance as underlying native statistics instance does not
|
||||
* use any locks to prevent concurrent updates.
|
||||
*/
|
||||
public static RocksDB open(Options options, String path)
|
||||
throws RocksDBException {
|
||||
// when non-default Options is used, keeping an Options reference
|
||||
// in RocksDB can prevent Java to GC during the life-time of
|
||||
// the currently-created RocksDB.
|
||||
RocksDB db = new RocksDB();
|
||||
db.open(options.nativeHandle_, options.cacheSize_,
|
||||
options.numShardBits_, path);
|
||||
|
||||
db.storeOptionsInstance(options);
|
||||
return db;
|
||||
}
|
||||
|
||||
private void storeOptionsInstance(Options options) {
|
||||
options_ = options;
|
||||
}
|
||||
|
||||
@Override protected void disposeInternal() {
|
||||
assert(isInitialized());
|
||||
disposeInternal(nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the RocksDB instance.
|
||||
* This function is equivalent to dispose().
|
||||
*/
|
||||
public void close() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the database entry for "key" to "value".
|
||||
*
|
||||
* @param key the specified key to be inserted.
|
||||
* @param value the value associated with the specified key.
|
||||
*/
|
||||
public void put(byte[] key, byte[] value) throws RocksDBException {
|
||||
put(nativeHandle_, key, key.length, value, value.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the database entry for "key" to "value".
|
||||
*
|
||||
* @param key the specified key to be inserted.
|
||||
* @param value the value associated with the specified key.
|
||||
*/
|
||||
public void put(WriteOptions writeOpts, byte[] key, byte[] value)
|
||||
throws RocksDBException {
|
||||
put(nativeHandle_, writeOpts.nativeHandle_,
|
||||
key, key.length, value, value.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified updates to the database.
|
||||
*/
|
||||
public void write(WriteOptions writeOpts, WriteBatch updates)
|
||||
throws RocksDBException {
|
||||
write(writeOpts.nativeHandle_, updates.nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value associated with the specified key.
|
||||
*
|
||||
* @param key the key to retrieve the value.
|
||||
* @param value the out-value to receive the retrieved value.
|
||||
* @return The size of the actual value that matches the specified
|
||||
* {@code key} in byte. If the return value is greater than the
|
||||
* length of {@code value}, then it indicates that the size of the
|
||||
* input buffer {@code value} is insufficient and partial result will
|
||||
* be returned. RocksDB.NOT_FOUND will be returned if the value not
|
||||
* found.
|
||||
*/
|
||||
public int get(byte[] key, byte[] value) throws RocksDBException {
|
||||
return get(nativeHandle_, key, key.length, value, value.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value associated with the specified key.
|
||||
*
|
||||
* @param key the key to retrieve the value.
|
||||
* @param value the out-value to receive the retrieved value.
|
||||
* @return The size of the actual value that matches the specified
|
||||
* {@code key} in byte. If the return value is greater than the
|
||||
* length of {@code value}, then it indicates that the size of the
|
||||
* input buffer {@code value} is insufficient and partial result will
|
||||
* be returned. RocksDB.NOT_FOUND will be returned if the value not
|
||||
* found.
|
||||
*/
|
||||
public int get(ReadOptions opt, byte[] key, byte[] value)
|
||||
throws RocksDBException {
|
||||
return get(nativeHandle_, opt.nativeHandle_,
|
||||
key, key.length, value, value.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* The simplified version of get which returns a new byte array storing
|
||||
* the value associated with the specified input key if any. null will be
|
||||
* returned if the specified key is not found.
|
||||
*
|
||||
* @param key the key retrieve the value.
|
||||
* @return a byte array storing the value associated with the input key if
|
||||
* any. null if it does not find the specified key.
|
||||
*
|
||||
* @see RocksDBException
|
||||
*/
|
||||
public byte[] get(byte[] key) throws RocksDBException {
|
||||
return get(nativeHandle_, key, key.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* The simplified version of get which returns a new byte array storing
|
||||
* the value associated with the specified input key if any. null will be
|
||||
* returned if the specified key is not found.
|
||||
*
|
||||
* @param key the key retrieve the value.
|
||||
* @param opt Read options.
|
||||
* @return a byte array storing the value associated with the input key if
|
||||
* any. null if it does not find the specified key.
|
||||
*
|
||||
* @see RocksDBException
|
||||
*/
|
||||
public byte[] get(ReadOptions opt, byte[] key) throws RocksDBException {
|
||||
return get(nativeHandle_, opt.nativeHandle_, key, key.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of keys for which values were found in DB.
|
||||
*
|
||||
* @param keys List of keys for which values need to be retrieved.
|
||||
* @return Map where key of map is the key passed by user and value for map
|
||||
* entry is the corresponding value in DB.
|
||||
*
|
||||
* @see RocksDBException
|
||||
*/
|
||||
public Map<byte[], byte[]> multiGet(List<byte[]> keys)
|
||||
throws RocksDBException {
|
||||
assert(keys.size() != 0);
|
||||
|
||||
List<byte[]> values = multiGet(
|
||||
nativeHandle_, keys, keys.size());
|
||||
|
||||
Map<byte[], byte[]> keyValueMap = new HashMap<byte[], byte[]>();
|
||||
for(int i = 0; i < values.size(); i++) {
|
||||
if(values.get(i) == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
keyValueMap.put(keys.get(i), values.get(i));
|
||||
}
|
||||
|
||||
return keyValueMap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a map of keys for which values were found in DB.
|
||||
*
|
||||
* @param List of keys for which values need to be retrieved.
|
||||
* @param opt Read options.
|
||||
* @return Map where key of map is the key passed by user and value for map
|
||||
* entry is the corresponding value in DB.
|
||||
*
|
||||
* @see RocksDBException
|
||||
*/
|
||||
public Map<byte[], byte[]> multiGet(ReadOptions opt, List<byte[]> keys)
|
||||
throws RocksDBException {
|
||||
assert(keys.size() != 0);
|
||||
|
||||
List<byte[]> values = multiGet(
|
||||
nativeHandle_, opt.nativeHandle_, keys, keys.size());
|
||||
|
||||
Map<byte[], byte[]> keyValueMap = new HashMap<byte[], byte[]>();
|
||||
for(int i = 0; i < values.size(); i++) {
|
||||
if(values.get(i) == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
keyValueMap.put(keys.get(i), values.get(i));
|
||||
}
|
||||
|
||||
return keyValueMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the database entry (if any) for "key". Returns OK on
|
||||
* success, and a non-OK status on error. It is not an error if "key"
|
||||
* did not exist in the database.
|
||||
*/
|
||||
public void remove(byte[] key) throws RocksDBException {
|
||||
remove(nativeHandle_, key, key.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the database entry (if any) for "key". Returns OK on
|
||||
* success, and a non-OK status on error. It is not an error if "key"
|
||||
* did not exist in the database.
|
||||
*/
|
||||
public void remove(WriteOptions writeOpt, byte[] key)
|
||||
throws RocksDBException {
|
||||
remove(nativeHandle_, writeOpt.nativeHandle_, key, key.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a heap-allocated iterator over the contents of the database.
|
||||
* The result of newIterator() is initially invalid (caller must
|
||||
* call one of the Seek methods on the iterator before using it).
|
||||
*
|
||||
* Caller should close the iterator when it is no longer needed.
|
||||
* The returned iterator should be closed before this db is closed.
|
||||
*
|
||||
* @return instance of iterator object.
|
||||
*/
|
||||
public RocksIterator newIterator() {
|
||||
return new RocksIterator(iterator0(nativeHandle_));
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor.
|
||||
*/
|
||||
protected RocksDB() {
|
||||
super();
|
||||
}
|
||||
|
||||
// native methods
|
||||
protected native void open(
|
||||
long optionsHandle, long cacheSize, int numShardBits,
|
||||
String path) throws RocksDBException;
|
||||
protected native void put(
|
||||
long handle, byte[] key, int keyLen,
|
||||
byte[] value, int valueLen) throws RocksDBException;
|
||||
protected native void put(
|
||||
long handle, long writeOptHandle,
|
||||
byte[] key, int keyLen,
|
||||
byte[] value, int valueLen) throws RocksDBException;
|
||||
protected native void write(
|
||||
long writeOptHandle, long batchHandle) throws RocksDBException;
|
||||
protected native int get(
|
||||
long handle, byte[] key, int keyLen,
|
||||
byte[] value, int valueLen) throws RocksDBException;
|
||||
protected native int get(
|
||||
long handle, long readOptHandle, byte[] key, int keyLen,
|
||||
byte[] value, int valueLen) throws RocksDBException;
|
||||
protected native List<byte[]> multiGet(
|
||||
long dbHandle, List<byte[]> keys, int keysCount);
|
||||
protected native List<byte[]> multiGet(
|
||||
long dbHandle, long rOptHandle, List<byte[]> keys, int keysCount);
|
||||
protected native byte[] get(
|
||||
long handle, byte[] key, int keyLen) throws RocksDBException;
|
||||
protected native byte[] get(
|
||||
long handle, long readOptHandle,
|
||||
byte[] key, int keyLen) throws RocksDBException;
|
||||
protected native void remove(
|
||||
long handle, byte[] key, int keyLen) throws RocksDBException;
|
||||
protected native void remove(
|
||||
long handle, long writeOptHandle,
|
||||
byte[] key, int keyLen) throws RocksDBException;
|
||||
protected native long iterator0(long optHandle);
|
||||
private native void disposeInternal(long handle);
|
||||
|
||||
protected Options options_;
|
||||
}
|
||||
23
java/org/rocksdb/RocksDBException.java
Normal file
23
java/org/rocksdb/RocksDBException.java
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2013, 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;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A RocksDBException encapsulates the error of an operation. This exception
|
||||
* type is used to describe an internal error from the c++ rocksdb library.
|
||||
*/
|
||||
public class RocksDBException extends Exception {
|
||||
/**
|
||||
* The private construct used by a set of public static factory method.
|
||||
*
|
||||
* @param msg the specified error message.
|
||||
*/
|
||||
public RocksDBException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
102
java/org/rocksdb/RocksEnv.java
Normal file
102
java/org/rocksdb/RocksEnv.java
Normal file
@@ -0,0 +1,102 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* A RocksEnv is an interface used by the rocksdb implementation to access
|
||||
* operating system functionality like the filesystem etc.
|
||||
*
|
||||
* All Env implementations are safe for concurrent access from
|
||||
* multiple threads without any external synchronization.
|
||||
*/
|
||||
public class RocksEnv extends RocksObject {
|
||||
public static final int FLUSH_POOL = 0;
|
||||
public static final int COMPACTION_POOL = 1;
|
||||
|
||||
static {
|
||||
default_env_ = new RocksEnv(getDefaultEnvInternal());
|
||||
}
|
||||
private static native long getDefaultEnvInternal();
|
||||
|
||||
/**
|
||||
* Returns the default environment suitable for the current operating
|
||||
* system.
|
||||
*
|
||||
* The result of getDefault() is a singleton whose ownership belongs
|
||||
* to rocksdb c++. As a result, the returned RocksEnv will not
|
||||
* have the ownership of its c++ resource, and calling its dispose()
|
||||
* will be no-op.
|
||||
*/
|
||||
public static RocksEnv getDefault() {
|
||||
return default_env_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of background worker threads of the flush pool
|
||||
* for this environment.
|
||||
* default number: 1
|
||||
*/
|
||||
public RocksEnv setBackgroundThreads(int num) {
|
||||
return setBackgroundThreads(num, FLUSH_POOL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of background worker threads of the specified thread
|
||||
* pool for this environment.
|
||||
*
|
||||
* @param num the number of threads
|
||||
* @param poolID the id to specified a thread pool. Should be either
|
||||
* FLUSH_POOL or COMPACTION_POOL.
|
||||
* Default number: 1
|
||||
*/
|
||||
public RocksEnv setBackgroundThreads(int num, int poolID) {
|
||||
setBackgroundThreads(nativeHandle_, num, poolID);
|
||||
return this;
|
||||
}
|
||||
private native void setBackgroundThreads(
|
||||
long handle, int num, int priority);
|
||||
|
||||
/**
|
||||
* Returns the length of the queue associated with the specified
|
||||
* thread pool.
|
||||
*
|
||||
* @param poolID the id to specified a thread pool. Should be either
|
||||
* FLUSH_POOL or COMPACTION_POOL.
|
||||
*/
|
||||
public int getThreadPoolQueueLen(int poolID) {
|
||||
return getThreadPoolQueueLen(nativeHandle_, poolID);
|
||||
}
|
||||
private native int getThreadPoolQueueLen(long handle, int poolID);
|
||||
|
||||
/**
|
||||
* Package-private constructor that uses the specified native handle
|
||||
* to construct a RocksEnv. Note that the ownership of the input handle
|
||||
* belongs to the caller, and the newly created RocksEnv will not take
|
||||
* the ownership of the input handle. As a result, calling dispose()
|
||||
* of the created RocksEnv will be no-op.
|
||||
*/
|
||||
RocksEnv(long handle) {
|
||||
super();
|
||||
nativeHandle_ = handle;
|
||||
disOwnNativeHandle();
|
||||
}
|
||||
|
||||
/**
|
||||
* The helper function of dispose() which all subclasses of RocksObject
|
||||
* must implement to release their associated C++ resource.
|
||||
*/
|
||||
protected void disposeInternal() {
|
||||
disposeInternal(nativeHandle_);
|
||||
}
|
||||
private native void disposeInternal(long handle);
|
||||
|
||||
/**
|
||||
* The static default RocksEnv. The ownership of its native handle
|
||||
* belongs to rocksdb c++ and is not able to be released on the Java
|
||||
* side.
|
||||
*/
|
||||
static RocksEnv default_env_;
|
||||
}
|
||||
136
java/org/rocksdb/RocksIterator.java
Normal file
136
java/org/rocksdb/RocksIterator.java
Normal file
@@ -0,0 +1,136 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* An iterator yields a sequence of key/value pairs from a source.
|
||||
* The following class defines the interface. Multiple implementations
|
||||
* are provided by this library. In particular, iterators are provided
|
||||
* to access the contents of a Table or a DB.
|
||||
*
|
||||
* Multiple threads can invoke const methods on an RocksIterator without
|
||||
* external synchronization, but if any of the threads may call a
|
||||
* non-const method, all threads accessing the same RocksIterator must use
|
||||
* external synchronization.
|
||||
*/
|
||||
public class RocksIterator extends RocksObject {
|
||||
public RocksIterator(long nativeHandle) {
|
||||
super();
|
||||
nativeHandle_ = nativeHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* An iterator is either positioned at a key/value pair, or
|
||||
* not valid. This method returns true iff the iterator is valid.
|
||||
* @return true if iterator is valid.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
assert(isInitialized());
|
||||
return isValid0(nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Position at the first key in the source. The iterator is Valid()
|
||||
* after this call iff the source is not empty.
|
||||
*/
|
||||
public void seekToFirst() {
|
||||
assert(isInitialized());
|
||||
seekToFirst0(nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Position at the last key in the source. The iterator is
|
||||
* Valid() after this call iff the source is not empty.
|
||||
*/
|
||||
public void seekToLast() {
|
||||
assert(isInitialized());
|
||||
seekToLast0(nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves to the next entry in the source. After this call, Valid() is
|
||||
* true iff the iterator was not positioned at the last entry in the source.
|
||||
* REQUIRES: Valid()
|
||||
*/
|
||||
public void next() {
|
||||
assert(isInitialized());
|
||||
next0(nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves to the previous entry in the source. After this call, Valid() is
|
||||
* true iff the iterator was not positioned at the first entry in source.
|
||||
* REQUIRES: Valid()
|
||||
*/
|
||||
public void prev() {
|
||||
assert(isInitialized());
|
||||
prev0(nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key for the current entry. The underlying storage for
|
||||
* the returned slice is valid only until the next modification of
|
||||
* the iterator.
|
||||
* REQUIRES: Valid()
|
||||
* @return key for the current entry.
|
||||
*/
|
||||
public byte[] key() {
|
||||
assert(isInitialized());
|
||||
return key0(nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value for the current entry. The underlying storage for
|
||||
* the returned slice is valid only until the next modification of
|
||||
* the iterator.
|
||||
* REQUIRES: !AtEnd() && !AtStart()
|
||||
* @return value for the current entry.
|
||||
*/
|
||||
public byte[] value() {
|
||||
assert(isInitialized());
|
||||
return value0(nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Position at the first key in the source that at or past target
|
||||
* The iterator is Valid() after this call iff the source contains
|
||||
* an entry that comes at or past target.
|
||||
*/
|
||||
public void seek(byte[] target) {
|
||||
assert(isInitialized());
|
||||
seek0(nativeHandle_, target, target.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* If an error has occurred, return it. Else return an ok status.
|
||||
* If non-blocking IO is requested and this operation cannot be
|
||||
* satisfied without doing some IO, then this returns Status::Incomplete().
|
||||
*
|
||||
*/
|
||||
public void status() throws RocksDBException {
|
||||
assert(isInitialized());
|
||||
status0(nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes underlying C++ iterator pointer.
|
||||
*/
|
||||
@Override protected void disposeInternal() {
|
||||
assert(isInitialized());
|
||||
disposeInternal(nativeHandle_);
|
||||
}
|
||||
|
||||
private native boolean isValid0(long handle);
|
||||
private native void disposeInternal(long handle);
|
||||
private native void seekToFirst0(long handle);
|
||||
private native void seekToLast0(long handle);
|
||||
private native void next0(long handle);
|
||||
private native void prev0(long handle);
|
||||
private native byte[] key0(long handle);
|
||||
private native byte[] value0(long handle);
|
||||
private native void seek0(long handle, byte[] target, int targetLen);
|
||||
private native void status0(long handle);
|
||||
}
|
||||
117
java/org/rocksdb/RocksObject.java
Normal file
117
java/org/rocksdb/RocksObject.java
Normal file
@@ -0,0 +1,117 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* RocksObject is the base-class of all RocksDB classes that has a pointer to
|
||||
* some c++ rocksdb object.
|
||||
*
|
||||
* RocksObject has dispose() function, which releases its associated c++ resource.
|
||||
* This function can be either called manually, or being called automatically
|
||||
* during the regular Java GC process. However, since Java may wrongly assume a
|
||||
* RocksObject only contains a long member variable and think it is small in size,
|
||||
* Java may give RocksObject low priority in the GC process. For this, it is
|
||||
* suggested to call dispose() manually. However, it is safe to let RocksObject go
|
||||
* out-of-scope without manually calling dispose() as dispose() will be called
|
||||
* in the finalizer during the regular GC process.
|
||||
*/
|
||||
public abstract class RocksObject {
|
||||
protected RocksObject() {
|
||||
nativeHandle_ = 0;
|
||||
owningHandle_ = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the c++ object manually pointed by the native handle.
|
||||
*
|
||||
* Note that dispose() will also be called during the GC process
|
||||
* if it was not called before its RocksObject went out-of-scope.
|
||||
* However, since Java may wrongly wrongly assume those objects are
|
||||
* small in that they seems to only hold a long variable. As a result,
|
||||
* they might have low priority in the GC process. To prevent this,
|
||||
* it is suggested to call dispose() manually.
|
||||
*
|
||||
* Note that once an instance of RocksObject has been disposed,
|
||||
* calling its function will lead undefined behavior.
|
||||
*/
|
||||
public final synchronized void dispose() {
|
||||
if (isOwningNativeHandle() && isInitialized()) {
|
||||
disposeInternal();
|
||||
}
|
||||
nativeHandle_ = 0;
|
||||
disOwnNativeHandle();
|
||||
}
|
||||
|
||||
/**
|
||||
* The helper function of dispose() which all subclasses of RocksObject
|
||||
* must implement to release their associated C++ resource.
|
||||
*/
|
||||
protected abstract void disposeInternal();
|
||||
|
||||
/**
|
||||
* Revoke ownership of the native object.
|
||||
*
|
||||
* This will prevent the object from attempting to delete the underlying
|
||||
* native object in its finalizer. This must be used when another object
|
||||
* takes over ownership of the native object or both will attempt to delete
|
||||
* the underlying object when garbage collected.
|
||||
*
|
||||
* When disOwnNativeHandle() is called, dispose() will simply set nativeHandle_
|
||||
* to 0 without releasing its associated C++ resource. As a result,
|
||||
* incorrectly use this function may cause memory leak, and this function call
|
||||
* will not affect the return value of isInitialized().
|
||||
*
|
||||
* @see dispose()
|
||||
* @see isInitialized()
|
||||
*/
|
||||
protected void disOwnNativeHandle() {
|
||||
owningHandle_ = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current RocksObject is responsable to release its
|
||||
* native handle.
|
||||
*
|
||||
* @return true if the current RocksObject is responsible to release its
|
||||
* native handle.
|
||||
*
|
||||
* @see disOwnNativeHandle()
|
||||
* @see dispose()
|
||||
*/
|
||||
protected boolean isOwningNativeHandle() {
|
||||
return owningHandle_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the associated native handle has been initialized.
|
||||
*
|
||||
* @return true if the associated native handle has been initialized.
|
||||
*
|
||||
* @see dispose()
|
||||
*/
|
||||
protected boolean isInitialized() {
|
||||
return (nativeHandle_ != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply calls dispose() and release its c++ resource if it has not
|
||||
* yet released.
|
||||
*/
|
||||
@Override protected void finalize() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* A long variable holding c++ pointer pointing to some RocksDB C++ object.
|
||||
*/
|
||||
protected long nativeHandle_;
|
||||
|
||||
/**
|
||||
* A flag indicating whether the current RocksObject is responsible to
|
||||
* release the c++ object stored in its nativeHandle_.
|
||||
*/
|
||||
private boolean owningHandle_;
|
||||
}
|
||||
15
java/org/rocksdb/SkipListMemTableConfig.java
Normal file
15
java/org/rocksdb/SkipListMemTableConfig.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package org.rocksdb;
|
||||
|
||||
/**
|
||||
* The config for skip-list memtable representation.
|
||||
*/
|
||||
public class SkipListMemTableConfig extends MemTableConfig {
|
||||
public SkipListMemTableConfig() {
|
||||
}
|
||||
|
||||
@Override protected long newMemTableFactoryHandle() {
|
||||
return newMemTableFactoryHandle0();
|
||||
}
|
||||
|
||||
private native long newMemTableFactoryHandle0();
|
||||
}
|
||||
38
java/org/rocksdb/Statistics.java
Normal file
38
java/org/rocksdb/Statistics.java
Normal file
@@ -0,0 +1,38 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* Statistics to analyze the performance of a db. Pointer for statistics object
|
||||
* is managed by Options class.
|
||||
*/
|
||||
public class Statistics {
|
||||
|
||||
private final long statsHandle_;
|
||||
|
||||
public Statistics(long statsHandle) {
|
||||
statsHandle_ = statsHandle;
|
||||
}
|
||||
|
||||
public long getTickerCount(TickerType tickerType) {
|
||||
assert(isInitialized());
|
||||
return getTickerCount0(tickerType.getValue(), statsHandle_);
|
||||
}
|
||||
|
||||
public HistogramData geHistogramData(HistogramType histogramType) {
|
||||
assert(isInitialized());
|
||||
HistogramData hist = geHistogramData0(
|
||||
histogramType.getValue(), statsHandle_);
|
||||
return hist;
|
||||
}
|
||||
|
||||
private boolean isInitialized() {
|
||||
return (statsHandle_ != 0);
|
||||
}
|
||||
|
||||
private native long getTickerCount0(int tickerType, long handle);
|
||||
private native HistogramData geHistogramData0(int histogramType, long handle);
|
||||
}
|
||||
107
java/org/rocksdb/StatisticsCollector.java
Normal file
107
java/org/rocksdb/StatisticsCollector.java
Normal file
@@ -0,0 +1,107 @@
|
||||
// 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;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Helper class to collect DB statistics periodically at a period specified in
|
||||
* constructor. Callback function (provided in constructor) is called with
|
||||
* every statistics collection.
|
||||
*
|
||||
* Caller should call start() to start statistics collection. Shutdown() should
|
||||
* be called to stop stats collection and should be called before statistics (
|
||||
* provided in constructor) reference has been disposed.
|
||||
*/
|
||||
public class StatisticsCollector {
|
||||
private final List<StatsCollectorInput> _statsCollectorInputList;
|
||||
private final ExecutorService _executorService;
|
||||
private final int _statsCollectionInterval;
|
||||
private volatile boolean _isRunning = true;
|
||||
|
||||
/**
|
||||
* Constructor for statistics collector.
|
||||
*
|
||||
* @param statsCollectorInputList List of statistics collector input.
|
||||
* @param statsCollectionIntervalInMilliSeconds Statistics collection time
|
||||
* period (specified in milliseconds).
|
||||
*/
|
||||
public StatisticsCollector(List<StatsCollectorInput> statsCollectorInputList,
|
||||
int statsCollectionIntervalInMilliSeconds) {
|
||||
_statsCollectorInputList = statsCollectorInputList;
|
||||
_statsCollectionInterval = statsCollectionIntervalInMilliSeconds;
|
||||
|
||||
_executorService = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
_executorService.submit(collectStatistics());
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts down statistics collector.
|
||||
*
|
||||
* @param shutdownTimeout Time in milli-seconds to wait for shutdown before
|
||||
* killing the collection process.
|
||||
*/
|
||||
public void shutDown(int shutdownTimeout) throws InterruptedException {
|
||||
_isRunning = false;
|
||||
|
||||
_executorService.shutdownNow();
|
||||
// Wait for collectStatistics runnable to finish so that disposal of
|
||||
// statistics does not cause any exceptions to be thrown.
|
||||
_executorService.awaitTermination(shutdownTimeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private Runnable collectStatistics() {
|
||||
return new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (_isRunning) {
|
||||
try {
|
||||
if(Thread.currentThread().isInterrupted()) {
|
||||
break;
|
||||
}
|
||||
for(StatsCollectorInput statsCollectorInput :
|
||||
_statsCollectorInputList) {
|
||||
Statistics statistics = statsCollectorInput.getStatistics();
|
||||
StatisticsCollectorCallback statsCallback =
|
||||
statsCollectorInput.getCallback();
|
||||
|
||||
// Collect ticker data
|
||||
for(TickerType ticker : TickerType.values()) {
|
||||
long tickerValue = statistics.getTickerCount(ticker);
|
||||
statsCallback.tickerCallback(ticker, tickerValue);
|
||||
}
|
||||
|
||||
// Collect histogram data
|
||||
for(HistogramType histogramType : HistogramType.values()) {
|
||||
HistogramData histogramData =
|
||||
statistics.geHistogramData(histogramType);
|
||||
statsCallback.histogramCallback(histogramType, histogramData);
|
||||
}
|
||||
|
||||
Thread.sleep(_statsCollectionInterval);
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException("Error while calculating statistics", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
34
java/org/rocksdb/StatisticsCollectorCallback.java
Normal file
34
java/org/rocksdb/StatisticsCollectorCallback.java
Normal 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;
|
||||
|
||||
/**
|
||||
* Callback interface provided to StatisticsCollector.
|
||||
*
|
||||
* Thread safety:
|
||||
* StatisticsCollector doesn't make any guarantees about thread safety.
|
||||
* If the same reference of StatisticsCollectorCallback is passed to multiple
|
||||
* StatisticsCollector references, then its the responsibility of the
|
||||
* user to make StatisticsCollectorCallback's implementation thread-safe.
|
||||
*
|
||||
* @param tickerType
|
||||
* @param tickerCount
|
||||
*/
|
||||
public interface StatisticsCollectorCallback {
|
||||
/**
|
||||
* Callback function to get ticker values.
|
||||
* @param tickerType Ticker type.
|
||||
* @param tickerCount Value of ticker type.
|
||||
*/
|
||||
void tickerCallback(TickerType tickerType, long tickerCount);
|
||||
|
||||
/**
|
||||
* Callback function to get histogram values.
|
||||
* @param histType Histogram type.
|
||||
* @param histData Histogram data.
|
||||
*/
|
||||
void histogramCallback(HistogramType histType, HistogramData histData);
|
||||
}
|
||||
35
java/org/rocksdb/StatsCollectorInput.java
Normal file
35
java/org/rocksdb/StatsCollectorInput.java
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* Contains all information necessary to collect statistics from one instance
|
||||
* of DB statistics.
|
||||
*/
|
||||
public class StatsCollectorInput {
|
||||
private final Statistics _statistics;
|
||||
private final StatisticsCollectorCallback _statsCallback;
|
||||
|
||||
/**
|
||||
* Constructor for StatsCollectorInput.
|
||||
*
|
||||
* @param statistics Reference of DB statistics.
|
||||
* @param statsCallback Reference of statistics callback interface.
|
||||
*/
|
||||
public StatsCollectorInput(Statistics statistics,
|
||||
StatisticsCollectorCallback statsCallback) {
|
||||
_statistics = statistics;
|
||||
_statsCallback = statsCallback;
|
||||
}
|
||||
|
||||
public Statistics getStatistics() {
|
||||
return _statistics;
|
||||
}
|
||||
|
||||
public StatisticsCollectorCallback getCallback() {
|
||||
return _statsCallback;
|
||||
}
|
||||
}
|
||||
20
java/org/rocksdb/TableFormatConfig.java
Normal file
20
java/org/rocksdb/TableFormatConfig.java
Normal file
@@ -0,0 +1,20 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* TableFormatConfig is used to config the internal Table format of a RocksDB.
|
||||
* To make a RocksDB to use a specific Table format, its associated
|
||||
* TableFormatConfig should be properly set and passed into Options via
|
||||
* Options.setTableFormatConfig() and open the db using that Options.
|
||||
*/
|
||||
public abstract class TableFormatConfig {
|
||||
/**
|
||||
* This function should only be called by Options.setTableFormatConfig(),
|
||||
* which will create a c++ shared-pointer to the c++ TableFactory
|
||||
* that associated with the Java TableFormatConfig.
|
||||
*/
|
||||
abstract protected long newTableFactoryHandle();
|
||||
}
|
||||
123
java/org/rocksdb/TickerType.java
Normal file
123
java/org/rocksdb/TickerType.java
Normal file
@@ -0,0 +1,123 @@
|
||||
// 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;
|
||||
|
||||
public enum TickerType {
|
||||
// total block cache misses
|
||||
// REQUIRES: BLOCK_CACHE_MISS == BLOCK_CACHE_INDEX_MISS +
|
||||
// BLOCK_CACHE_FILTER_MISS +
|
||||
// BLOCK_CACHE_DATA_MISS;
|
||||
BLOCK_CACHE_MISS(0),
|
||||
// total block cache hit
|
||||
// REQUIRES: BLOCK_CACHE_HIT == BLOCK_CACHE_INDEX_HIT +
|
||||
// BLOCK_CACHE_FILTER_HIT +
|
||||
// BLOCK_CACHE_DATA_HIT;
|
||||
BLOCK_CACHE_HIT(1),
|
||||
// # of blocks added to block cache.
|
||||
BLOCK_CACHE_ADD(2),
|
||||
// # of times cache miss when accessing index block from block cache.
|
||||
BLOCK_CACHE_INDEX_MISS(3),
|
||||
// # of times cache hit when accessing index block from block cache.
|
||||
BLOCK_CACHE_INDEX_HIT(4),
|
||||
// # of times cache miss when accessing filter block from block cache.
|
||||
BLOCK_CACHE_FILTER_MISS(5),
|
||||
// # of times cache hit when accessing filter block from block cache.
|
||||
BLOCK_CACHE_FILTER_HIT(6),
|
||||
// # of times cache miss when accessing data block from block cache.
|
||||
BLOCK_CACHE_DATA_MISS(7),
|
||||
// # of times cache hit when accessing data block from block cache.
|
||||
BLOCK_CACHE_DATA_HIT(8),
|
||||
// # of times bloom filter has avoided file reads.
|
||||
BLOOM_FILTER_USEFUL(9),
|
||||
|
||||
// # of memtable hits.
|
||||
MEMTABLE_HIT(10),
|
||||
// # of memtable misses.
|
||||
MEMTABLE_MISS(11),
|
||||
|
||||
/**
|
||||
* COMPACTION_KEY_DROP_* count the reasons for key drop during compaction
|
||||
* There are 3 reasons currently.
|
||||
*/
|
||||
COMPACTION_KEY_DROP_NEWER_ENTRY(12), // key was written with a newer value.
|
||||
COMPACTION_KEY_DROP_OBSOLETE(13), // The key is obsolete.
|
||||
COMPACTION_KEY_DROP_USER(14), // user compaction function has dropped the key.
|
||||
|
||||
// Number of keys written to the database via the Put and Write call's
|
||||
NUMBER_KEYS_WRITTEN(15),
|
||||
// Number of Keys read,
|
||||
NUMBER_KEYS_READ(16),
|
||||
// Number keys updated, if inplace update is enabled
|
||||
NUMBER_KEYS_UPDATED(17),
|
||||
// Bytes written / read
|
||||
BYTES_WRITTEN(18),
|
||||
BYTES_READ(19),
|
||||
NO_FILE_CLOSES(20),
|
||||
NO_FILE_OPENS(21),
|
||||
NO_FILE_ERRORS(22),
|
||||
// Time system had to wait to do LO-L1 compactions
|
||||
STALL_L0_SLOWDOWN_MICROS(23),
|
||||
// Time system had to wait to move memtable to L1.
|
||||
STALL_MEMTABLE_COMPACTION_MICROS(24),
|
||||
// write throttle because of too many files in L0
|
||||
STALL_L0_NUM_FILES_MICROS(25),
|
||||
RATE_LIMIT_DELAY_MILLIS(26),
|
||||
NO_ITERATORS(27), // number of iterators currently open
|
||||
|
||||
// Number of MultiGet calls, keys read, and bytes read
|
||||
NUMBER_MULTIGET_CALLS(28),
|
||||
NUMBER_MULTIGET_KEYS_READ(29),
|
||||
NUMBER_MULTIGET_BYTES_READ(30),
|
||||
|
||||
// Number of deletes records that were not required to be
|
||||
// written to storage because key does not exist
|
||||
NUMBER_FILTERED_DELETES(31),
|
||||
NUMBER_MERGE_FAILURES(32),
|
||||
SEQUENCE_NUMBER(33),
|
||||
|
||||
// number of times bloom was checked before creating iterator on a
|
||||
// file, and the number of times the check was useful in avoiding
|
||||
// iterator creation (and thus likely IOPs).
|
||||
BLOOM_FILTER_PREFIX_CHECKED(34),
|
||||
BLOOM_FILTER_PREFIX_USEFUL(35),
|
||||
|
||||
// Number of times we had to reseek inside an iteration to skip
|
||||
// over large number of keys with same userkey.
|
||||
NUMBER_OF_RESEEKS_IN_ITERATION(36),
|
||||
|
||||
// Record the number of calls to GetUpadtesSince. Useful to keep track of
|
||||
// transaction log iterator refreshes
|
||||
GET_UPDATES_SINCE_CALLS(37),
|
||||
BLOCK_CACHE_COMPRESSED_MISS(38), // miss in the compressed block cache
|
||||
BLOCK_CACHE_COMPRESSED_HIT(39), // hit in the compressed block cache
|
||||
WAL_FILE_SYNCED(40), // Number of times WAL sync is done
|
||||
WAL_FILE_BYTES(41), // Number of bytes written to WAL
|
||||
|
||||
// Writes can be processed by requesting thread or by the thread at the
|
||||
// head of the writers queue.
|
||||
WRITE_DONE_BY_SELF(42),
|
||||
WRITE_DONE_BY_OTHER(43),
|
||||
WRITE_WITH_WAL(44), // Number of Write calls that request WAL
|
||||
COMPACT_READ_BYTES(45), // Bytes read during compaction
|
||||
COMPACT_WRITE_BYTES(46), // Bytes written during compaction
|
||||
|
||||
// Number of table's properties loaded directly from file, without creating
|
||||
// table reader object.
|
||||
NUMBER_DIRECT_LOAD_TABLE_PROPERTIES(47),
|
||||
NUMBER_SUPERVERSION_ACQUIRES(48),
|
||||
NUMBER_SUPERVERSION_RELEASES(49),
|
||||
NUMBER_SUPERVERSION_CLEANUPS(50);
|
||||
|
||||
private final int value_;
|
||||
|
||||
private TickerType(int value) {
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value_;
|
||||
}
|
||||
}
|
||||
40
java/org/rocksdb/VectorMemTableConfig.java
Normal file
40
java/org/rocksdb/VectorMemTableConfig.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package org.rocksdb;
|
||||
|
||||
/**
|
||||
* The config for vector memtable representation.
|
||||
*/
|
||||
public class VectorMemTableConfig extends MemTableConfig {
|
||||
public static final int DEFAULT_RESERVED_SIZE = 0;
|
||||
public VectorMemTableConfig() {
|
||||
reservedSize_ = DEFAULT_RESERVED_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the initial size of the vector that will be used
|
||||
* by the memtable created based on this config.
|
||||
*
|
||||
* @param size the initial size of the vector.
|
||||
* @return the reference to the current config.
|
||||
*/
|
||||
public VectorMemTableConfig setReservedSize(int size) {
|
||||
reservedSize_ = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the initial size of the vector used by the memtable
|
||||
* created based on this config.
|
||||
*
|
||||
* @return the initial size of the vector.
|
||||
*/
|
||||
public int reservedSize() {
|
||||
return reservedSize_;
|
||||
}
|
||||
|
||||
@Override protected long newMemTableFactoryHandle() {
|
||||
return newMemTableFactoryHandle(reservedSize_);
|
||||
}
|
||||
|
||||
private native long newMemTableFactoryHandle(long reservedSize);
|
||||
private int reservedSize_;
|
||||
}
|
||||
112
java/org/rocksdb/WriteBatch.java
Normal file
112
java/org/rocksdb/WriteBatch.java
Normal file
@@ -0,0 +1,112 @@
|
||||
// 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;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* WriteBatch holds a collection of updates to apply atomically to a DB.
|
||||
*
|
||||
* The updates are applied in the order in which they are added
|
||||
* to the WriteBatch. For example, the value of "key" will be "v3"
|
||||
* after the following batch is written:
|
||||
*
|
||||
* batch.put("key", "v1");
|
||||
* batch.remove("key");
|
||||
* batch.put("key", "v2");
|
||||
* batch.put("key", "v3");
|
||||
*
|
||||
* Multiple threads can invoke const methods on a WriteBatch without
|
||||
* external synchronization, but if any of the threads may call a
|
||||
* non-const method, all threads accessing the same WriteBatch must use
|
||||
* external synchronization.
|
||||
*/
|
||||
public class WriteBatch extends RocksObject {
|
||||
public WriteBatch() {
|
||||
super();
|
||||
newWriteBatch(0);
|
||||
}
|
||||
|
||||
public WriteBatch(int reserved_bytes) {
|
||||
nativeHandle_ = 0;
|
||||
newWriteBatch(reserved_bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of updates in the batch.
|
||||
*/
|
||||
public native int count();
|
||||
|
||||
/**
|
||||
* Store the mapping "key->value" in the database.
|
||||
*/
|
||||
public void put(byte[] key, byte[] value) {
|
||||
put(key, key.length, value, value.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge "value" with the existing value of "key" in the database.
|
||||
* "key->merge(existing, value)"
|
||||
*/
|
||||
public void merge(byte[] key, byte[] value) {
|
||||
merge(key, key.length, value, value.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the database contains a mapping for "key", erase it. Else do nothing.
|
||||
*/
|
||||
public void remove(byte[] key) {
|
||||
remove(key, key.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a blob of arbitrary size to the records in this batch. The blob will
|
||||
* be stored in the transaction log but not in any other file. In particular,
|
||||
* it will not be persisted to the SST files. When iterating over this
|
||||
* WriteBatch, WriteBatch::Handler::LogData will be called with the contents
|
||||
* of the blob as it is encountered. Blobs, puts, deletes, and merges will be
|
||||
* encountered in the same order in thich they were inserted. The blob will
|
||||
* NOT consume sequence number(s) and will NOT increase the count of the batch
|
||||
*
|
||||
* Example application: add timestamps to the transaction log for use in
|
||||
* replication.
|
||||
*/
|
||||
public void putLogData(byte[] blob) {
|
||||
putLogData(blob, blob.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all updates buffered in this batch
|
||||
*/
|
||||
public native void clear();
|
||||
|
||||
/**
|
||||
* Delete the c++ side pointer.
|
||||
*/
|
||||
@Override protected void disposeInternal() {
|
||||
assert(isInitialized());
|
||||
disposeInternal(nativeHandle_);
|
||||
}
|
||||
|
||||
private native void newWriteBatch(int reserved_bytes);
|
||||
private native void put(byte[] key, int keyLen,
|
||||
byte[] value, int valueLen);
|
||||
private native void merge(byte[] key, int keyLen,
|
||||
byte[] value, int valueLen);
|
||||
private native void remove(byte[] key, int keyLen);
|
||||
private native void putLogData(byte[] blob, int blobLen);
|
||||
private native void disposeInternal(long handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Package-private class which provides java api to access
|
||||
* c++ WriteBatchInternal.
|
||||
*/
|
||||
class WriteBatchInternal {
|
||||
static native void setSequence(WriteBatch batch, long sn);
|
||||
static native long sequence(WriteBatch batch);
|
||||
static native void append(WriteBatch b1, WriteBatch b2);
|
||||
}
|
||||
124
java/org/rocksdb/WriteBatchTest.java
Normal file
124
java/org/rocksdb/WriteBatchTest.java
Normal file
@@ -0,0 +1,124 @@
|
||||
// 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.
|
||||
//
|
||||
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||
package org.rocksdb;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* This class mimics the db/write_batch_test.cc in the c++ rocksdb library.
|
||||
*/
|
||||
public class WriteBatchTest {
|
||||
static {
|
||||
RocksDB.loadLibrary();
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println("Testing WriteBatchTest.Empty ===");
|
||||
Empty();
|
||||
|
||||
System.out.println("Testing WriteBatchTest.Multiple ===");
|
||||
Multiple();
|
||||
|
||||
System.out.println("Testing WriteBatchTest.Append ===");
|
||||
Append();
|
||||
|
||||
System.out.println("Testing WriteBatchTest.Blob ===");
|
||||
Blob();
|
||||
|
||||
// The following tests have not yet ported.
|
||||
// Continue();
|
||||
// PutGatherSlices();
|
||||
|
||||
System.out.println("Passed all WriteBatchTest!");
|
||||
}
|
||||
|
||||
static void Empty() {
|
||||
WriteBatch batch = new WriteBatch();
|
||||
assert(batch.count() == 0);
|
||||
}
|
||||
|
||||
static void Multiple() {
|
||||
try {
|
||||
WriteBatch batch = new WriteBatch();
|
||||
batch.put("foo".getBytes("US-ASCII"), "bar".getBytes("US-ASCII"));
|
||||
batch.remove("box".getBytes("US-ASCII"));
|
||||
batch.put("baz".getBytes("US-ASCII"), "boo".getBytes("US-ASCII"));
|
||||
WriteBatchInternal.setSequence(batch, 100);
|
||||
assert(100 == WriteBatchInternal.sequence(batch));
|
||||
assert(3 == batch.count());
|
||||
assert(new String("Put(baz, boo)@102" +
|
||||
"Delete(box)@101" +
|
||||
"Put(foo, bar)@100")
|
||||
.equals(new String(getContents(batch), "US-ASCII")));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
System.err.println(e);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
static void Append() {
|
||||
WriteBatch b1 = new WriteBatch();
|
||||
WriteBatch b2 = new WriteBatch();
|
||||
WriteBatchInternal.setSequence(b1, 200);
|
||||
WriteBatchInternal.setSequence(b2, 300);
|
||||
WriteBatchInternal.append(b1, b2);
|
||||
assert(getContents(b1).length == 0);
|
||||
assert(b1.count() == 0);
|
||||
try {
|
||||
b2.put("a".getBytes("US-ASCII"), "va".getBytes("US-ASCII"));
|
||||
WriteBatchInternal.append(b1, b2);
|
||||
assert("Put(a, va)@200".equals(new String(getContents(b1), "US-ASCII")));
|
||||
assert(1 == b1.count());
|
||||
b2.clear();
|
||||
b2.put("b".getBytes("US-ASCII"), "vb".getBytes("US-ASCII"));
|
||||
WriteBatchInternal.append(b1, b2);
|
||||
assert(new String("Put(a, va)@200" +
|
||||
"Put(b, vb)@201")
|
||||
.equals(new String(getContents(b1), "US-ASCII")));
|
||||
assert(2 == b1.count());
|
||||
b2.remove("foo".getBytes("US-ASCII"));
|
||||
WriteBatchInternal.append(b1, b2);
|
||||
assert(new String("Put(a, va)@200" +
|
||||
"Put(b, vb)@202" +
|
||||
"Put(b, vb)@201" +
|
||||
"Delete(foo)@203")
|
||||
.equals(new String(getContents(b1), "US-ASCII")));
|
||||
assert(4 == b1.count());
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
System.err.println(e);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
static void Blob() {
|
||||
WriteBatch batch = new WriteBatch();
|
||||
try {
|
||||
batch.put("k1".getBytes("US-ASCII"), "v1".getBytes("US-ASCII"));
|
||||
batch.put("k2".getBytes("US-ASCII"), "v2".getBytes("US-ASCII"));
|
||||
batch.put("k3".getBytes("US-ASCII"), "v3".getBytes("US-ASCII"));
|
||||
batch.putLogData("blob1".getBytes("US-ASCII"));
|
||||
batch.remove("k2".getBytes("US-ASCII"));
|
||||
batch.putLogData("blob2".getBytes("US-ASCII"));
|
||||
batch.merge("foo".getBytes("US-ASCII"), "bar".getBytes("US-ASCII"));
|
||||
assert(5 == batch.count());
|
||||
assert(new String("Merge(foo, bar)@4" +
|
||||
"Put(k1, v1)@0" +
|
||||
"Delete(k2)@3" +
|
||||
"Put(k2, v2)@1" +
|
||||
"Put(k3, v3)@2")
|
||||
.equals(new String(getContents(batch), "US-ASCII")));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
System.err.println(e);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
static native byte[] getContents(WriteBatch batch);
|
||||
}
|
||||
99
java/org/rocksdb/WriteOptions.java
Normal file
99
java/org/rocksdb/WriteOptions.java
Normal file
@@ -0,0 +1,99 @@
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* Options that control write operations.
|
||||
*
|
||||
* Note that developers should call WriteOptions.dispose() to release the
|
||||
* c++ side memory before a WriteOptions instance runs out of scope.
|
||||
*/
|
||||
public class WriteOptions extends RocksObject {
|
||||
public WriteOptions() {
|
||||
super();
|
||||
newWriteOptions();
|
||||
}
|
||||
|
||||
@Override protected void disposeInternal() {
|
||||
assert(isInitialized());
|
||||
disposeInternal(nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, the write will be flushed from the operating system
|
||||
* buffer cache (by calling WritableFile::Sync()) before the write
|
||||
* is considered complete. If this flag is true, writes will be
|
||||
* slower.
|
||||
*
|
||||
* If this flag is false, and the machine crashes, some recent
|
||||
* writes may be lost. Note that if it is just the process that
|
||||
* crashes (i.e., the machine does not reboot), no writes will be
|
||||
* lost even if sync==false.
|
||||
*
|
||||
* In other words, a DB write with sync==false has similar
|
||||
* crash semantics as the "write()" system call. A DB write
|
||||
* with sync==true has similar crash semantics to a "write()"
|
||||
* system call followed by "fdatasync()".
|
||||
*
|
||||
* Default: false
|
||||
*
|
||||
* @param flag a boolean flag to indicate whether a write
|
||||
* should be synchronized.
|
||||
* @return the instance of the current WriteOptions.
|
||||
*/
|
||||
public WriteOptions setSync(boolean flag) {
|
||||
setSync(nativeHandle_, flag);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, the write will be flushed from the operating system
|
||||
* buffer cache (by calling WritableFile::Sync()) before the write
|
||||
* is considered complete. If this flag is true, writes will be
|
||||
* slower.
|
||||
*
|
||||
* If this flag is false, and the machine crashes, some recent
|
||||
* writes may be lost. Note that if it is just the process that
|
||||
* crashes (i.e., the machine does not reboot), no writes will be
|
||||
* lost even if sync==false.
|
||||
*
|
||||
* In other words, a DB write with sync==false has similar
|
||||
* crash semantics as the "write()" system call. A DB write
|
||||
* with sync==true has similar crash semantics to a "write()"
|
||||
* system call followed by "fdatasync()".
|
||||
*/
|
||||
public boolean sync() {
|
||||
return sync(nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, writes will not first go to the write ahead log,
|
||||
* and the write may got lost after a crash.
|
||||
*
|
||||
* @param flag a boolean flag to specify whether to disable
|
||||
* write-ahead-log on writes.
|
||||
* @return the instance of the current WriteOptions.
|
||||
*/
|
||||
public WriteOptions setDisableWAL(boolean flag) {
|
||||
setDisableWAL(nativeHandle_, flag);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, writes will not first go to the write ahead log,
|
||||
* and the write may got lost after a crash.
|
||||
*/
|
||||
public boolean disableWAL() {
|
||||
return disableWAL(nativeHandle_);
|
||||
}
|
||||
|
||||
private native void newWriteOptions();
|
||||
private native void setSync(long handle, boolean flag);
|
||||
private native boolean sync(long handle);
|
||||
private native void setDisableWAL(long handle, boolean flag);
|
||||
private native boolean disableWAL(long handle);
|
||||
private native void disposeInternal(long handle);
|
||||
}
|
||||
1625
java/org/rocksdb/benchmark/DbBenchmark.java
Normal file
1625
java/org/rocksdb/benchmark/DbBenchmark.java
Normal file
File diff suppressed because it is too large
Load Diff
63
java/org/rocksdb/test/BackupableDBTest.java
Normal file
63
java/org/rocksdb/test/BackupableDBTest.java
Normal file
@@ -0,0 +1,63 @@
|
||||
// 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.*;
|
||||
|
||||
public class BackupableDBTest {
|
||||
static final String db_path = "/tmp/backupablejni_db";
|
||||
static final String backup_path = "/tmp/backupablejni_db_backup";
|
||||
static {
|
||||
RocksDB.loadLibrary();
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
|
||||
Options opt = new Options();
|
||||
opt.setCreateIfMissing(true);
|
||||
|
||||
BackupableDBOptions bopt = new BackupableDBOptions(backup_path, false,
|
||||
true, false, true, 0, 0);
|
||||
BackupableDB bdb = null;
|
||||
|
||||
try {
|
||||
bdb = BackupableDB.open(opt, bopt, db_path);
|
||||
|
||||
bdb.put("abc".getBytes(), "def".getBytes());
|
||||
bdb.put("ghi".getBytes(), "jkl".getBytes());
|
||||
bdb.createNewBackup(true);
|
||||
|
||||
// delete record after backup
|
||||
bdb.remove("abc".getBytes());
|
||||
byte[] value = bdb.get("abc".getBytes());
|
||||
assert(value == null);
|
||||
bdb.close();
|
||||
|
||||
// restore from backup
|
||||
RestoreOptions ropt = new RestoreOptions(false);
|
||||
RestoreBackupableDB rdb = new RestoreBackupableDB(bopt);
|
||||
rdb.restoreDBFromLatestBackup(db_path, db_path,
|
||||
ropt);
|
||||
rdb.dispose();
|
||||
ropt.dispose();
|
||||
|
||||
// verify that backed up data contains deleted record
|
||||
bdb = BackupableDB.open(opt, bopt, db_path);
|
||||
value = bdb.get("abc".getBytes());
|
||||
assert(new String(value).equals("def"));
|
||||
|
||||
System.out.println("Backup and restore test passed");
|
||||
} catch (RocksDBException e) {
|
||||
System.err.format("[ERROR]: %s%n", e);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
opt.dispose();
|
||||
bopt.dispose();
|
||||
if (bdb != null) {
|
||||
bdb.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
424
java/org/rocksdb/test/OptionsTest.java
Normal file
424
java/org/rocksdb/test/OptionsTest.java
Normal file
@@ -0,0 +1,424 @@
|
||||
// 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 java.util.Random;
|
||||
import org.rocksdb.RocksDB;
|
||||
import org.rocksdb.Options;
|
||||
|
||||
public class OptionsTest {
|
||||
static {
|
||||
RocksDB.loadLibrary();
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Options opt = new Options();
|
||||
Random rand = new Random();
|
||||
{ // CreateIfMissing test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setCreateIfMissing(boolValue);
|
||||
assert(opt.createIfMissing() == boolValue);
|
||||
}
|
||||
|
||||
{ // ErrorIfExists test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setErrorIfExists(boolValue);
|
||||
assert(opt.errorIfExists() == boolValue);
|
||||
}
|
||||
|
||||
{ // ParanoidChecks test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setParanoidChecks(boolValue);
|
||||
assert(opt.paranoidChecks() == boolValue);
|
||||
}
|
||||
|
||||
{ // MaxOpenFiles test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setMaxOpenFiles(intValue);
|
||||
assert(opt.maxOpenFiles() == intValue);
|
||||
}
|
||||
|
||||
{ // DisableDataSync test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setDisableDataSync(boolValue);
|
||||
assert(opt.disableDataSync() == boolValue);
|
||||
}
|
||||
|
||||
{ // UseFsync test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setUseFsync(boolValue);
|
||||
assert(opt.useFsync() == boolValue);
|
||||
}
|
||||
|
||||
{ // DbStatsLogInterval test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setDbStatsLogInterval(intValue);
|
||||
assert(opt.dbStatsLogInterval() == intValue);
|
||||
}
|
||||
|
||||
{ // DbLogDir test
|
||||
String str = "path/to/DbLogDir";
|
||||
opt.setDbLogDir(str);
|
||||
assert(opt.dbLogDir().equals(str));
|
||||
}
|
||||
|
||||
{ // WalDir test
|
||||
String str = "path/to/WalDir";
|
||||
opt.setWalDir(str);
|
||||
assert(opt.walDir().equals(str));
|
||||
}
|
||||
|
||||
{ // DeleteObsoleteFilesPeriodMicros test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setDeleteObsoleteFilesPeriodMicros(longValue);
|
||||
assert(opt.deleteObsoleteFilesPeriodMicros() == longValue);
|
||||
}
|
||||
|
||||
{ // MaxBackgroundCompactions test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setMaxBackgroundCompactions(intValue);
|
||||
assert(opt.maxBackgroundCompactions() == intValue);
|
||||
}
|
||||
|
||||
{ // MaxBackgroundFlushes test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setMaxBackgroundFlushes(intValue);
|
||||
assert(opt.maxBackgroundFlushes() == intValue);
|
||||
}
|
||||
|
||||
{ // MaxLogFileSize test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setMaxLogFileSize(longValue);
|
||||
assert(opt.maxLogFileSize() == longValue);
|
||||
}
|
||||
|
||||
{ // LogFileTimeToRoll test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setLogFileTimeToRoll(longValue);
|
||||
assert(opt.logFileTimeToRoll() == longValue);
|
||||
}
|
||||
|
||||
{ // KeepLogFileNum test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setKeepLogFileNum(longValue);
|
||||
assert(opt.keepLogFileNum() == longValue);
|
||||
}
|
||||
|
||||
{ // MaxManifestFileSize test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setMaxManifestFileSize(longValue);
|
||||
assert(opt.maxManifestFileSize() == longValue);
|
||||
}
|
||||
|
||||
{ // TableCacheNumshardbits test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setTableCacheNumshardbits(intValue);
|
||||
assert(opt.tableCacheNumshardbits() == intValue);
|
||||
}
|
||||
|
||||
{ // TableCacheRemoveScanCountLimit test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setTableCacheRemoveScanCountLimit(intValue);
|
||||
assert(opt.tableCacheRemoveScanCountLimit() == intValue);
|
||||
}
|
||||
|
||||
{ // WalTtlSeconds test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setWalTtlSeconds(longValue);
|
||||
assert(opt.walTtlSeconds() == longValue);
|
||||
}
|
||||
|
||||
{ // ManifestPreallocationSize test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setManifestPreallocationSize(longValue);
|
||||
assert(opt.manifestPreallocationSize() == longValue);
|
||||
}
|
||||
|
||||
{ // AllowOsBuffer test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setAllowOsBuffer(boolValue);
|
||||
assert(opt.allowOsBuffer() == boolValue);
|
||||
}
|
||||
|
||||
{ // AllowMmapReads test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setAllowMmapReads(boolValue);
|
||||
assert(opt.allowMmapReads() == boolValue);
|
||||
}
|
||||
|
||||
{ // AllowMmapWrites test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setAllowMmapWrites(boolValue);
|
||||
assert(opt.allowMmapWrites() == boolValue);
|
||||
}
|
||||
|
||||
{ // IsFdCloseOnExec test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setIsFdCloseOnExec(boolValue);
|
||||
assert(opt.isFdCloseOnExec() == boolValue);
|
||||
}
|
||||
|
||||
{ // SkipLogErrorOnRecovery test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setSkipLogErrorOnRecovery(boolValue);
|
||||
assert(opt.skipLogErrorOnRecovery() == boolValue);
|
||||
}
|
||||
|
||||
{ // StatsDumpPeriodSec test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setStatsDumpPeriodSec(intValue);
|
||||
assert(opt.statsDumpPeriodSec() == intValue);
|
||||
}
|
||||
|
||||
{ // AdviseRandomOnOpen test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setAdviseRandomOnOpen(boolValue);
|
||||
assert(opt.adviseRandomOnOpen() == boolValue);
|
||||
}
|
||||
|
||||
{ // UseAdaptiveMutex test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setUseAdaptiveMutex(boolValue);
|
||||
assert(opt.useAdaptiveMutex() == boolValue);
|
||||
}
|
||||
|
||||
{ // BytesPerSync test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setBytesPerSync(longValue);
|
||||
assert(opt.bytesPerSync() == longValue);
|
||||
}
|
||||
|
||||
{ // AllowThreadLocal test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setAllowThreadLocal(boolValue);
|
||||
assert(opt.allowThreadLocal() == boolValue);
|
||||
}
|
||||
|
||||
{ // WriteBufferSize test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setWriteBufferSize(longValue);
|
||||
assert(opt.writeBufferSize() == longValue);
|
||||
}
|
||||
|
||||
{ // MaxWriteBufferNumber test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setMaxWriteBufferNumber(intValue);
|
||||
assert(opt.maxWriteBufferNumber() == intValue);
|
||||
}
|
||||
|
||||
{ // MinWriteBufferNumberToMerge test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setMinWriteBufferNumberToMerge(intValue);
|
||||
assert(opt.minWriteBufferNumberToMerge() == intValue);
|
||||
}
|
||||
|
||||
{ // BlockSize test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setBlockSize(longValue);
|
||||
assert(opt.blockSize() == longValue);
|
||||
}
|
||||
|
||||
{ // BlockRestartInterval test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setBlockRestartInterval(intValue);
|
||||
assert(opt.blockRestartInterval() == intValue);
|
||||
}
|
||||
|
||||
{ // WholeKeyFiltering test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setWholeKeyFiltering(boolValue);
|
||||
assert(opt.wholeKeyFiltering() == boolValue);
|
||||
}
|
||||
|
||||
{ // NumLevels test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setNumLevels(intValue);
|
||||
assert(opt.numLevels() == intValue);
|
||||
}
|
||||
|
||||
{ // LevelFileNumCompactionTrigger test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setLevelZeroFileNumCompactionTrigger(intValue);
|
||||
assert(opt.levelZeroFileNumCompactionTrigger() == intValue);
|
||||
}
|
||||
|
||||
{ // LevelSlowdownWritesTrigger test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setLevelZeroSlowdownWritesTrigger(intValue);
|
||||
assert(opt.levelZeroSlowdownWritesTrigger() == intValue);
|
||||
}
|
||||
|
||||
{ // LevelStopWritesTrigger test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setLevelZeroStopWritesTrigger(intValue);
|
||||
assert(opt.levelZeroStopWritesTrigger() == intValue);
|
||||
}
|
||||
|
||||
{ // MaxMemCompactionLevel test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setMaxMemCompactionLevel(intValue);
|
||||
assert(opt.maxMemCompactionLevel() == intValue);
|
||||
}
|
||||
|
||||
{ // TargetFileSizeBase test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setTargetFileSizeBase(intValue);
|
||||
assert(opt.targetFileSizeBase() == intValue);
|
||||
}
|
||||
|
||||
{ // TargetFileSizeMultiplier test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setTargetFileSizeMultiplier(intValue);
|
||||
assert(opt.targetFileSizeMultiplier() == intValue);
|
||||
}
|
||||
|
||||
{ // MaxBytesForLevelBase test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setMaxBytesForLevelBase(longValue);
|
||||
assert(opt.maxBytesForLevelBase() == longValue);
|
||||
}
|
||||
|
||||
{ // MaxBytesForLevelMultiplier test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setMaxBytesForLevelMultiplier(intValue);
|
||||
assert(opt.maxBytesForLevelMultiplier() == intValue);
|
||||
}
|
||||
|
||||
{ // ExpandedCompactionFactor test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setExpandedCompactionFactor(intValue);
|
||||
assert(opt.expandedCompactionFactor() == intValue);
|
||||
}
|
||||
|
||||
{ // SourceCompactionFactor test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setSourceCompactionFactor(intValue);
|
||||
assert(opt.sourceCompactionFactor() == intValue);
|
||||
}
|
||||
|
||||
{ // MaxGrandparentOverlapFactor test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setMaxGrandparentOverlapFactor(intValue);
|
||||
assert(opt.maxGrandparentOverlapFactor() == intValue);
|
||||
}
|
||||
|
||||
{ // DisableSeekCompaction test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setDisableSeekCompaction(boolValue);
|
||||
assert(opt.disableSeekCompaction() == boolValue);
|
||||
}
|
||||
|
||||
{ // SoftRateLimit test
|
||||
double doubleValue = rand.nextDouble();
|
||||
opt.setSoftRateLimit(doubleValue);
|
||||
assert(opt.softRateLimit() == doubleValue);
|
||||
}
|
||||
|
||||
{ // HardRateLimit test
|
||||
double doubleValue = rand.nextDouble();
|
||||
opt.setHardRateLimit(doubleValue);
|
||||
assert(opt.hardRateLimit() == doubleValue);
|
||||
}
|
||||
|
||||
{ // RateLimitDelayMaxMilliseconds test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setRateLimitDelayMaxMilliseconds(intValue);
|
||||
assert(opt.rateLimitDelayMaxMilliseconds() == intValue);
|
||||
}
|
||||
|
||||
{ // NoBlockCache test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setNoBlockCache(boolValue);
|
||||
assert(opt.noBlockCache() == boolValue);
|
||||
}
|
||||
|
||||
{ // ArenaBlockSize test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setArenaBlockSize(longValue);
|
||||
assert(opt.arenaBlockSize() == longValue);
|
||||
}
|
||||
|
||||
{ // DisableAutoCompactions test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setDisableAutoCompactions(boolValue);
|
||||
assert(opt.disableAutoCompactions() == boolValue);
|
||||
}
|
||||
|
||||
{ // PurgeRedundantKvsWhileFlush test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setPurgeRedundantKvsWhileFlush(boolValue);
|
||||
assert(opt.purgeRedundantKvsWhileFlush() == boolValue);
|
||||
}
|
||||
|
||||
{ // BlockSizeDeviation test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setBlockSizeDeviation(intValue);
|
||||
assert(opt.blockSizeDeviation() == intValue);
|
||||
}
|
||||
|
||||
{ // VerifyChecksumsInCompaction test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setVerifyChecksumsInCompaction(boolValue);
|
||||
assert(opt.verifyChecksumsInCompaction() == boolValue);
|
||||
}
|
||||
|
||||
{ // FilterDeletes test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setFilterDeletes(boolValue);
|
||||
assert(opt.filterDeletes() == boolValue);
|
||||
}
|
||||
|
||||
{ // MaxSequentialSkipInIterations test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setMaxSequentialSkipInIterations(longValue);
|
||||
assert(opt.maxSequentialSkipInIterations() == longValue);
|
||||
}
|
||||
|
||||
{ // InplaceUpdateSupport test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setInplaceUpdateSupport(boolValue);
|
||||
assert(opt.inplaceUpdateSupport() == boolValue);
|
||||
}
|
||||
|
||||
{ // InplaceUpdateNumLocks test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setInplaceUpdateNumLocks(longValue);
|
||||
assert(opt.inplaceUpdateNumLocks() == longValue);
|
||||
}
|
||||
|
||||
{ // MemtablePrefixBloomBits test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setMemtablePrefixBloomBits(intValue);
|
||||
assert(opt.memtablePrefixBloomBits() == intValue);
|
||||
}
|
||||
|
||||
{ // MemtablePrefixBloomProbes test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setMemtablePrefixBloomProbes(intValue);
|
||||
assert(opt.memtablePrefixBloomProbes() == intValue);
|
||||
}
|
||||
|
||||
{ // BloomLocality test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setBloomLocality(intValue);
|
||||
assert(opt.bloomLocality() == intValue);
|
||||
}
|
||||
|
||||
{ // MaxSuccessiveMerges test
|
||||
long longValue = rand.nextLong();
|
||||
opt.setMaxSuccessiveMerges(longValue);
|
||||
assert(opt.maxSuccessiveMerges() == longValue);
|
||||
}
|
||||
|
||||
{ // MinPartialMergeOperands test
|
||||
int intValue = rand.nextInt();
|
||||
opt.setMinPartialMergeOperands(intValue);
|
||||
assert(opt.minPartialMergeOperands() == intValue);
|
||||
}
|
||||
|
||||
opt.dispose();
|
||||
System.out.println("Passed OptionsTest");
|
||||
}
|
||||
}
|
||||
40
java/org/rocksdb/test/ReadOptionsTest.java
Normal file
40
java/org/rocksdb/test/ReadOptionsTest.java
Normal file
@@ -0,0 +1,40 @@
|
||||
// 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 java.util.Random;
|
||||
import org.rocksdb.RocksDB;
|
||||
import org.rocksdb.ReadOptions;
|
||||
|
||||
public class ReadOptionsTest {
|
||||
static {
|
||||
RocksDB.loadLibrary();
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
ReadOptions opt = new ReadOptions();
|
||||
Random rand = new Random();
|
||||
{ // VerifyChecksums test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setVerifyChecksums(boolValue);
|
||||
assert(opt.verifyChecksums() == boolValue);
|
||||
}
|
||||
|
||||
{ // FillCache test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setFillCache(boolValue);
|
||||
assert(opt.fillCache() == boolValue);
|
||||
}
|
||||
|
||||
{ // Tailing test
|
||||
boolean boolValue = rand.nextBoolean();
|
||||
opt.setTailing(boolValue);
|
||||
assert(opt.tailing() == boolValue);
|
||||
}
|
||||
|
||||
opt.dispose();
|
||||
System.out.println("Passed ReadOptionsTest");
|
||||
}
|
||||
}
|
||||
43
java/org/rocksdb/test/StatisticsCollectorTest.java
Normal file
43
java/org/rocksdb/test/StatisticsCollectorTest.java
Normal 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;
|
||||
|
||||
import java.util.Collections;
|
||||
import org.rocksdb.*;
|
||||
|
||||
public class StatisticsCollectorTest {
|
||||
static final String db_path = "/tmp/backupablejni_db";
|
||||
static {
|
||||
RocksDB.loadLibrary();
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
throws InterruptedException, RocksDBException {
|
||||
Options opt = new Options().createStatistics().setCreateIfMissing(true);
|
||||
Statistics stats = opt.statisticsPtr();
|
||||
|
||||
RocksDB db = RocksDB.open(db_path);
|
||||
|
||||
StatsCallbackMock callback = new StatsCallbackMock();
|
||||
StatsCollectorInput statsInput = new StatsCollectorInput(stats, callback);
|
||||
|
||||
StatisticsCollector statsCollector = new StatisticsCollector(
|
||||
Collections.singletonList(statsInput), 100);
|
||||
statsCollector.start();
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
assert(callback.tickerCallbackCount > 0);
|
||||
assert(callback.histCallbackCount > 0);
|
||||
|
||||
statsCollector.shutDown(1000);
|
||||
|
||||
db.close();
|
||||
opt.dispose();
|
||||
|
||||
System.out.println("Stats collector test passed.!");
|
||||
}
|
||||
}
|
||||
22
java/org/rocksdb/test/StatsCallbackMock.java
Normal file
22
java/org/rocksdb/test/StatsCallbackMock.java
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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.*;
|
||||
|
||||
public class StatsCallbackMock implements StatisticsCollectorCallback {
|
||||
public int tickerCallbackCount = 0;
|
||||
public int histCallbackCount = 0;
|
||||
|
||||
public void tickerCallback(TickerType tickerType, long tickerCount) {
|
||||
tickerCallbackCount++;
|
||||
}
|
||||
|
||||
public void histogramCallback(HistogramType histType,
|
||||
HistogramData histData) {
|
||||
histCallbackCount++;
|
||||
}
|
||||
}
|
||||
37
java/org/rocksdb/util/Environment.java
Normal file
37
java/org/rocksdb/util/Environment.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package org.rocksdb.util;
|
||||
|
||||
public class Environment {
|
||||
private static String OS = System.getProperty("os.name").toLowerCase();
|
||||
|
||||
public static boolean isWindows() {
|
||||
return (OS.indexOf("win") >= 0);
|
||||
}
|
||||
|
||||
public static boolean isMac() {
|
||||
return (OS.indexOf("mac") >= 0);
|
||||
}
|
||||
|
||||
public static boolean isUnix() {
|
||||
return (OS.indexOf("nix") >= 0 ||
|
||||
OS.indexOf("nux") >= 0 ||
|
||||
OS.indexOf("aix") >= 0);
|
||||
}
|
||||
|
||||
public static String getSharedLibraryName(String name) {
|
||||
if (isUnix()) {
|
||||
return String.format("lib%s.so", name);
|
||||
} else if (isMac()) {
|
||||
return String.format("lib%s.dylib", name);
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static String getJniLibraryName(String name) {
|
||||
if (isUnix()) {
|
||||
return String.format("lib%s.so", name);
|
||||
} else if (isMac()) {
|
||||
return String.format("lib%s.jnilib", name);
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
16
java/org/rocksdb/util/SizeUnit.java
Normal file
16
java/org/rocksdb/util/SizeUnit.java
Normal file
@@ -0,0 +1,16 @@
|
||||
// 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.util;
|
||||
|
||||
public class SizeUnit {
|
||||
public static final long KB = 1024L;
|
||||
public static final long MB = KB * KB;
|
||||
public static final long GB = KB * MB;
|
||||
public static final long TB = KB * GB;
|
||||
public static final long PB = KB * TB;
|
||||
|
||||
private SizeUnit() {}
|
||||
}
|
||||
95
java/rocksjni/backupablejni.cc
Normal file
95
java/rocksjni/backupablejni.cc
Normal file
@@ -0,0 +1,95 @@
|
||||
// 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.
|
||||
//
|
||||
// This file implements the "bridge" between Java and C++ and enables
|
||||
// calling c++ rocksdb::BackupableDB and rocksdb::BackupableDBOptions methods
|
||||
// from Java side.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <jni.h>
|
||||
#include <string>
|
||||
|
||||
#include "include/org_rocksdb_BackupableDB.h"
|
||||
#include "include/org_rocksdb_BackupableDBOptions.h"
|
||||
#include "rocksjni/portal.h"
|
||||
#include "rocksdb/utilities/backupable_db.h"
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_BackupableDB
|
||||
* Method: open
|
||||
* Signature: (JJ)V
|
||||
*/
|
||||
void Java_org_rocksdb_BackupableDB_open(
|
||||
JNIEnv* env, jobject jbdb, jlong jdb_handle, jlong jopt_handle) {
|
||||
auto db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
|
||||
auto opt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jopt_handle);
|
||||
auto bdb = new rocksdb::BackupableDB(db, *opt);
|
||||
|
||||
// as BackupableDB extends RocksDB on the java side, we can reuse
|
||||
// the RocksDB portal here.
|
||||
rocksdb::RocksDBJni::setHandle(env, jbdb, bdb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_BackupableDB
|
||||
* Method: createNewBackup
|
||||
* Signature: (JZ)V
|
||||
*/
|
||||
void Java_org_rocksdb_BackupableDB_createNewBackup(
|
||||
JNIEnv* env, jobject jbdb, jlong jhandle, jboolean jflag) {
|
||||
reinterpret_cast<rocksdb::BackupableDB*>(jhandle)->CreateNewBackup(jflag);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// BackupDBOptions
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_BackupableDBOptions
|
||||
* Method: newBackupableDBOptions
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
*/
|
||||
void Java_org_rocksdb_BackupableDBOptions_newBackupableDBOptions(
|
||||
JNIEnv* env, jobject jobj, jstring jpath, jboolean jshare_table_files,
|
||||
jboolean jsync, jboolean jdestroy_old_data, jboolean jbackup_log_files,
|
||||
jlong jbackup_rate_limit, jlong jrestore_rate_limit) {
|
||||
jbackup_rate_limit = (jbackup_rate_limit <= 0) ? 0 : jbackup_rate_limit;
|
||||
jrestore_rate_limit = (jrestore_rate_limit <= 0) ? 0 : jrestore_rate_limit;
|
||||
|
||||
const char* cpath = env->GetStringUTFChars(jpath, 0);
|
||||
|
||||
auto bopt = new rocksdb::BackupableDBOptions(cpath, nullptr,
|
||||
jshare_table_files, nullptr, jsync, jdestroy_old_data, jbackup_log_files,
|
||||
jbackup_rate_limit, jrestore_rate_limit);
|
||||
|
||||
env->ReleaseStringUTFChars(jpath, cpath);
|
||||
|
||||
rocksdb::BackupableDBOptionsJni::setHandle(env, jobj, bopt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_BackupableDBOptions
|
||||
* Method: backupDir
|
||||
* Signature: (J)Ljava/lang/String;
|
||||
*/
|
||||
jstring Java_org_rocksdb_BackupableDBOptions_backupDir(
|
||||
JNIEnv* env, jobject jopt, jlong jhandle, jstring jpath) {
|
||||
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
|
||||
return env->NewStringUTF(bopt->backup_dir.c_str());
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_BackupableDBOptions
|
||||
* Method: disposeInternal
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_BackupableDBOptions_disposeInternal(
|
||||
JNIEnv* env, jobject jopt, jlong jhandle) {
|
||||
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle);
|
||||
assert(bopt);
|
||||
delete bopt;
|
||||
|
||||
rocksdb::BackupableDBOptionsJni::setHandle(env, jopt, nullptr);
|
||||
}
|
||||
66
java/rocksjni/env.cc
Normal file
66
java/rocksjni/env.cc
Normal file
@@ -0,0 +1,66 @@
|
||||
// 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.
|
||||
//
|
||||
// This file implements the "bridge" between Java and C++ and enables
|
||||
// calling c++ rocksdb::Env methods from Java side.
|
||||
|
||||
#include "include/org_rocksdb_RocksEnv.h"
|
||||
#include "rocksdb/env.h"
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksEnv
|
||||
* Method: getDefaultEnvInternal
|
||||
* Signature: ()J
|
||||
*/
|
||||
jlong Java_org_rocksdb_RocksEnv_getDefaultEnvInternal(
|
||||
JNIEnv* env, jclass jclass) {
|
||||
return reinterpret_cast<jlong>(rocksdb::Env::Default());
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksEnv
|
||||
* Method: setBackgroundThreads
|
||||
* Signature: (JII)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksEnv_setBackgroundThreads(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle,
|
||||
jint num, jint priority) {
|
||||
auto* rocks_env = reinterpret_cast<rocksdb::Env*>(jhandle);
|
||||
switch (priority) {
|
||||
case org_rocksdb_RocksEnv_FLUSH_POOL:
|
||||
rocks_env->SetBackgroundThreads(num, rocksdb::Env::Priority::LOW);
|
||||
break;
|
||||
case org_rocksdb_RocksEnv_COMPACTION_POOL:
|
||||
rocks_env->SetBackgroundThreads(num, rocksdb::Env::Priority::HIGH);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksEnv
|
||||
* Method: getThreadPoolQueueLen
|
||||
* Signature: (JI)I
|
||||
*/
|
||||
jint Java_org_rocksdb_RocksEnv_getThreadPoolQueueLen(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jint pool_id) {
|
||||
auto* rocks_env = reinterpret_cast<rocksdb::Env*>(jhandle);
|
||||
switch (pool_id) {
|
||||
case org_rocksdb_RocksEnv_FLUSH_POOL:
|
||||
return rocks_env->GetThreadPoolQueueLen(rocksdb::Env::Priority::LOW);
|
||||
case org_rocksdb_RocksEnv_COMPACTION_POOL:
|
||||
return rocks_env->GetThreadPoolQueueLen(rocksdb::Env::Priority::HIGH);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksEnv
|
||||
* Method: disposeInternal
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksEnv_disposeInternal(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle) {
|
||||
delete reinterpret_cast<rocksdb::Env*>(jhandle);
|
||||
}
|
||||
38
java/rocksjni/filter.cc
Normal file
38
java/rocksjni/filter.cc
Normal file
@@ -0,0 +1,38 @@
|
||||
// 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.
|
||||
//
|
||||
// This file implements the "bridge" between Java and C++ for
|
||||
// rocksdb::FilterPolicy.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <jni.h>
|
||||
#include <string>
|
||||
|
||||
#include "include/org_rocksdb_Filter.h"
|
||||
#include "include/org_rocksdb_BloomFilter.h"
|
||||
#include "rocksjni/portal.h"
|
||||
#include "rocksdb/filter_policy.h"
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_BloomFilter
|
||||
* Method: createNewFilter0
|
||||
* Signature: (I)V
|
||||
*/
|
||||
void Java_org_rocksdb_BloomFilter_createNewFilter0(
|
||||
JNIEnv* env, jobject jobj, jint bits_per_key) {
|
||||
const rocksdb::FilterPolicy* fp = rocksdb::NewBloomFilterPolicy(bits_per_key);
|
||||
rocksdb::FilterJni::setHandle(env, jobj, fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Filter
|
||||
* Method: disposeInternal
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_Filter_disposeInternal(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
delete reinterpret_cast<rocksdb::FilterPolicy*>(handle);
|
||||
}
|
||||
145
java/rocksjni/iterator.cc
Normal file
145
java/rocksjni/iterator.cc
Normal file
@@ -0,0 +1,145 @@
|
||||
// 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.
|
||||
//
|
||||
// This file implements the "bridge" between Java and C++ and enables
|
||||
// calling c++ rocksdb::Iterator methods from Java side.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <jni.h>
|
||||
|
||||
#include "include/org_rocksdb_RocksIterator.h"
|
||||
#include "rocksjni/portal.h"
|
||||
#include "rocksdb/iterator.h"
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksIterator
|
||||
* Method: isValid0
|
||||
* Signature: (J)Z
|
||||
*/
|
||||
jboolean Java_org_rocksdb_RocksIterator_isValid0(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
return reinterpret_cast<rocksdb::Iterator*>(handle)->Valid();
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksIterator
|
||||
* Method: seekToFirst0
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksIterator_seekToFirst0(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
reinterpret_cast<rocksdb::Iterator*>(handle)->SeekToFirst();
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksIterator
|
||||
* Method: seekToFirst0
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksIterator_seekToLast0(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
reinterpret_cast<rocksdb::Iterator*>(handle)->SeekToLast();
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksIterator
|
||||
* Method: seekToLast0
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksIterator_next0(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
reinterpret_cast<rocksdb::Iterator*>(handle)->Next();
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksIterator
|
||||
* Method: next0
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksIterator_prev0(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
reinterpret_cast<rocksdb::Iterator*>(handle)->Prev();
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksIterator
|
||||
* Method: prev0
|
||||
* Signature: (J)V
|
||||
*/
|
||||
jbyteArray Java_org_rocksdb_RocksIterator_key0(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
auto it = reinterpret_cast<rocksdb::Iterator*>(handle);
|
||||
rocksdb::Slice key_slice = it->key();
|
||||
|
||||
jbyteArray jkey = env->NewByteArray(key_slice.size());
|
||||
env->SetByteArrayRegion(
|
||||
jkey, 0, key_slice.size(),
|
||||
reinterpret_cast<const jbyte*>(key_slice.data()));
|
||||
return jkey;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksIterator
|
||||
* Method: key0
|
||||
* Signature: (J)[B
|
||||
*/
|
||||
jbyteArray Java_org_rocksdb_RocksIterator_value0(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
auto it = reinterpret_cast<rocksdb::Iterator*>(handle);
|
||||
rocksdb::Slice value_slice = it->value();
|
||||
|
||||
jbyteArray jvalue = env->NewByteArray(value_slice.size());
|
||||
env->SetByteArrayRegion(
|
||||
jvalue, 0, value_slice.size(),
|
||||
reinterpret_cast<const jbyte*>(value_slice.data()));
|
||||
return jvalue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksIterator
|
||||
* Method: value0
|
||||
* Signature: (J)[B
|
||||
*/
|
||||
void Java_org_rocksdb_RocksIterator_seek0(
|
||||
JNIEnv* env, jobject jobj, jlong handle,
|
||||
jbyteArray jtarget, jint jtarget_len) {
|
||||
auto it = reinterpret_cast<rocksdb::Iterator*>(handle);
|
||||
jbyte* target = env->GetByteArrayElements(jtarget, 0);
|
||||
rocksdb::Slice target_slice(
|
||||
reinterpret_cast<char*>(target), jtarget_len);
|
||||
|
||||
it->Seek(target_slice);
|
||||
|
||||
env->ReleaseByteArrayElements(jtarget, target, JNI_ABORT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksIterator
|
||||
* Method: seek0
|
||||
* Signature: (J[BI)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksIterator_status0(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
auto it = reinterpret_cast<rocksdb::Iterator*>(handle);
|
||||
rocksdb::Status s = it->status();
|
||||
|
||||
if (s.ok()) {
|
||||
return;
|
||||
}
|
||||
|
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksIterator
|
||||
* Method: disposeInternal
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksIterator_disposeInternal(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
auto it = reinterpret_cast<rocksdb::Iterator*>(handle);
|
||||
delete it;
|
||||
}
|
||||
58
java/rocksjni/memtablejni.cc
Normal file
58
java/rocksjni/memtablejni.cc
Normal file
@@ -0,0 +1,58 @@
|
||||
// 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.
|
||||
//
|
||||
// This file implements the "bridge" between Java and C++ for MemTables.
|
||||
|
||||
#include "include/org_rocksdb_HashSkipListMemTableConfig.h"
|
||||
#include "include/org_rocksdb_HashLinkedListMemTableConfig.h"
|
||||
#include "include/org_rocksdb_VectorMemTableConfig.h"
|
||||
#include "include/org_rocksdb_SkipListMemTableConfig.h"
|
||||
#include "rocksdb/memtablerep.h"
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_HashSkipListMemTableConfig
|
||||
* Method: newMemTableFactoryHandle
|
||||
* Signature: (JII)J
|
||||
*/
|
||||
jlong Java_org_rocksdb_HashSkipListMemTableConfig_newMemTableFactoryHandle(
|
||||
JNIEnv* env, jobject jobj, jlong jbucket_count,
|
||||
jint jheight, jint jbranching_factor) {
|
||||
return reinterpret_cast<jlong>(rocksdb::NewHashSkipListRepFactory(
|
||||
static_cast<size_t>(jbucket_count),
|
||||
static_cast<int32_t>(jheight),
|
||||
static_cast<int32_t>(jbranching_factor)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_HashLinkedListMemTableConfig
|
||||
* Method: newMemTableFactoryHandle
|
||||
* Signature: (J)J
|
||||
*/
|
||||
jlong Java_org_rocksdb_HashLinkedListMemTableConfig_newMemTableFactoryHandle(
|
||||
JNIEnv* env, jobject jobj, jlong jbucket_count) {
|
||||
return reinterpret_cast<jlong>(rocksdb::NewHashLinkListRepFactory(
|
||||
static_cast<size_t>(jbucket_count)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_VectorMemTableConfig
|
||||
* Method: newMemTableFactoryHandle
|
||||
* Signature: (J)J
|
||||
*/
|
||||
jlong Java_org_rocksdb_VectorMemTableConfig_newMemTableFactoryHandle(
|
||||
JNIEnv* env, jobject jobj, jlong jreserved_size) {
|
||||
return reinterpret_cast<jlong>(new rocksdb::VectorRepFactory(
|
||||
static_cast<size_t>(jreserved_size)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_SkipListMemTableConfig
|
||||
* Method: newMemTableFactoryHandle0
|
||||
* Signature: ()J
|
||||
*/
|
||||
jlong Java_org_rocksdb_SkipListMemTableConfig_newMemTableFactoryHandle0(
|
||||
JNIEnv* env, jobject jobj) {
|
||||
return reinterpret_cast<jlong>(new rocksdb::SkipListFactory());
|
||||
}
|
||||
1847
java/rocksjni/options.cc
Normal file
1847
java/rocksjni/options.cc
Normal file
File diff suppressed because it is too large
Load Diff
383
java/rocksjni/portal.h
Normal file
383
java/rocksjni/portal.h
Normal file
@@ -0,0 +1,383 @@
|
||||
// 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.
|
||||
|
||||
// This file is designed for caching those frequently used IDs and provide
|
||||
// efficient portal (i.e, a set of static functions) to access java code
|
||||
// from c++.
|
||||
|
||||
#ifndef JAVA_ROCKSJNI_PORTAL_H_
|
||||
#define JAVA_ROCKSJNI_PORTAL_H_
|
||||
|
||||
#include <jni.h>
|
||||
#include "rocksdb/db.h"
|
||||
#include "rocksdb/filter_policy.h"
|
||||
#include "rocksdb/utilities/backupable_db.h"
|
||||
|
||||
namespace rocksdb {
|
||||
|
||||
// The portal class for org.rocksdb.RocksDB
|
||||
class RocksDBJni {
|
||||
public:
|
||||
// Get the java class id of org.rocksdb.RocksDB.
|
||||
static jclass getJClass(JNIEnv* env) {
|
||||
jclass jclazz = env->FindClass("org/rocksdb/RocksDB");
|
||||
assert(jclazz != nullptr);
|
||||
return jclazz;
|
||||
}
|
||||
|
||||
// Get the field id of the member variable of org.rocksdb.RocksDB
|
||||
// that stores the pointer to rocksdb::DB.
|
||||
static jfieldID getHandleFieldID(JNIEnv* env) {
|
||||
static jfieldID fid = env->GetFieldID(
|
||||
getJClass(env), "nativeHandle_", "J");
|
||||
assert(fid != nullptr);
|
||||
return fid;
|
||||
}
|
||||
|
||||
// Get the pointer to rocksdb::DB of the specified org.rocksdb.RocksDB.
|
||||
static rocksdb::DB* getHandle(JNIEnv* env, jobject jdb) {
|
||||
return reinterpret_cast<rocksdb::DB*>(
|
||||
env->GetLongField(jdb, getHandleFieldID(env)));
|
||||
}
|
||||
|
||||
// Pass the rocksdb::DB pointer to the java side.
|
||||
static void setHandle(JNIEnv* env, jobject jdb, rocksdb::DB* db) {
|
||||
env->SetLongField(
|
||||
jdb, getHandleFieldID(env),
|
||||
reinterpret_cast<jlong>(db));
|
||||
}
|
||||
};
|
||||
|
||||
// The portal class for org.rocksdb.RocksDBException
|
||||
class RocksDBExceptionJni {
|
||||
public:
|
||||
// Get the jclass of org.rocksdb.RocksDBException
|
||||
static jclass getJClass(JNIEnv* env) {
|
||||
jclass jclazz = env->FindClass("org/rocksdb/RocksDBException");
|
||||
assert(jclazz != nullptr);
|
||||
return jclazz;
|
||||
}
|
||||
|
||||
// Create and throw a java exception by converting the input
|
||||
// Status to an RocksDBException.
|
||||
//
|
||||
// In case s.ok() is true, then this function will not throw any
|
||||
// exception.
|
||||
static void ThrowNew(JNIEnv* env, Status s) {
|
||||
if (s.ok()) {
|
||||
return;
|
||||
}
|
||||
jstring msg = env->NewStringUTF(s.ToString().c_str());
|
||||
// get the constructor id of org.rocksdb.RocksDBException
|
||||
static jmethodID mid = env->GetMethodID(
|
||||
getJClass(env), "<init>", "(Ljava/lang/String;)V");
|
||||
assert(mid != nullptr);
|
||||
|
||||
env->Throw((jthrowable)env->NewObject(getJClass(env), mid, msg));
|
||||
}
|
||||
};
|
||||
|
||||
class OptionsJni {
|
||||
public:
|
||||
// Get the java class id of org.rocksdb.Options.
|
||||
static jclass getJClass(JNIEnv* env) {
|
||||
jclass jclazz = env->FindClass("org/rocksdb/Options");
|
||||
assert(jclazz != nullptr);
|
||||
return jclazz;
|
||||
}
|
||||
|
||||
// Get the field id of the member variable of org.rocksdb.Options
|
||||
// that stores the pointer to rocksdb::Options
|
||||
static jfieldID getHandleFieldID(JNIEnv* env) {
|
||||
static jfieldID fid = env->GetFieldID(
|
||||
getJClass(env), "nativeHandle_", "J");
|
||||
assert(fid != nullptr);
|
||||
return fid;
|
||||
}
|
||||
|
||||
// Get the pointer to rocksdb::Options
|
||||
static rocksdb::Options* getHandle(JNIEnv* env, jobject jobj) {
|
||||
return reinterpret_cast<rocksdb::Options*>(
|
||||
env->GetLongField(jobj, getHandleFieldID(env)));
|
||||
}
|
||||
|
||||
// Pass the rocksdb::Options pointer to the java side.
|
||||
static void setHandle(JNIEnv* env, jobject jobj, rocksdb::Options* op) {
|
||||
env->SetLongField(
|
||||
jobj, getHandleFieldID(env),
|
||||
reinterpret_cast<jlong>(op));
|
||||
}
|
||||
};
|
||||
|
||||
class WriteOptionsJni {
|
||||
public:
|
||||
// Get the java class id of org.rocksdb.WriteOptions.
|
||||
static jclass getJClass(JNIEnv* env) {
|
||||
jclass jclazz = env->FindClass("org/rocksdb/WriteOptions");
|
||||
assert(jclazz != nullptr);
|
||||
return jclazz;
|
||||
}
|
||||
|
||||
// Get the field id of the member variable of org.rocksdb.WriteOptions
|
||||
// that stores the pointer to rocksdb::WriteOptions
|
||||
static jfieldID getHandleFieldID(JNIEnv* env) {
|
||||
static jfieldID fid = env->GetFieldID(
|
||||
getJClass(env), "nativeHandle_", "J");
|
||||
assert(fid != nullptr);
|
||||
return fid;
|
||||
}
|
||||
|
||||
// Get the pointer to rocksdb::WriteOptions
|
||||
static rocksdb::WriteOptions* getHandle(JNIEnv* env, jobject jobj) {
|
||||
return reinterpret_cast<rocksdb::WriteOptions*>(
|
||||
env->GetLongField(jobj, getHandleFieldID(env)));
|
||||
}
|
||||
|
||||
// Pass the rocksdb::WriteOptions pointer to the java side.
|
||||
static void setHandle(JNIEnv* env, jobject jobj, rocksdb::WriteOptions* op) {
|
||||
env->SetLongField(
|
||||
jobj, getHandleFieldID(env),
|
||||
reinterpret_cast<jlong>(op));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ReadOptionsJni {
|
||||
public:
|
||||
// Get the java class id of org.rocksdb.ReadOptions.
|
||||
static jclass getJClass(JNIEnv* env) {
|
||||
jclass jclazz = env->FindClass("org/rocksdb/ReadOptions");
|
||||
assert(jclazz != nullptr);
|
||||
return jclazz;
|
||||
}
|
||||
|
||||
// Get the field id of the member variable of org.rocksdb.ReadOptions
|
||||
// that stores the pointer to rocksdb::ReadOptions
|
||||
static jfieldID getHandleFieldID(JNIEnv* env) {
|
||||
static jfieldID fid = env->GetFieldID(
|
||||
getJClass(env), "nativeHandle_", "J");
|
||||
assert(fid != nullptr);
|
||||
return fid;
|
||||
}
|
||||
|
||||
// Get the pointer to rocksdb::ReadOptions
|
||||
static rocksdb::ReadOptions* getHandle(JNIEnv* env, jobject jobj) {
|
||||
return reinterpret_cast<rocksdb::ReadOptions*>(
|
||||
env->GetLongField(jobj, getHandleFieldID(env)));
|
||||
}
|
||||
|
||||
// Pass the rocksdb::ReadOptions pointer to the java side.
|
||||
static void setHandle(JNIEnv* env, jobject jobj,
|
||||
rocksdb::ReadOptions* op) {
|
||||
env->SetLongField(
|
||||
jobj, getHandleFieldID(env),
|
||||
reinterpret_cast<jlong>(op));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class WriteBatchJni {
|
||||
public:
|
||||
static jclass getJClass(JNIEnv* env) {
|
||||
jclass jclazz = env->FindClass("org/rocksdb/WriteBatch");
|
||||
assert(jclazz != nullptr);
|
||||
return jclazz;
|
||||
}
|
||||
|
||||
static jfieldID getHandleFieldID(JNIEnv* env) {
|
||||
static jfieldID fid = env->GetFieldID(
|
||||
getJClass(env), "nativeHandle_", "J");
|
||||
assert(fid != nullptr);
|
||||
return fid;
|
||||
}
|
||||
|
||||
// Get the pointer to rocksdb::WriteBatch of the specified
|
||||
// org.rocksdb.WriteBatch.
|
||||
static rocksdb::WriteBatch* getHandle(JNIEnv* env, jobject jwb) {
|
||||
return reinterpret_cast<rocksdb::WriteBatch*>(
|
||||
env->GetLongField(jwb, getHandleFieldID(env)));
|
||||
}
|
||||
|
||||
// Pass the rocksdb::WriteBatch pointer to the java side.
|
||||
static void setHandle(JNIEnv* env, jobject jwb, rocksdb::WriteBatch* wb) {
|
||||
env->SetLongField(
|
||||
jwb, getHandleFieldID(env),
|
||||
reinterpret_cast<jlong>(wb));
|
||||
}
|
||||
};
|
||||
|
||||
class HistogramDataJni {
|
||||
public:
|
||||
static jmethodID getConstructorMethodId(JNIEnv* env, jclass jclazz) {
|
||||
static jmethodID mid = env->GetMethodID(jclazz, "<init>", "(DDDDD)V");
|
||||
assert(mid != nullptr);
|
||||
return mid;
|
||||
}
|
||||
};
|
||||
|
||||
class BackupableDBOptionsJni {
|
||||
public:
|
||||
// Get the java class id of org.rocksdb.BackupableDBOptions.
|
||||
static jclass getJClass(JNIEnv* env) {
|
||||
jclass jclazz = env->FindClass("org/rocksdb/BackupableDBOptions");
|
||||
assert(jclazz != nullptr);
|
||||
return jclazz;
|
||||
}
|
||||
|
||||
// Get the field id of the member variable of org.rocksdb.BackupableDBOptions
|
||||
// that stores the pointer to rocksdb::BackupableDBOptions
|
||||
static jfieldID getHandleFieldID(JNIEnv* env) {
|
||||
static jfieldID fid = env->GetFieldID(
|
||||
getJClass(env), "nativeHandle_", "J");
|
||||
assert(fid != nullptr);
|
||||
return fid;
|
||||
}
|
||||
|
||||
// Get the pointer to rocksdb::BackupableDBOptions
|
||||
static rocksdb::BackupableDBOptions* getHandle(JNIEnv* env, jobject jobj) {
|
||||
return reinterpret_cast<rocksdb::BackupableDBOptions*>(
|
||||
env->GetLongField(jobj, getHandleFieldID(env)));
|
||||
}
|
||||
|
||||
// Pass the rocksdb::BackupableDBOptions pointer to the java side.
|
||||
static void setHandle(
|
||||
JNIEnv* env, jobject jobj, rocksdb::BackupableDBOptions* op) {
|
||||
env->SetLongField(
|
||||
jobj, getHandleFieldID(env),
|
||||
reinterpret_cast<jlong>(op));
|
||||
}
|
||||
};
|
||||
|
||||
class IteratorJni {
|
||||
public:
|
||||
// Get the java class id of org.rocksdb.Iteartor.
|
||||
static jclass getJClass(JNIEnv* env) {
|
||||
jclass jclazz = env->FindClass("org/rocksdb/RocksIterator");
|
||||
assert(jclazz != nullptr);
|
||||
return jclazz;
|
||||
}
|
||||
|
||||
// Get the field id of the member variable of org.rocksdb.Iterator
|
||||
// that stores the pointer to rocksdb::Iterator.
|
||||
static jfieldID getHandleFieldID(JNIEnv* env) {
|
||||
static jfieldID fid = env->GetFieldID(
|
||||
getJClass(env), "nativeHandle_", "J");
|
||||
assert(fid != nullptr);
|
||||
return fid;
|
||||
}
|
||||
|
||||
// Get the pointer to rocksdb::Iterator.
|
||||
static rocksdb::Iterator* getHandle(JNIEnv* env, jobject jobj) {
|
||||
return reinterpret_cast<rocksdb::Iterator*>(
|
||||
env->GetLongField(jobj, getHandleFieldID(env)));
|
||||
}
|
||||
|
||||
// Pass the rocksdb::Iterator pointer to the java side.
|
||||
static void setHandle(
|
||||
JNIEnv* env, jobject jobj, rocksdb::Iterator* op) {
|
||||
env->SetLongField(
|
||||
jobj, getHandleFieldID(env),
|
||||
reinterpret_cast<jlong>(op));
|
||||
}
|
||||
};
|
||||
|
||||
class FilterJni {
|
||||
public:
|
||||
// Get the java class id of org.rocksdb.FilterPolicy.
|
||||
static jclass getJClass(JNIEnv* env) {
|
||||
jclass jclazz = env->FindClass("org/rocksdb/Filter");
|
||||
assert(jclazz != nullptr);
|
||||
return jclazz;
|
||||
}
|
||||
|
||||
// Get the field id of the member variable of org.rocksdb.Filter
|
||||
// that stores the pointer to rocksdb::FilterPolicy.
|
||||
static jfieldID getHandleFieldID(JNIEnv* env) {
|
||||
static jfieldID fid = env->GetFieldID(
|
||||
getJClass(env), "nativeHandle_", "J");
|
||||
assert(fid != nullptr);
|
||||
return fid;
|
||||
}
|
||||
|
||||
// Get the pointer to rocksdb::FilterPolicy.
|
||||
static rocksdb::FilterPolicy* getHandle(JNIEnv* env, jobject jobj) {
|
||||
return reinterpret_cast<rocksdb::FilterPolicy*>(
|
||||
env->GetLongField(jobj, getHandleFieldID(env)));
|
||||
}
|
||||
|
||||
// Pass the rocksdb::FilterPolicy pointer to the java side.
|
||||
static void setHandle(
|
||||
JNIEnv* env, jobject jobj, const rocksdb::FilterPolicy* op) {
|
||||
env->SetLongField(
|
||||
jobj, getHandleFieldID(env),
|
||||
reinterpret_cast<jlong>(op));
|
||||
}
|
||||
};
|
||||
|
||||
class ListJni {
|
||||
public:
|
||||
// Get the java class id of java.util.List.
|
||||
static jclass getListClass(JNIEnv* env) {
|
||||
jclass jclazz = env->FindClass("java/util/List");
|
||||
assert(jclazz != nullptr);
|
||||
return jclazz;
|
||||
}
|
||||
|
||||
// Get the java class id of java.util.ArrayList.
|
||||
static jclass getArrayListClass(JNIEnv* env) {
|
||||
jclass jclazz = env->FindClass("java/util/ArrayList");
|
||||
assert(jclazz != nullptr);
|
||||
return jclazz;
|
||||
}
|
||||
|
||||
// Get the java class id of java.util.Iterator.
|
||||
static jclass getIteratorClass(JNIEnv* env) {
|
||||
jclass jclazz = env->FindClass("java/util/Iterator");
|
||||
assert(jclazz != nullptr);
|
||||
return jclazz;
|
||||
}
|
||||
|
||||
// Get the java method id of java.util.List.iterator().
|
||||
static jmethodID getIteratorMethod(JNIEnv* env) {
|
||||
static jmethodID mid = env->GetMethodID(
|
||||
getListClass(env), "iterator", "()Ljava/util/Iterator;");
|
||||
assert(mid != nullptr);
|
||||
return mid;
|
||||
}
|
||||
|
||||
// Get the java method id of java.util.Iterator.hasNext().
|
||||
static jmethodID getHasNextMethod(JNIEnv* env) {
|
||||
static jmethodID mid = env->GetMethodID(
|
||||
getIteratorClass(env), "hasNext", "()Z");
|
||||
assert(mid != nullptr);
|
||||
return mid;
|
||||
}
|
||||
|
||||
// Get the java method id of java.util.Iterator.next().
|
||||
static jmethodID getNextMethod(JNIEnv* env) {
|
||||
static jmethodID mid = env->GetMethodID(
|
||||
getIteratorClass(env), "next", "()Ljava/lang/Object;");
|
||||
assert(mid != nullptr);
|
||||
return mid;
|
||||
}
|
||||
|
||||
// Get the java method id of arrayList constructor.
|
||||
static jmethodID getArrayListConstructorMethodId(JNIEnv* env, jclass jclazz) {
|
||||
static jmethodID mid = env->GetMethodID(
|
||||
jclazz, "<init>", "(I)V");
|
||||
assert(mid != nullptr);
|
||||
return mid;
|
||||
}
|
||||
|
||||
// Get the java method id of java.util.List.add().
|
||||
static jmethodID getListAddMethodId(JNIEnv* env) {
|
||||
static jmethodID mid = env->GetMethodID(
|
||||
getListClass(env), "add", "(Ljava/lang/Object;)Z");
|
||||
assert(mid != nullptr);
|
||||
return mid;
|
||||
}
|
||||
};
|
||||
} // namespace rocksdb
|
||||
#endif // JAVA_ROCKSJNI_PORTAL_H_
|
||||
145
java/rocksjni/restorejni.cc
Normal file
145
java/rocksjni/restorejni.cc
Normal file
@@ -0,0 +1,145 @@
|
||||
// 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.
|
||||
//
|
||||
// This file implements the "bridge" between Java and C++ and enables
|
||||
// calling c++ rocksdb::RestoreBackupableDB and rocksdb::RestoreOptions methods
|
||||
// from Java side.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <jni.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "include/org_rocksdb_RestoreOptions.h"
|
||||
#include "include/org_rocksdb_RestoreBackupableDB.h"
|
||||
#include "rocksjni/portal.h"
|
||||
#include "rocksdb/utilities/backupable_db.h"
|
||||
/*
|
||||
* Class: org_rocksdb_RestoreOptions
|
||||
* Method: newRestoreOptions
|
||||
* Signature: (Z)J
|
||||
*/
|
||||
jlong Java_org_rocksdb_RestoreOptions_newRestoreOptions(JNIEnv* env,
|
||||
jobject jobj, jboolean keep_log_files) {
|
||||
auto ropt = new rocksdb::RestoreOptions(keep_log_files);
|
||||
return reinterpret_cast<jlong>(ropt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RestoreOptions
|
||||
* Method: dispose
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_RestoreOptions_dispose(JNIEnv* env, jobject jobj,
|
||||
jlong jhandle) {
|
||||
auto ropt = reinterpret_cast<rocksdb::RestoreOptions*>(jhandle);
|
||||
assert(ropt);
|
||||
delete ropt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RestoreBackupableDB
|
||||
* Method: newRestoreBackupableDB
|
||||
* Signature: (J)J
|
||||
*/
|
||||
jlong Java_org_rocksdb_RestoreBackupableDB_newRestoreBackupableDB(JNIEnv* env,
|
||||
jobject jobj, jlong jopt_handle) {
|
||||
auto opt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jopt_handle);
|
||||
auto rdb = new rocksdb::RestoreBackupableDB(rocksdb::Env::Default(), *opt);
|
||||
return reinterpret_cast<jlong>(rdb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RestoreBackupableDB
|
||||
* Method: restoreDBFromBackup0
|
||||
* Signature: (JJLjava/lang/String;Ljava/lang/String;J)V
|
||||
*/
|
||||
void Java_org_rocksdb_RestoreBackupableDB_restoreDBFromBackup0(JNIEnv* env,
|
||||
jobject jobj, jlong jhandle, jlong jbackup_id, jstring jdb_dir,
|
||||
jstring jwal_dir, jlong jopt_handle) {
|
||||
auto opt = reinterpret_cast<rocksdb::RestoreOptions*>(jopt_handle);
|
||||
|
||||
const char* cdb_dir = env->GetStringUTFChars(jdb_dir, 0);
|
||||
const char* cwal_dir = env->GetStringUTFChars(jwal_dir, 0);
|
||||
|
||||
auto rdb = reinterpret_cast<rocksdb::RestoreBackupableDB*>(jhandle);
|
||||
rocksdb::Status s =
|
||||
rdb->RestoreDBFromBackup(jbackup_id, cdb_dir, cwal_dir, *opt);
|
||||
|
||||
env->ReleaseStringUTFChars(jdb_dir, cdb_dir);
|
||||
env->ReleaseStringUTFChars(jwal_dir, cwal_dir);
|
||||
|
||||
if(!s.ok()) {
|
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RestoreBackupableDB
|
||||
* Method: restoreDBFromLatestBackup0
|
||||
* Signature: (JLjava/lang/String;Ljava/lang/String;J)V
|
||||
*/
|
||||
void Java_org_rocksdb_RestoreBackupableDB_restoreDBFromLatestBackup0(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jstring jdb_dir, jstring jwal_dir,
|
||||
jlong jopt_handle) {
|
||||
auto opt = reinterpret_cast<rocksdb::RestoreOptions*>(jopt_handle);
|
||||
|
||||
const char* cdb_dir = env->GetStringUTFChars(jdb_dir, 0);
|
||||
const char* cwal_dir = env->GetStringUTFChars(jwal_dir, 0);
|
||||
|
||||
auto rdb = reinterpret_cast<rocksdb::RestoreBackupableDB*>(jhandle);
|
||||
rocksdb::Status s =
|
||||
rdb->RestoreDBFromLatestBackup(cdb_dir, cwal_dir, *opt);
|
||||
|
||||
env->ReleaseStringUTFChars(jdb_dir, cdb_dir);
|
||||
env->ReleaseStringUTFChars(jwal_dir, cwal_dir);
|
||||
|
||||
if(!s.ok()) {
|
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RestoreBackupableDB
|
||||
* Method: purgeOldBackups0
|
||||
* Signature: (JI)V
|
||||
*/
|
||||
void Java_org_rocksdb_RestoreBackupableDB_purgeOldBackups0(JNIEnv* env,
|
||||
jobject jobj, jlong jhandle, jint jnum_backups_to_keep) {
|
||||
auto rdb = reinterpret_cast<rocksdb::RestoreBackupableDB*>(jhandle);
|
||||
rocksdb::Status s = rdb->PurgeOldBackups(jnum_backups_to_keep);
|
||||
|
||||
if(!s.ok()) {
|
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RestoreBackupableDB
|
||||
* Method: deleteBackup0
|
||||
* Signature: (JJ)V
|
||||
*/
|
||||
void Java_org_rocksdb_RestoreBackupableDB_deleteBackup0(JNIEnv* env,
|
||||
jobject jobj, jlong jhandle, jlong jbackup_id) {
|
||||
auto rdb = reinterpret_cast<rocksdb::RestoreBackupableDB*>(jhandle);
|
||||
rocksdb::Status s = rdb->DeleteBackup(jbackup_id);
|
||||
|
||||
if(!s.ok()) {
|
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RestoreBackupableDB
|
||||
* Method: dispose
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_RestoreBackupableDB_dispose(JNIEnv* env, jobject jobj,
|
||||
jlong jhandle) {
|
||||
auto ropt = reinterpret_cast<rocksdb::RestoreBackupableDB*>(jhandle);
|
||||
assert(ropt);
|
||||
delete ropt;
|
||||
}
|
||||
440
java/rocksjni/rocksjni.cc
Normal file
440
java/rocksjni/rocksjni.cc
Normal file
@@ -0,0 +1,440 @@
|
||||
// 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.
|
||||
//
|
||||
// This file implements the "bridge" between Java and C++ and enables
|
||||
// calling c++ rocksdb::DB methods from Java side.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <jni.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "include/org_rocksdb_RocksDB.h"
|
||||
#include "rocksjni/portal.h"
|
||||
#include "rocksdb/db.h"
|
||||
#include "rocksdb/cache.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// rocksdb::DB::Open
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: open
|
||||
* Signature: (JLjava/lang/String;)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksDB_open(
|
||||
JNIEnv* env, jobject jdb, jlong jopt_handle,
|
||||
jlong jcache_size, jint jnum_shardbits, jstring jdb_path) {
|
||||
auto opt = reinterpret_cast<rocksdb::Options*>(jopt_handle);
|
||||
if (jcache_size > 0) {
|
||||
opt->no_block_cache = false;
|
||||
if (jnum_shardbits >= 1) {
|
||||
opt->block_cache = rocksdb::NewLRUCache(jcache_size, jnum_shardbits);
|
||||
} else {
|
||||
opt->block_cache = rocksdb::NewLRUCache(jcache_size);
|
||||
}
|
||||
} else {
|
||||
opt->no_block_cache = true;
|
||||
opt->block_cache = nullptr;
|
||||
}
|
||||
|
||||
rocksdb::DB* db = nullptr;
|
||||
const char* db_path = env->GetStringUTFChars(jdb_path, 0);
|
||||
rocksdb::Status s = rocksdb::DB::Open(*opt, db_path, &db);
|
||||
env->ReleaseStringUTFChars(jdb_path, db_path);
|
||||
|
||||
if (s.ok()) {
|
||||
rocksdb::RocksDBJni::setHandle(env, jdb, db);
|
||||
return;
|
||||
}
|
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// rocksdb::DB::Put
|
||||
|
||||
void rocksdb_put_helper(
|
||||
JNIEnv* env, rocksdb::DB* db, const rocksdb::WriteOptions& write_options,
|
||||
jbyteArray jkey, jint jkey_len,
|
||||
jbyteArray jvalue, jint jvalue_len) {
|
||||
|
||||
jbyte* key = env->GetByteArrayElements(jkey, 0);
|
||||
jbyte* value = env->GetByteArrayElements(jvalue, 0);
|
||||
rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
|
||||
rocksdb::Slice value_slice(reinterpret_cast<char*>(value), jvalue_len);
|
||||
|
||||
rocksdb::Status s = db->Put(write_options, key_slice, value_slice);
|
||||
|
||||
// trigger java unref on key and value.
|
||||
// by passing JNI_ABORT, it will simply release the reference without
|
||||
// copying the result back to the java byte array.
|
||||
env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
|
||||
env->ReleaseByteArrayElements(jvalue, value, JNI_ABORT);
|
||||
|
||||
if (s.ok()) {
|
||||
return;
|
||||
}
|
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: put
|
||||
* Signature: (J[BI[BI)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksDB_put__J_3BI_3BI(
|
||||
JNIEnv* env, jobject jdb, jlong jdb_handle,
|
||||
jbyteArray jkey, jint jkey_len,
|
||||
jbyteArray jvalue, jint jvalue_len) {
|
||||
auto db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
|
||||
static const rocksdb::WriteOptions default_write_options =
|
||||
rocksdb::WriteOptions();
|
||||
|
||||
rocksdb_put_helper(env, db, default_write_options,
|
||||
jkey, jkey_len,
|
||||
jvalue, jvalue_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: put
|
||||
* Signature: (JJ[BI[BI)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksDB_put__JJ_3BI_3BI(
|
||||
JNIEnv* env, jobject jdb,
|
||||
jlong jdb_handle, jlong jwrite_options_handle,
|
||||
jbyteArray jkey, jint jkey_len,
|
||||
jbyteArray jvalue, jint jvalue_len) {
|
||||
auto db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
|
||||
auto write_options = reinterpret_cast<rocksdb::WriteOptions*>(
|
||||
jwrite_options_handle);
|
||||
|
||||
rocksdb_put_helper(env, db, *write_options,
|
||||
jkey, jkey_len,
|
||||
jvalue, jvalue_len);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// rocksdb::DB::Write
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: write
|
||||
* Signature: (JJ)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksDB_write(
|
||||
JNIEnv* env, jobject jdb,
|
||||
jlong jwrite_options_handle, jlong jbatch_handle) {
|
||||
rocksdb::DB* db = rocksdb::RocksDBJni::getHandle(env, jdb);
|
||||
auto write_options = reinterpret_cast<rocksdb::WriteOptions*>(
|
||||
jwrite_options_handle);
|
||||
auto batch = reinterpret_cast<rocksdb::WriteBatch*>(jbatch_handle);
|
||||
|
||||
rocksdb::Status s = db->Write(*write_options, batch);
|
||||
|
||||
if (!s.ok()) {
|
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// rocksdb::DB::Get
|
||||
|
||||
jbyteArray rocksdb_get_helper(
|
||||
JNIEnv* env, rocksdb::DB* db, const rocksdb::ReadOptions& read_opt,
|
||||
jbyteArray jkey, jint jkey_len) {
|
||||
jboolean isCopy;
|
||||
jbyte* key = env->GetByteArrayElements(jkey, &isCopy);
|
||||
rocksdb::Slice key_slice(
|
||||
reinterpret_cast<char*>(key), jkey_len);
|
||||
|
||||
std::string value;
|
||||
rocksdb::Status s = db->Get(
|
||||
read_opt, key_slice, &value);
|
||||
|
||||
// trigger java unref on key.
|
||||
// by passing JNI_ABORT, it will simply release the reference without
|
||||
// copying the result back to the java byte array.
|
||||
env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
|
||||
|
||||
if (s.IsNotFound()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (s.ok()) {
|
||||
jbyteArray jvalue = env->NewByteArray(value.size());
|
||||
env->SetByteArrayRegion(
|
||||
jvalue, 0, value.size(),
|
||||
reinterpret_cast<const jbyte*>(value.c_str()));
|
||||
return jvalue;
|
||||
}
|
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: get
|
||||
* Signature: (J[BI)[B
|
||||
*/
|
||||
jbyteArray Java_org_rocksdb_RocksDB_get__J_3BI(
|
||||
JNIEnv* env, jobject jdb, jlong jdb_handle,
|
||||
jbyteArray jkey, jint jkey_len) {
|
||||
return rocksdb_get_helper(env,
|
||||
reinterpret_cast<rocksdb::DB*>(jdb_handle),
|
||||
rocksdb::ReadOptions(),
|
||||
jkey, jkey_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: get
|
||||
* Signature: (JJ[BI)[B
|
||||
*/
|
||||
jbyteArray Java_org_rocksdb_RocksDB_get__JJ_3BI(
|
||||
JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jropt_handle,
|
||||
jbyteArray jkey, jint jkey_len) {
|
||||
return rocksdb_get_helper(env,
|
||||
reinterpret_cast<rocksdb::DB*>(jdb_handle),
|
||||
*reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle),
|
||||
jkey, jkey_len);
|
||||
}
|
||||
|
||||
jint rocksdb_get_helper(
|
||||
JNIEnv* env, rocksdb::DB* db, const rocksdb::ReadOptions& read_options,
|
||||
jbyteArray jkey, jint jkey_len,
|
||||
jbyteArray jvalue, jint jvalue_len) {
|
||||
static const int kNotFound = -1;
|
||||
static const int kStatusError = -2;
|
||||
|
||||
jbyte* key = env->GetByteArrayElements(jkey, 0);
|
||||
rocksdb::Slice key_slice(
|
||||
reinterpret_cast<char*>(key), jkey_len);
|
||||
|
||||
// TODO(yhchiang): we might save one memory allocation here by adding
|
||||
// a DB::Get() function which takes preallocated jbyte* as input.
|
||||
std::string cvalue;
|
||||
rocksdb::Status s = db->Get(
|
||||
read_options, key_slice, &cvalue);
|
||||
|
||||
// trigger java unref on key.
|
||||
// by passing JNI_ABORT, it will simply release the reference without
|
||||
// copying the result back to the java byte array.
|
||||
env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
|
||||
|
||||
if (s.IsNotFound()) {
|
||||
return kNotFound;
|
||||
} else if (!s.ok()) {
|
||||
// Here since we are throwing a Java exception from c++ side.
|
||||
// As a result, c++ does not know calling this function will in fact
|
||||
// throwing an exception. As a result, the execution flow will
|
||||
// not stop here, and codes after this throw will still be
|
||||
// executed.
|
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||
|
||||
// Return a dummy const value to avoid compilation error, although
|
||||
// java side might not have a chance to get the return value :)
|
||||
return kStatusError;
|
||||
}
|
||||
|
||||
int cvalue_len = static_cast<int>(cvalue.size());
|
||||
int length = std::min(jvalue_len, cvalue_len);
|
||||
|
||||
env->SetByteArrayRegion(
|
||||
jvalue, 0, length,
|
||||
reinterpret_cast<const jbyte*>(cvalue.c_str()));
|
||||
return cvalue_len;
|
||||
}
|
||||
|
||||
jobject multi_get_helper(JNIEnv* env, jobject jdb, rocksdb::DB* db,
|
||||
const rocksdb::ReadOptions& rOpt, jobject jkey_list, jint jkeys_count) {
|
||||
std::vector<rocksdb::Slice> keys;
|
||||
std::vector<jbyte*> keys_to_free;
|
||||
|
||||
// get iterator
|
||||
jobject iteratorObj = env->CallObjectMethod(
|
||||
jkey_list, rocksdb::ListJni::getIteratorMethod(env));
|
||||
|
||||
// iterate over keys and convert java byte array to slice
|
||||
while(env->CallBooleanMethod(
|
||||
iteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) {
|
||||
jbyteArray jkey = (jbyteArray) env->CallObjectMethod(
|
||||
iteratorObj, rocksdb::ListJni::getNextMethod(env));
|
||||
jint key_length = env->GetArrayLength(jkey);
|
||||
|
||||
jbyte* key = new jbyte[key_length];
|
||||
env->GetByteArrayRegion(jkey, 0, key_length, key);
|
||||
// store allocated jbyte to free it after multiGet call
|
||||
keys_to_free.push_back(key);
|
||||
|
||||
rocksdb::Slice key_slice(
|
||||
reinterpret_cast<char*>(key), key_length);
|
||||
keys.push_back(key_slice);
|
||||
}
|
||||
|
||||
std::vector<std::string> values;
|
||||
std::vector<rocksdb::Status> s = db->MultiGet(rOpt, keys, &values);
|
||||
|
||||
// Don't reuse class pointer
|
||||
jclass jclazz = env->FindClass("java/util/ArrayList");
|
||||
jmethodID mid = rocksdb::ListJni::getArrayListConstructorMethodId(
|
||||
env, jclazz);
|
||||
jobject jvalue_list = env->NewObject(jclazz, mid, jkeys_count);
|
||||
|
||||
// insert in java list
|
||||
for(std::vector<rocksdb::Status>::size_type i = 0; i != s.size(); i++) {
|
||||
if(s[i].ok()) {
|
||||
jbyteArray jvalue = env->NewByteArray(values[i].size());
|
||||
env->SetByteArrayRegion(
|
||||
jvalue, 0, values[i].size(),
|
||||
reinterpret_cast<const jbyte*>(values[i].c_str()));
|
||||
env->CallBooleanMethod(
|
||||
jvalue_list, rocksdb::ListJni::getListAddMethodId(env), jvalue);
|
||||
}
|
||||
else {
|
||||
env->CallBooleanMethod(
|
||||
jvalue_list, rocksdb::ListJni::getListAddMethodId(env), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// free up allocated byte arrays
|
||||
for(std::vector<jbyte*>::size_type i = 0; i != keys_to_free.size(); i++) {
|
||||
delete[] keys_to_free[i];
|
||||
}
|
||||
keys_to_free.clear();
|
||||
|
||||
return jvalue_list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: multiGet
|
||||
* Signature: (JLjava/util/List;I)Ljava/util/List;
|
||||
*/
|
||||
jobject Java_org_rocksdb_RocksDB_multiGet__JLjava_util_List_2I(
|
||||
JNIEnv* env, jobject jdb, jlong jdb_handle,
|
||||
jobject jkey_list, jint jkeys_count) {
|
||||
return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle),
|
||||
rocksdb::ReadOptions(), jkey_list, jkeys_count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: multiGet
|
||||
* Signature: (JJLjava/util/List;I)Ljava/util/List;
|
||||
*/
|
||||
jobject Java_org_rocksdb_RocksDB_multiGet__JJLjava_util_List_2I(
|
||||
JNIEnv* env, jobject jdb, jlong jdb_handle,
|
||||
jlong jropt_handle, jobject jkey_list, jint jkeys_count) {
|
||||
return multi_get_helper(env, jdb, reinterpret_cast<rocksdb::DB*>(jdb_handle),
|
||||
*reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle), jkey_list,
|
||||
jkeys_count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: get
|
||||
* Signature: (J[BI[BI)I
|
||||
*/
|
||||
jint Java_org_rocksdb_RocksDB_get__J_3BI_3BI(
|
||||
JNIEnv* env, jobject jdb, jlong jdb_handle,
|
||||
jbyteArray jkey, jint jkey_len,
|
||||
jbyteArray jvalue, jint jvalue_len) {
|
||||
return rocksdb_get_helper(env,
|
||||
reinterpret_cast<rocksdb::DB*>(jdb_handle),
|
||||
rocksdb::ReadOptions(),
|
||||
jkey, jkey_len, jvalue, jvalue_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: get
|
||||
* Signature: (JJ[BI[BI)I
|
||||
*/
|
||||
jint Java_org_rocksdb_RocksDB_get__JJ_3BI_3BI(
|
||||
JNIEnv* env, jobject jdb, jlong jdb_handle, jlong jropt_handle,
|
||||
jbyteArray jkey, jint jkey_len,
|
||||
jbyteArray jvalue, jint jvalue_len) {
|
||||
return rocksdb_get_helper(env,
|
||||
reinterpret_cast<rocksdb::DB*>(jdb_handle),
|
||||
*reinterpret_cast<rocksdb::ReadOptions*>(jropt_handle),
|
||||
jkey, jkey_len, jvalue, jvalue_len);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// rocksdb::DB::Delete()
|
||||
void rocksdb_remove_helper(
|
||||
JNIEnv* env, rocksdb::DB* db, const rocksdb::WriteOptions& write_options,
|
||||
jbyteArray jkey, jint jkey_len) {
|
||||
jbyte* key = env->GetByteArrayElements(jkey, 0);
|
||||
rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
|
||||
|
||||
rocksdb::Status s = db->Delete(write_options, key_slice);
|
||||
|
||||
// trigger java unref on key and value.
|
||||
// by passing JNI_ABORT, it will simply release the reference without
|
||||
// copying the result back to the java byte array.
|
||||
env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
|
||||
|
||||
if (!s.ok()) {
|
||||
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: remove
|
||||
* Signature: (J[BI)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksDB_remove__J_3BI(
|
||||
JNIEnv* env, jobject jdb, jlong jdb_handle,
|
||||
jbyteArray jkey, jint jkey_len) {
|
||||
auto db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
|
||||
static const rocksdb::WriteOptions default_write_options =
|
||||
rocksdb::WriteOptions();
|
||||
|
||||
rocksdb_remove_helper(env, db, default_write_options, jkey, jkey_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: remove
|
||||
* Signature: (JJ[BI)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksDB_remove__JJ_3BI(
|
||||
JNIEnv* env, jobject jdb, jlong jdb_handle,
|
||||
jlong jwrite_options, jbyteArray jkey, jint jkey_len) {
|
||||
auto db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
|
||||
auto write_options = reinterpret_cast<rocksdb::WriteOptions*>(jwrite_options);
|
||||
|
||||
rocksdb_remove_helper(env, db, *write_options, jkey, jkey_len);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// rocksdb::DB::~DB()
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: disposeInternal
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksDB_disposeInternal(
|
||||
JNIEnv* env, jobject java_db, jlong jhandle) {
|
||||
delete reinterpret_cast<rocksdb::DB*>(jhandle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: iterator0
|
||||
* Signature: (J)J
|
||||
*/
|
||||
jlong Java_org_rocksdb_RocksDB_iterator0(
|
||||
JNIEnv* env, jobject jdb, jlong db_handle) {
|
||||
auto db = reinterpret_cast<rocksdb::DB*>(db_handle);
|
||||
rocksdb::Iterator* iterator = db->NewIterator(rocksdb::ReadOptions());
|
||||
return reinterpret_cast<jlong>(iterator);
|
||||
}
|
||||
50
java/rocksjni/statistics.cc
Normal file
50
java/rocksjni/statistics.cc
Normal file
@@ -0,0 +1,50 @@
|
||||
// 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.
|
||||
//
|
||||
// This file implements the "bridge" between Java and C++ and enables
|
||||
// calling c++ rocksdb::Statistics methods from Java side.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <jni.h>
|
||||
|
||||
#include "include/org_rocksdb_Statistics.h"
|
||||
#include "rocksjni/portal.h"
|
||||
#include "rocksdb/statistics.h"
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Statistics
|
||||
* Method: getTickerCount0
|
||||
* Signature: (IJ)J
|
||||
*/
|
||||
jlong Java_org_rocksdb_Statistics_getTickerCount0(
|
||||
JNIEnv* env, jobject jobj, int tickerType, jlong handle) {
|
||||
auto st = reinterpret_cast<rocksdb::Statistics*>(handle);
|
||||
assert(st != nullptr);
|
||||
|
||||
return st->getTickerCount(static_cast<rocksdb::Tickers>(tickerType));
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Statistics
|
||||
* Method: geHistogramData0
|
||||
* Signature: (IJ)Lorg/rocksdb/HistogramData;
|
||||
*/
|
||||
jobject Java_org_rocksdb_Statistics_geHistogramData0(
|
||||
JNIEnv* env, jobject jobj, int histogramType, jlong handle) {
|
||||
auto st = reinterpret_cast<rocksdb::Statistics*>(handle);
|
||||
assert(st != nullptr);
|
||||
|
||||
rocksdb::HistogramData data;
|
||||
st->histogramData(static_cast<rocksdb::Histograms>(histogramType),
|
||||
&data);
|
||||
|
||||
// Don't reuse class pointer
|
||||
jclass jclazz = env->FindClass("org/rocksdb/HistogramData");
|
||||
jmethodID mid = rocksdb::HistogramDataJni::getConstructorMethodId(
|
||||
env, jclazz);
|
||||
return env->NewObject(jclazz, mid, data.median, data.percentile95,
|
||||
data.percentile99, data.average, data.standard_deviation);
|
||||
}
|
||||
26
java/rocksjni/table.cc
Normal file
26
java/rocksjni/table.cc
Normal file
@@ -0,0 +1,26 @@
|
||||
// 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.
|
||||
//
|
||||
// This file implements the "bridge" between Java and C++ for rocksdb::Options.
|
||||
|
||||
#include <jni.h>
|
||||
#include "include/org_rocksdb_PlainTableConfig.h"
|
||||
#include "rocksdb/table.h"
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_PlainTableConfig
|
||||
* Method: newTableFactoryHandle
|
||||
* Signature: (IIDI)J
|
||||
*/
|
||||
jlong Java_org_rocksdb_PlainTableConfig_newTableFactoryHandle(
|
||||
JNIEnv* env, jobject jobj, jint jkey_size, jint jbloom_bits_per_key,
|
||||
jdouble jhash_table_ratio, jint jindex_sparseness) {
|
||||
rocksdb::PlainTableOptions options = rocksdb::PlainTableOptions();
|
||||
options.user_key_len = jkey_size;
|
||||
options.bloom_bits_per_key = jbloom_bits_per_key;
|
||||
options.hash_table_ratio = jhash_table_ratio;
|
||||
options.index_sparseness = jindex_sparseness;
|
||||
return reinterpret_cast<jlong>(rocksdb::NewPlainTableFactory(options));
|
||||
}
|
||||
261
java/rocksjni/write_batch.cc
Normal file
261
java/rocksjni/write_batch.cc
Normal file
@@ -0,0 +1,261 @@
|
||||
// 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.
|
||||
//
|
||||
// This file implements the "bridge" between Java and C++ and enables
|
||||
// calling c++ rocksdb::WriteBatch methods from Java side.
|
||||
#include <memory>
|
||||
|
||||
#include "include/org_rocksdb_WriteBatch.h"
|
||||
#include "include/org_rocksdb_WriteBatchInternal.h"
|
||||
#include "include/org_rocksdb_WriteBatchTest.h"
|
||||
#include "rocksjni/portal.h"
|
||||
#include "rocksdb/db.h"
|
||||
#include "db/memtable.h"
|
||||
#include "rocksdb/write_batch.h"
|
||||
#include "db/write_batch_internal.h"
|
||||
#include "rocksdb/env.h"
|
||||
#include "rocksdb/memtablerep.h"
|
||||
#include "util/logging.h"
|
||||
#include "util/testharness.h"
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_WriteBatch
|
||||
* Method: newWriteBatch
|
||||
* Signature: (I)V
|
||||
*/
|
||||
void Java_org_rocksdb_WriteBatch_newWriteBatch(
|
||||
JNIEnv* env, jobject jobj, jint jreserved_bytes) {
|
||||
rocksdb::WriteBatch* wb = new rocksdb::WriteBatch(
|
||||
static_cast<size_t>(jreserved_bytes));
|
||||
|
||||
rocksdb::WriteBatchJni::setHandle(env, jobj, wb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_WriteBatch
|
||||
* Method: count
|
||||
* Signature: ()I
|
||||
*/
|
||||
jint Java_org_rocksdb_WriteBatch_count(JNIEnv* env, jobject jobj) {
|
||||
rocksdb::WriteBatch* wb = rocksdb::WriteBatchJni::getHandle(env, jobj);
|
||||
assert(wb != nullptr);
|
||||
|
||||
return static_cast<jint>(wb->Count());
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_WriteBatch
|
||||
* Method: clear
|
||||
* Signature: ()V
|
||||
*/
|
||||
void Java_org_rocksdb_WriteBatch_clear(JNIEnv* env, jobject jobj) {
|
||||
rocksdb::WriteBatch* wb = rocksdb::WriteBatchJni::getHandle(env, jobj);
|
||||
assert(wb != nullptr);
|
||||
|
||||
wb->Clear();
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_WriteBatch
|
||||
* Method: put
|
||||
* Signature: ([BI[BI)V
|
||||
*/
|
||||
void Java_org_rocksdb_WriteBatch_put(
|
||||
JNIEnv* env, jobject jobj,
|
||||
jbyteArray jkey, jint jkey_len,
|
||||
jbyteArray jvalue, jint jvalue_len) {
|
||||
rocksdb::WriteBatch* wb = rocksdb::WriteBatchJni::getHandle(env, jobj);
|
||||
assert(wb != nullptr);
|
||||
|
||||
jbyte* key = env->GetByteArrayElements(jkey, nullptr);
|
||||
jbyte* value = env->GetByteArrayElements(jvalue, nullptr);
|
||||
rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
|
||||
rocksdb::Slice value_slice(reinterpret_cast<char*>(value), jvalue_len);
|
||||
wb->Put(key_slice, value_slice);
|
||||
env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
|
||||
env->ReleaseByteArrayElements(jvalue, value, JNI_ABORT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_WriteBatch
|
||||
* Method: merge
|
||||
* Signature: ([BI[BI)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_rocksdb_WriteBatch_merge(
|
||||
JNIEnv* env, jobject jobj,
|
||||
jbyteArray jkey, jint jkey_len,
|
||||
jbyteArray jvalue, jint jvalue_len) {
|
||||
rocksdb::WriteBatch* wb = rocksdb::WriteBatchJni::getHandle(env, jobj);
|
||||
assert(wb != nullptr);
|
||||
|
||||
jbyte* key = env->GetByteArrayElements(jkey, nullptr);
|
||||
jbyte* value = env->GetByteArrayElements(jvalue, nullptr);
|
||||
rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
|
||||
rocksdb::Slice value_slice(reinterpret_cast<char*>(value), jvalue_len);
|
||||
wb->Merge(key_slice, value_slice);
|
||||
env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
|
||||
env->ReleaseByteArrayElements(jvalue, value, JNI_ABORT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_WriteBatch
|
||||
* Method: remove
|
||||
* Signature: ([BI)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_rocksdb_WriteBatch_remove(
|
||||
JNIEnv* env, jobject jobj,
|
||||
jbyteArray jkey, jint jkey_len) {
|
||||
rocksdb::WriteBatch* wb = rocksdb::WriteBatchJni::getHandle(env, jobj);
|
||||
assert(wb != nullptr);
|
||||
|
||||
jbyte* key = env->GetByteArrayElements(jkey, nullptr);
|
||||
rocksdb::Slice key_slice(reinterpret_cast<char*>(key), jkey_len);
|
||||
wb->Delete(key_slice);
|
||||
env->ReleaseByteArrayElements(jkey, key, JNI_ABORT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_WriteBatch
|
||||
* Method: putLogData
|
||||
* Signature: ([BI)V
|
||||
*/
|
||||
void Java_org_rocksdb_WriteBatch_putLogData(
|
||||
JNIEnv* env, jobject jobj, jbyteArray jblob, jint jblob_len) {
|
||||
rocksdb::WriteBatch* wb = rocksdb::WriteBatchJni::getHandle(env, jobj);
|
||||
assert(wb != nullptr);
|
||||
|
||||
jbyte* blob = env->GetByteArrayElements(jblob, nullptr);
|
||||
rocksdb::Slice blob_slice(reinterpret_cast<char*>(blob), jblob_len);
|
||||
wb->PutLogData(blob_slice);
|
||||
env->ReleaseByteArrayElements(jblob, blob, JNI_ABORT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_WriteBatch
|
||||
* Method: disposeInternal
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_WriteBatch_disposeInternal(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
delete reinterpret_cast<rocksdb::WriteBatch*>(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_WriteBatchInternal
|
||||
* Method: setSequence
|
||||
* Signature: (Lorg/rocksdb/WriteBatch;J)V
|
||||
*/
|
||||
void Java_org_rocksdb_WriteBatchInternal_setSequence(
|
||||
JNIEnv* env, jclass jclazz, jobject jobj, jlong jsn) {
|
||||
rocksdb::WriteBatch* wb = rocksdb::WriteBatchJni::getHandle(env, jobj);
|
||||
assert(wb != nullptr);
|
||||
|
||||
rocksdb::WriteBatchInternal::SetSequence(
|
||||
wb, static_cast<rocksdb::SequenceNumber>(jsn));
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_WriteBatchInternal
|
||||
* Method: sequence
|
||||
* Signature: (Lorg/rocksdb/WriteBatch;)J
|
||||
*/
|
||||
jlong Java_org_rocksdb_WriteBatchInternal_sequence(
|
||||
JNIEnv* env, jclass jclazz, jobject jobj) {
|
||||
rocksdb::WriteBatch* wb = rocksdb::WriteBatchJni::getHandle(env, jobj);
|
||||
assert(wb != nullptr);
|
||||
|
||||
return static_cast<jlong>(rocksdb::WriteBatchInternal::Sequence(wb));
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_WriteBatchInternal
|
||||
* Method: append
|
||||
* Signature: (Lorg/rocksdb/WriteBatch;Lorg/rocksdb/WriteBatch;)V
|
||||
*/
|
||||
void Java_org_rocksdb_WriteBatchInternal_append(
|
||||
JNIEnv* env, jclass jclazz, jobject jwb1, jobject jwb2) {
|
||||
rocksdb::WriteBatch* wb1 = rocksdb::WriteBatchJni::getHandle(env, jwb1);
|
||||
assert(wb1 != nullptr);
|
||||
rocksdb::WriteBatch* wb2 = rocksdb::WriteBatchJni::getHandle(env, jwb2);
|
||||
assert(wb2 != nullptr);
|
||||
|
||||
rocksdb::WriteBatchInternal::Append(wb1, wb2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_WriteBatchTest
|
||||
* Method: getContents
|
||||
* Signature: (Lorg/rocksdb/WriteBatch;)[B
|
||||
*/
|
||||
jbyteArray Java_org_rocksdb_WriteBatchTest_getContents(
|
||||
JNIEnv* env, jclass jclazz, jobject jobj) {
|
||||
rocksdb::WriteBatch* b = rocksdb::WriteBatchJni::getHandle(env, jobj);
|
||||
assert(b != nullptr);
|
||||
|
||||
// todo: Currently the following code is directly copied from
|
||||
// db/write_bench_test.cc. It could be implemented in java once
|
||||
// all the necessary components can be accessed via jni api.
|
||||
|
||||
rocksdb::InternalKeyComparator cmp(rocksdb::BytewiseComparator());
|
||||
auto factory = std::make_shared<rocksdb::SkipListFactory>();
|
||||
rocksdb::Options options;
|
||||
options.memtable_factory = factory;
|
||||
rocksdb::MemTable* mem = new rocksdb::MemTable(cmp, options);
|
||||
mem->Ref();
|
||||
std::string state;
|
||||
rocksdb::ColumnFamilyMemTablesDefault cf_mems_default(mem, &options);
|
||||
rocksdb::Status s =
|
||||
rocksdb::WriteBatchInternal::InsertInto(b, &cf_mems_default);
|
||||
int count = 0;
|
||||
rocksdb::Iterator* iter = mem->NewIterator(rocksdb::ReadOptions());
|
||||
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
|
||||
rocksdb::ParsedInternalKey ikey;
|
||||
memset(reinterpret_cast<void*>(&ikey), 0, sizeof(ikey));
|
||||
ASSERT_TRUE(rocksdb::ParseInternalKey(iter->key(), &ikey));
|
||||
switch (ikey.type) {
|
||||
case rocksdb::kTypeValue:
|
||||
state.append("Put(");
|
||||
state.append(ikey.user_key.ToString());
|
||||
state.append(", ");
|
||||
state.append(iter->value().ToString());
|
||||
state.append(")");
|
||||
count++;
|
||||
break;
|
||||
case rocksdb::kTypeMerge:
|
||||
state.append("Merge(");
|
||||
state.append(ikey.user_key.ToString());
|
||||
state.append(", ");
|
||||
state.append(iter->value().ToString());
|
||||
state.append(")");
|
||||
count++;
|
||||
break;
|
||||
case rocksdb::kTypeDeletion:
|
||||
state.append("Delete(");
|
||||
state.append(ikey.user_key.ToString());
|
||||
state.append(")");
|
||||
count++;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
state.append("@");
|
||||
state.append(rocksdb::NumberToString(ikey.sequence));
|
||||
}
|
||||
delete iter;
|
||||
if (!s.ok()) {
|
||||
state.append(s.ToString());
|
||||
} else if (count != rocksdb::WriteBatchInternal::Count(b)) {
|
||||
state.append("CountMismatch()");
|
||||
}
|
||||
delete mem->Unref();
|
||||
|
||||
jbyteArray jstate = env->NewByteArray(state.size());
|
||||
env->SetByteArrayRegion(
|
||||
jstate, 0, state.size(),
|
||||
reinterpret_cast<const jbyte*>(state.c_str()));
|
||||
|
||||
return jstate;
|
||||
}
|
||||
Reference in New Issue
Block a user