Summary: Add a skeleton binding and test for BackupableDB which shows that BackupableDB and RocksDB can share the same JNI calls. Test Plan: make rocksdbjava make jtest Reviewers: haobo, ankgup87, sdong, dhruba Reviewed By: haobo CC: leveldb Differential Revision: https://reviews.facebook.net/D17793main
parent
651792251a
commit
bb6fd15a6e
@ -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; |
||||
|
||||
/** |
||||
* 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 { |
||||
// since BackupableDB c++ will handle the life cycle of
|
||||
// the returned RocksDB of RocksDB.open(), here we store
|
||||
// it as a BackupableDB member variable to avoid GC.
|
||||
BackupableDB bdb = new BackupableDB(RocksDB.open(opt, db_path)); |
||||
bdb.open(bdb.db_.nativeHandle_, bopt.nativeHandle_); |
||||
|
||||
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 (isOpened()) { |
||||
super.close0(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* A protected construction that will be used in the static factory |
||||
* method BackupableDB.open(). |
||||
*/ |
||||
protected BackupableDB(RocksDB db) { |
||||
super(); |
||||
db_ = db; |
||||
} |
||||
|
||||
@Override protected void finalize() { |
||||
close(); |
||||
} |
||||
|
||||
private boolean isOpened() { |
||||
return nativeHandle_ != 0; |
||||
} |
||||
|
||||
protected native void open(long rocksDBHandle, long backupDBOptionsHandle); |
||||
protected native void createNewBackup(long handle, boolean flag); |
||||
|
||||
private final RocksDB db_; |
||||
} |
@ -0,0 +1,52 @@ |
||||
// 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++. |
||||
*/ |
||||
public class BackupableDBOptions { |
||||
public BackupableDBOptions(String path) { |
||||
newBackupableDBOptions(path); |
||||
} |
||||
|
||||
/** |
||||
* 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. |
||||
*/ |
||||
public synchronized void dispose() { |
||||
if (isInitialized()) { |
||||
dispose(nativeHandle_); |
||||
} |
||||
} |
||||
|
||||
@Override protected void finalize() { |
||||
dispose(); |
||||
} |
||||
|
||||
boolean isInitialized() { |
||||
return nativeHandle_ != 0; |
||||
} |
||||
|
||||
private native void newBackupableDBOptions(String path); |
||||
private native String backupDir(long handle); |
||||
private native void dispose(long handle); |
||||
long nativeHandle_; |
||||
} |
@ -0,0 +1,41 @@ |
||||
// 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 { |
||||
System.loadLibrary("rocksdbjni"); |
||||
} |
||||
public static void main(String[] args) { |
||||
|
||||
Options opt = new Options(); |
||||
opt.setCreateIfMissing(true); |
||||
|
||||
BackupableDBOptions bopt = new BackupableDBOptions(backup_path); |
||||
BackupableDB bdb = null; |
||||
|
||||
try { |
||||
bdb = BackupableDB.open(opt, bopt, db_path); |
||||
bdb.put("hello".getBytes(), "BackupableDB".getBytes()); |
||||
bdb.createNewBackup(true); |
||||
byte[] value = bdb.get("hello".getBytes()); |
||||
assert(new String(value).equals("BackupableDB")); |
||||
} catch (RocksDBException e) { |
||||
System.err.format("[ERROR]: %s%n", e); |
||||
e.printStackTrace(); |
||||
} finally { |
||||
opt.dispose(); |
||||
bopt.dispose(); |
||||
if (bdb != null) { |
||||
bdb.close(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,85 @@ |
||||
// 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 "include/org_rocksdb_BackupableDB.h" |
||||
#include "include/org_rocksdb_BackupableDBOptions.h" |
||||
#include "rocksjni/portal.h" |
||||
#include "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) { |
||||
const char* cpath = env->GetStringUTFChars(jpath, 0); |
||||
auto bopt = new rocksdb::BackupableDBOptions(cpath); |
||||
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: dispose |
||||
* Signature: (J)V |
||||
*/ |
||||
void Java_org_rocksdb_BackupableDBOptions_dispose( |
||||
JNIEnv* env, jobject jopt, jlong jhandle) { |
||||
auto bopt = reinterpret_cast<rocksdb::BackupableDBOptions*>(jhandle); |
||||
assert(bopt); |
||||
delete bopt; |
||||
|
||||
rocksdb::BackupableDBOptionsJni::setHandle(env, jopt, nullptr); |
||||
} |
Loading…
Reference in new issue