Skip to content

Commit 8c4a3bf

Browse files
committed
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
1 parent e0a87c4 commit 8c4a3bf

File tree

8 files changed

+234
-15
lines changed

8 files changed

+234
-15
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ ldb: tools/ldb.o $(LIBOBJECTS)
402402
# ---------------------------------------------------------------------------
403403
# Jni stuff
404404
# ---------------------------------------------------------------------------
405-
JNI_NATIVE_SOURCES = ./java/rocksjni/rocksjni.cc
405+
JNI_NATIVE_SOURCES = ./java/rocksjni/rocksjni.cc ./java/rocksjni/options.cc
406406

407407
JAVA_INCLUDE = -I/usr/lib/jvm/java-openjdk/include/ -I/usr/lib/jvm/java-openjdk/include/linux
408408
ROCKSDBJNILIB = ./java/librocksdbjni.so

java/Makefile

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
NATIVE_JAVA_CLASSES = org.rocksdb.RocksDB
1+
NATIVE_JAVA_CLASSES = org.rocksdb.RocksDB org.rocksdb.Options
22
NATIVE_INCLUDE = ./include
33
ROCKSDB_JAR = rocksdbjni.jar
44

@@ -14,4 +14,8 @@ java:
1414

1515
sample:
1616
javac -cp $(ROCKSDB_JAR) RocksDBSample.java
17-
java -ea -Djava.library.path=.:../ -cp ".:./*" RocksDBSample /tmp/rocksdbjni/
17+
@rm -rf /tmp/rocksdbjni
18+
@rm -rf /tmp/rocksdbjni_not_found
19+
java -ea -Djava.library.path=.:../ -cp ".:./*" RocksDBSample /tmp/rocksdbjni
20+
@rm -rf /tmp/rocksdbjni
21+
@rm -rf /tmp/rocksdbjni_not_found

java/RocksDBSample.java

+25
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,34 @@ public static void main(String[] args) {
1919
return;
2020
}
2121
String db_path = args[0];
22+
String db_path_not_found = db_path + "_not_found";
2223

2324
System.out.println("RocksDBSample");
2425
RocksDB db = null;
26+
Options options = new Options();
27+
try {
28+
db = RocksDB.open(options, db_path_not_found);
29+
assert(false);
30+
} catch (RocksDBException e) {
31+
System.out.format("caught the expceted exception -- %s\n", e);
32+
assert(db == null);
33+
}
34+
35+
options.setCreateIfMissing(true);
36+
try {
37+
db = RocksDB.open(options, db_path_not_found);
38+
db.put("hello".getBytes(), "world".getBytes());
39+
byte[] value = db.get("hello".getBytes());
40+
assert("world".equals(new String(value)));
41+
} catch (RocksDBException e) {
42+
System.out.format("[ERROR] caught the unexpceted exception -- %s\n", e);
43+
assert(db == null);
44+
assert(false);
45+
}
46+
47+
// be sure to release the c++ pointer
48+
options.dispose();
49+
db.close();
2550

2651
try {
2752
db = RocksDB.open(db_path);

java/org/rocksdb/Options.java

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
2+
// This source code is licensed under the BSD-style license found in the
3+
// LICENSE file in the root directory of this source tree. An additional grant
4+
// of patent rights can be found in the PATENTS file in the same directory.
5+
6+
package org.rocksdb;
7+
8+
/**
9+
* Options to control the behavior of a database. It will be used
10+
* during the creation of a RocksDB (i.e., RocksDB::Open()).
11+
*
12+
* Note that dispose() must be called before an Options instance
13+
* become out-of-scope to release the allocated memory in c++.
14+
*/
15+
public class Options {
16+
/**
17+
* Construct options for opening a RocksDB.
18+
*
19+
* This constructor will create (by allocating a block of memory)
20+
* an rocksdb::Options in the c++ side.
21+
*/
22+
public Options() {
23+
nativeHandle_ = 0;
24+
newOptions();
25+
}
26+
27+
/**
28+
* If this value is set to true, then the database will be created
29+
* if it is missing during RocksDB::Open().
30+
* Default: false
31+
*
32+
* @param flag a flag indicating whether to create a database the
33+
* specified database in RocksDB::Open() operation is missing.
34+
* @see RocksDB::Open()
35+
*/
36+
public void setCreateIfMissing(boolean flag) {
37+
assert(nativeHandle_ != 0);
38+
setCreateIfMissing(nativeHandle_, flag);
39+
}
40+
41+
/**
42+
* Return true if the create_if_missing flag is set to true.
43+
* If true, the database will be created if it is missing.
44+
*
45+
* @return return true if the create_if_missing flag is set to true.
46+
* @see setCreateIfMissing()
47+
*/
48+
public boolean craeteIfMissing() {
49+
assert(nativeHandle_ != 0);
50+
return createIfMissing(nativeHandle_);
51+
}
52+
53+
/**
54+
* Release the memory allocated for the current instance
55+
* in the c++ side.
56+
*/
57+
public synchronized void dispose() {
58+
if (nativeHandle_ != 0) {
59+
dispose0();
60+
}
61+
}
62+
63+
private native void newOptions();
64+
private native void dispose0();
65+
private native void setCreateIfMissing(long handle, boolean flag);
66+
private native boolean createIfMissing(long handle);
67+
68+
long nativeHandle_;
69+
}

java/org/rocksdb/RocksDB.java

+17-1
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,34 @@ public class RocksDB {
2020
public static final int NOT_FOUND = -1;
2121
/**
2222
* The factory constructor of RocksDB that opens a RocksDB instance given
23-
* the path to the database.
23+
* the path to the database using the default options w/ createIfMissing
24+
* set to true.
2425
*
2526
* @param path the path to the rocksdb.
2627
* @param status an out value indicating the status of the Open().
2728
* @return a rocksdb instance on success, null if the specified rocksdb can
2829
* not be opened.
30+
*
31+
* @see Options.setCreateIfMissing()
32+
* @see Options.createIfMissing()
2933
*/
3034
public static RocksDB open(String path) throws RocksDBException {
3135
RocksDB db = new RocksDB();
3236
db.open0(path);
3337
return db;
3438
}
3539

40+
/**
41+
* The factory constructor of RocksDB that opens a RocksDB instance given
42+
* the path to the database using the specified options and db path.
43+
*/
44+
public static RocksDB open(Options options, String path)
45+
throws RocksDBException {
46+
RocksDB db = new RocksDB();
47+
db.open(options.nativeHandle_, path);
48+
return db;
49+
}
50+
3651
public synchronized void close() {
3752
if (nativeHandle_ != 0) {
3853
close0();
@@ -93,6 +108,7 @@ private RocksDB() {
93108

94109
// native methods
95110
private native void open0(String path) throws RocksDBException;
111+
private native void open(long optionsHandle, String path) throws RocksDBException;
96112
private native void put(
97113
byte[] key, int keyLen,
98114
byte[] value, int valueLen) throws RocksDBException;

java/rocksjni/options.cc

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
2+
// This source code is licensed under the BSD-style license found in the
3+
// LICENSE file in the root directory of this source tree. An additional grant
4+
// of patent rights can be found in the PATENTS file in the same directory.
5+
//
6+
// This file implements the "bridge" between Java and C++ for rocksdb::Options.
7+
8+
#include <stdio.h>
9+
#include <stdlib.h>
10+
#include <jni.h>
11+
#include <string>
12+
13+
#include "include/org_rocksdb_Options.h"
14+
#include "rocksjni/portal.h"
15+
#include "rocksdb/db.h"
16+
17+
/*
18+
* Class: org_rocksdb_Options
19+
* Method: newOptions
20+
* Signature: ()V
21+
*/
22+
void Java_org_rocksdb_Options_newOptions(JNIEnv* env, jobject jobj) {
23+
rocksdb::Options* op = new rocksdb::Options();
24+
rocksdb::OptionsJni::setHandle(env, jobj, op);
25+
}
26+
27+
/*
28+
* Class: org_rocksdb_Options
29+
* Method: dispose0
30+
* Signature: ()V
31+
*/
32+
void Java_org_rocksdb_Options_dispose0(JNIEnv* env, jobject jobj) {
33+
rocksdb::Options* op = rocksdb::OptionsJni::getHandle(env, jobj);
34+
delete op;
35+
36+
rocksdb::OptionsJni::setHandle(env, jobj, op);
37+
}
38+
39+
/*
40+
* Class: org_rocksdb_Options
41+
* Method: setCreateIfMissing
42+
* Signature: (JZ)V
43+
*/
44+
void Java_org_rocksdb_Options_setCreateIfMissing(
45+
JNIEnv* env, jobject jobj, jlong jhandle, jboolean flag) {
46+
reinterpret_cast<rocksdb::Options*>(jhandle)->create_if_missing = flag;
47+
}
48+
49+
/*
50+
* Class: org_rocksdb_Options
51+
* Method: createIfMissing
52+
* Signature: (J)Z
53+
*/
54+
jboolean Java_org_rocksdb_Options_createIfMissing(
55+
JNIEnv* env, jobject jobj, jlong jhandle) {
56+
return reinterpret_cast<rocksdb::Options*>(jhandle)->create_if_missing;
57+
}

java/rocksjni/portal.h

+32
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,37 @@ class RocksDBExceptionJni {
7777
}
7878
};
7979

80+
class OptionsJni {
81+
public:
82+
// Get the java class id of org.rocksdb.Options.
83+
static jclass getJClass(JNIEnv* env) {
84+
static jclass jclazz = env->FindClass("org/rocksdb/Options");
85+
assert(jclazz != nullptr);
86+
return jclazz;
87+
}
88+
89+
// Get the field id of the member variable of org.rocksdb.Options
90+
// that stores the pointer to rocksdb::Options
91+
static jfieldID getHandleFieldID(JNIEnv* env) {
92+
static jfieldID fid = env->GetFieldID(
93+
getJClass(env), "nativeHandle_", "J");
94+
assert(fid != nullptr);
95+
return fid;
96+
}
97+
98+
// Get the pointer to rocksdb::Options
99+
static rocksdb::Options* getHandle(JNIEnv* env, jobject jobj) {
100+
return reinterpret_cast<rocksdb::Options*>(
101+
env->GetLongField(jobj, getHandleFieldID(env)));
102+
}
103+
104+
// Pass the rocksdb::Options pointer to the java side.
105+
static void setHandle(JNIEnv* env, jobject jobj, rocksdb::Options* op) {
106+
env->SetLongField(
107+
jobj, getHandleFieldID(env),
108+
reinterpret_cast<jlong>(op));
109+
}
110+
};
111+
80112
} // namespace rocksdb
81113
#endif // JAVA_ROCKSJNI_PORTAL_H_

java/rocksjni/rocksjni.cc

+27-11
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,43 @@
1515
#include "rocksjni/portal.h"
1616
#include "rocksdb/db.h"
1717

18+
void rocksdb_open_helper(
19+
JNIEnv* env, jobject java_db, jstring jdb_path, const rocksdb::Options& opt) {
20+
rocksdb::DB* db;
21+
22+
const char* db_path = env->GetStringUTFChars(jdb_path, 0);
23+
rocksdb::Status s = rocksdb::DB::Open(opt, db_path, &db);
24+
env->ReleaseStringUTFChars(jdb_path, db_path);
25+
26+
if (s.ok()) {
27+
rocksdb::RocksDBJni::setHandle(env, java_db, db);
28+
return;
29+
}
30+
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
31+
}
32+
1833
/*
1934
* Class: org_rocksdb_RocksDB
2035
* Method: open0
2136
* Signature: (Ljava/lang/String;)V
2237
*/
2338
void Java_org_rocksdb_RocksDB_open0(
24-
JNIEnv* env, jobject java_db, jstring jdb_path) {
25-
rocksdb::DB* db;
39+
JNIEnv* env, jobject jdb, jstring jdb_path) {
2640
rocksdb::Options options;
2741
options.create_if_missing = true;
2842

29-
jboolean isCopy = false;
30-
const char* db_path = env->GetStringUTFChars(jdb_path, &isCopy);
31-
rocksdb::Status s = rocksdb::DB::Open(options, db_path, &db);
32-
env->ReleaseStringUTFChars(jdb_path, db_path);
43+
rocksdb_open_helper(env, jdb, jdb_path, options);
44+
}
3345

34-
if (s.ok()) {
35-
rocksdb::RocksDBJni::setHandle(env, java_db, db);
36-
return;
37-
}
38-
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
46+
/*
47+
* Class: org_rocksdb_RocksDB
48+
* Method: open
49+
* Signature: (JLjava/lang/String;)V
50+
*/
51+
void Java_org_rocksdb_RocksDB_open(
52+
JNIEnv* env, jobject jdb, jlong jopt_handle, jstring jdb_path) {
53+
auto options = reinterpret_cast<rocksdb::Options*>(jopt_handle);
54+
rocksdb_open_helper(env, jdb, jdb_path, *options);
3955
}
4056

4157
/*

0 commit comments

Comments
 (0)