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