mirror of https://github.com/facebook/rocksdb.git
Add a java api for rocksdb::Options, currently only supports create_if_missing.
Summary: * [java] Add a java api for rocksdb::Options, currently only supports create_if_missing. * [java] Add a test for RocksDBException in RocksDBSample. Test Plan: make jtest Reviewers: haobo, sdong Reviewed By: haobo CC: leveldb, dhruba Differential Revision: https://reviews.facebook.net/D17385
This commit is contained in:
parent
e0a87c4cf1
commit
8c4a3bfa5b
2
Makefile
2
Makefile
|
@ -402,7 +402,7 @@ ldb: tools/ldb.o $(LIBOBJECTS)
|
|||
# ---------------------------------------------------------------------------
|
||||
# Jni stuff
|
||||
# ---------------------------------------------------------------------------
|
||||
JNI_NATIVE_SOURCES = ./java/rocksjni/rocksjni.cc
|
||||
JNI_NATIVE_SOURCES = ./java/rocksjni/rocksjni.cc ./java/rocksjni/options.cc
|
||||
|
||||
JAVA_INCLUDE = -I/usr/lib/jvm/java-openjdk/include/ -I/usr/lib/jvm/java-openjdk/include/linux
|
||||
ROCKSDBJNILIB = ./java/librocksdbjni.so
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
NATIVE_JAVA_CLASSES = org.rocksdb.RocksDB
|
||||
NATIVE_JAVA_CLASSES = org.rocksdb.RocksDB org.rocksdb.Options
|
||||
NATIVE_INCLUDE = ./include
|
||||
ROCKSDB_JAR = rocksdbjni.jar
|
||||
|
||||
|
@ -14,4 +14,8 @@ java:
|
|||
|
||||
sample:
|
||||
javac -cp $(ROCKSDB_JAR) RocksDBSample.java
|
||||
java -ea -Djava.library.path=.:../ -cp ".:./*" RocksDBSample /tmp/rocksdbjni/
|
||||
@rm -rf /tmp/rocksdbjni
|
||||
@rm -rf /tmp/rocksdbjni_not_found
|
||||
java -ea -Djava.library.path=.:../ -cp ".:./*" RocksDBSample /tmp/rocksdbjni
|
||||
@rm -rf /tmp/rocksdbjni
|
||||
@rm -rf /tmp/rocksdbjni_not_found
|
||||
|
|
|
@ -19,9 +19,34 @@ public class RocksDBSample {
|
|||
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);
|
||||
}
|
||||
|
||||
options.setCreateIfMissing(true);
|
||||
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
|
||||
options.dispose();
|
||||
db.close();
|
||||
|
||||
try {
|
||||
db = RocksDB.open(db_path);
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
// 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 to control the behavior of a database. It will be used
|
||||
* during the creation of a RocksDB (i.e., RocksDB::Open()).
|
||||
*
|
||||
* Note that dispose() must be called before an Options instance
|
||||
* become out-of-scope to release the allocated memory in c++.
|
||||
*/
|
||||
public class Options {
|
||||
/**
|
||||
* Construct options for opening a RocksDB.
|
||||
*
|
||||
* This constructor will create (by allocating a block of memory)
|
||||
* an rocksdb::Options in the c++ side.
|
||||
*/
|
||||
public Options() {
|
||||
nativeHandle_ = 0;
|
||||
newOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* If this value is set to true, then the database will be created
|
||||
* if it is missing during RocksDB::Open().
|
||||
* Default: false
|
||||
*
|
||||
* @param flag a flag indicating whether to create a database the
|
||||
* specified database in RocksDB::Open() operation is missing.
|
||||
* @see RocksDB::Open()
|
||||
*/
|
||||
public void setCreateIfMissing(boolean flag) {
|
||||
assert(nativeHandle_ != 0);
|
||||
setCreateIfMissing(nativeHandle_, flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the create_if_missing flag is set to true.
|
||||
* If true, the database will be created if it is missing.
|
||||
*
|
||||
* @return return true if the create_if_missing flag is set to true.
|
||||
* @see setCreateIfMissing()
|
||||
*/
|
||||
public boolean craeteIfMissing() {
|
||||
assert(nativeHandle_ != 0);
|
||||
return createIfMissing(nativeHandle_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the memory allocated for the current instance
|
||||
* in the c++ side.
|
||||
*/
|
||||
public synchronized void dispose() {
|
||||
if (nativeHandle_ != 0) {
|
||||
dispose0();
|
||||
}
|
||||
}
|
||||
|
||||
private native void newOptions();
|
||||
private native void dispose0();
|
||||
private native void setCreateIfMissing(long handle, boolean flag);
|
||||
private native boolean createIfMissing(long handle);
|
||||
|
||||
long nativeHandle_;
|
||||
}
|
|
@ -20,12 +20,16 @@ public class RocksDB {
|
|||
public static final int NOT_FOUND = -1;
|
||||
/**
|
||||
* The factory constructor of RocksDB that opens a RocksDB instance given
|
||||
* the path to the database.
|
||||
* 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();
|
||||
|
@ -33,6 +37,17 @@ public class RocksDB {
|
|||
return db;
|
||||
}
|
||||
|
||||
/**
|
||||
* The factory constructor of RocksDB that opens a RocksDB instance given
|
||||
* the path to the database using the specified options and db path.
|
||||
*/
|
||||
public static RocksDB open(Options options, String path)
|
||||
throws RocksDBException {
|
||||
RocksDB db = new RocksDB();
|
||||
db.open(options.nativeHandle_, path);
|
||||
return db;
|
||||
}
|
||||
|
||||
public synchronized void close() {
|
||||
if (nativeHandle_ != 0) {
|
||||
close0();
|
||||
|
@ -93,6 +108,7 @@ public class RocksDB {
|
|||
|
||||
// native methods
|
||||
private native void open0(String path) throws RocksDBException;
|
||||
private native void open(long optionsHandle, String path) throws RocksDBException;
|
||||
private native void put(
|
||||
byte[] key, int keyLen,
|
||||
byte[] value, int valueLen) throws RocksDBException;
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
// 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <jni.h>
|
||||
#include <string>
|
||||
|
||||
#include "include/org_rocksdb_Options.h"
|
||||
#include "rocksjni/portal.h"
|
||||
#include "rocksdb/db.h"
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Options
|
||||
* Method: newOptions
|
||||
* Signature: ()V
|
||||
*/
|
||||
void Java_org_rocksdb_Options_newOptions(JNIEnv* env, jobject jobj) {
|
||||
rocksdb::Options* op = new rocksdb::Options();
|
||||
rocksdb::OptionsJni::setHandle(env, jobj, op);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Options
|
||||
* Method: dispose0
|
||||
* Signature: ()V
|
||||
*/
|
||||
void Java_org_rocksdb_Options_dispose0(JNIEnv* env, jobject jobj) {
|
||||
rocksdb::Options* op = rocksdb::OptionsJni::getHandle(env, jobj);
|
||||
delete op;
|
||||
|
||||
rocksdb::OptionsJni::setHandle(env, jobj, op);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Options
|
||||
* Method: setCreateIfMissing
|
||||
* Signature: (JZ)V
|
||||
*/
|
||||
void Java_org_rocksdb_Options_setCreateIfMissing(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle, jboolean flag) {
|
||||
reinterpret_cast<rocksdb::Options*>(jhandle)->create_if_missing = flag;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Options
|
||||
* Method: createIfMissing
|
||||
* Signature: (J)Z
|
||||
*/
|
||||
jboolean Java_org_rocksdb_Options_createIfMissing(
|
||||
JNIEnv* env, jobject jobj, jlong jhandle) {
|
||||
return reinterpret_cast<rocksdb::Options*>(jhandle)->create_if_missing;
|
||||
}
|
|
@ -77,5 +77,37 @@ class RocksDBExceptionJni {
|
|||
}
|
||||
};
|
||||
|
||||
class OptionsJni {
|
||||
public:
|
||||
// Get the java class id of org.rocksdb.Options.
|
||||
static jclass getJClass(JNIEnv* env) {
|
||||
static 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));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace rocksdb
|
||||
#endif // JAVA_ROCKSJNI_PORTAL_H_
|
||||
|
|
|
@ -15,20 +15,12 @@
|
|||
#include "rocksjni/portal.h"
|
||||
#include "rocksdb/db.h"
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: open0
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksDB_open0(
|
||||
JNIEnv* env, jobject java_db, jstring jdb_path) {
|
||||
void rocksdb_open_helper(
|
||||
JNIEnv* env, jobject java_db, jstring jdb_path, const rocksdb::Options& opt) {
|
||||
rocksdb::DB* db;
|
||||
rocksdb::Options options;
|
||||
options.create_if_missing = true;
|
||||
|
||||
jboolean isCopy = false;
|
||||
const char* db_path = env->GetStringUTFChars(jdb_path, &isCopy);
|
||||
rocksdb::Status s = rocksdb::DB::Open(options, db_path, &db);
|
||||
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()) {
|
||||
|
@ -38,6 +30,30 @@ void Java_org_rocksdb_RocksDB_open0(
|
|||
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: open0
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksDB_open0(
|
||||
JNIEnv* env, jobject jdb, jstring jdb_path) {
|
||||
rocksdb::Options options;
|
||||
options.create_if_missing = true;
|
||||
|
||||
rocksdb_open_helper(env, jdb, jdb_path, options);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: open
|
||||
* Signature: (JLjava/lang/String;)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksDB_open(
|
||||
JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path) {
|
||||
auto options = reinterpret_cast<rocksdb::Options*>(jopt_handle);
|
||||
rocksdb_open_helper(env, jdb, jdb_path, *options);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: put
|
||||
|
|
Loading…
Reference in New Issue