[Java] Add RocksObject, the base class of all java objects with a c++ pointer.
Summary: Add RocksObject, the base class of all java objects which has a c++ pointer. While the finalizer of a RocksObject will release its c++ resource, it is suggested to call its RocksObject.dispose() to manually release its c++ resource. Existing RocksDB java classes are now extending RocksObject. Test Plan: make rocksdbjava make jtest make jdb_bench Reviewers: haobo, dhruba, sdong, ankgup87, rsumbaly, swapnilghike, zzbennett Reviewed By: haobo CC: leveldb Differential Revision: https://reviews.facebook.net/D18411
This commit is contained in:
parent
096f5be0ed
commit
61955a0dda
@ -218,7 +218,7 @@ public class RocksDBSample {
|
||||
|
||||
System.out.println("iterator seek test passed.");
|
||||
|
||||
iterator.close();
|
||||
iterator.dispose();
|
||||
System.out.println("iterator tests passed.");
|
||||
|
||||
iterator = db.newIterator();
|
||||
@ -226,7 +226,7 @@ public class RocksDBSample {
|
||||
for (iterator.seekToLast(); iterator.isValid(); iterator.prev()) {
|
||||
keys.add(iterator.key());
|
||||
}
|
||||
iterator.close();
|
||||
iterator.dispose();
|
||||
|
||||
Map<byte[], byte[]> values = db.multiGet(keys);
|
||||
assert(values.size() == keys.size());
|
||||
@ -248,5 +248,6 @@ public class RocksDBSample {
|
||||
// be sure to dispose c++ pointers
|
||||
options.dispose();
|
||||
readOptions.dispose();
|
||||
filter.dispose();
|
||||
}
|
||||
}
|
||||
|
@ -55,8 +55,8 @@ public class BackupableDB extends RocksDB {
|
||||
* should be transparent to Java developers.
|
||||
*/
|
||||
@Override public synchronized void close() {
|
||||
if (isOpened()) {
|
||||
super.close0();
|
||||
if (isInitialized()) {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,10 +73,6 @@ public class BackupableDB extends RocksDB {
|
||||
close();
|
||||
}
|
||||
|
||||
private boolean isOpened() {
|
||||
return nativeHandle_ != 0;
|
||||
}
|
||||
|
||||
protected native void open(long rocksDBHandle, long backupDBOptionsHandle);
|
||||
protected native void createNewBackup(long handle, boolean flag);
|
||||
|
||||
|
@ -12,8 +12,9 @@ package org.rocksdb;
|
||||
* 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 class BackupableDBOptions extends RocksObject {
|
||||
public BackupableDBOptions(String path) {
|
||||
super();
|
||||
newBackupableDBOptions(path);
|
||||
}
|
||||
|
||||
@ -31,22 +32,13 @@ public class BackupableDBOptions {
|
||||
* Release the memory allocated for the current instance
|
||||
* in the c++ side.
|
||||
*/
|
||||
public synchronized void dispose() {
|
||||
@Override 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_;
|
||||
}
|
||||
|
@ -12,27 +12,21 @@ package org.rocksdb;
|
||||
* number of disk seeks form a handful to a single disk seek per
|
||||
* DB::Get() call.
|
||||
*/
|
||||
public abstract class Filter {
|
||||
protected long nativeHandle_ = 0;
|
||||
|
||||
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.
|
||||
*/
|
||||
protected synchronized void dispose() {
|
||||
if(nativeHandle_ != 0) {
|
||||
@Override public synchronized void dispose() {
|
||||
if (isInitialized()) {
|
||||
dispose0(nativeHandle_);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void finalize() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
protected boolean isInitialized() {
|
||||
return (nativeHandle_ != 0);
|
||||
}
|
||||
|
||||
private native void dispose0(long handle);
|
||||
}
|
||||
|
@ -16,10 +16,9 @@ package org.rocksdb;
|
||||
* non-const method, all threads accessing the same Iterator must use
|
||||
* external synchronization.
|
||||
*/
|
||||
public class Iterator {
|
||||
private long nativeHandle_;
|
||||
|
||||
public class Iterator extends RocksObject {
|
||||
public Iterator(long nativeHandle) {
|
||||
super();
|
||||
nativeHandle_ = nativeHandle;
|
||||
}
|
||||
|
||||
@ -119,22 +118,15 @@ public class Iterator {
|
||||
/**
|
||||
* Deletes underlying C++ iterator pointer.
|
||||
*/
|
||||
public synchronized void close() {
|
||||
if(nativeHandle_ != 0) {
|
||||
close0(nativeHandle_);
|
||||
@Override public synchronized void dispose() {
|
||||
if(isInitialized()) {
|
||||
dispose(nativeHandle_);
|
||||
nativeHandle_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void finalize() {
|
||||
close();
|
||||
}
|
||||
|
||||
private boolean isInitialized() {
|
||||
return (nativeHandle_ != 0);
|
||||
}
|
||||
|
||||
private native boolean isValid0(long handle);
|
||||
private native void close0(long handle);
|
||||
private native void dispose(long handle);
|
||||
private native void seekToFirst0(long handle);
|
||||
private native void seekToLast0(long handle);
|
||||
private native void next0(long handle);
|
||||
|
@ -12,7 +12,7 @@ package org.rocksdb;
|
||||
* Note that dispose() must be called before an Options instance
|
||||
* become out-of-scope to release the allocated memory in c++.
|
||||
*/
|
||||
public class Options {
|
||||
public class Options extends RocksObject {
|
||||
static final long DEFAULT_CACHE_SIZE = 8 << 20;
|
||||
/**
|
||||
* Construct options for opening a RocksDB.
|
||||
@ -21,7 +21,7 @@ public class Options {
|
||||
* an rocksdb::Options in the c++ side.
|
||||
*/
|
||||
public Options() {
|
||||
nativeHandle_ = 0;
|
||||
super();
|
||||
cacheSize_ = DEFAULT_CACHE_SIZE;
|
||||
newOptions();
|
||||
}
|
||||
@ -2311,20 +2311,12 @@ public class Options {
|
||||
* Release the memory allocated for the current instance
|
||||
* in the c++ side.
|
||||
*/
|
||||
public synchronized void dispose() {
|
||||
@Override public synchronized void dispose() {
|
||||
if (isInitialized()) {
|
||||
dispose0();
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void finalize() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
private boolean isInitialized() {
|
||||
return (nativeHandle_ != 0);
|
||||
}
|
||||
|
||||
static final int DEFAULT_PLAIN_TABLE_BLOOM_BITS_PER_KEY = 10;
|
||||
static final double DEFAULT_PLAIN_TABLE_HASH_TABLE_RATIO = 0.75;
|
||||
static final int DEFAULT_PLAIN_TABLE_INDEX_SPARSENESS = 16;
|
||||
@ -2358,7 +2350,6 @@ public class Options {
|
||||
private native void useFixedLengthPrefixExtractor(
|
||||
long handle, int prefixLength);
|
||||
|
||||
long nativeHandle_;
|
||||
long cacheSize_;
|
||||
Filter filter_;
|
||||
}
|
||||
|
@ -11,9 +11,9 @@ package org.rocksdb;
|
||||
* Note that dispose() must be called before an Options instance
|
||||
* become out-of-scope to release the allocated memory in c++.
|
||||
*/
|
||||
public class ReadOptions {
|
||||
public class ReadOptions extends RocksObject {
|
||||
public ReadOptions() {
|
||||
nativeHandle_ = 0;
|
||||
super();
|
||||
newReadOptions();
|
||||
}
|
||||
private native void newReadOptions();
|
||||
@ -24,7 +24,7 @@ public class ReadOptions {
|
||||
*
|
||||
* Calling other methods after dispose() leads to undefined behavior.
|
||||
*/
|
||||
public synchronized void dispose() {
|
||||
@Override public synchronized void dispose() {
|
||||
if (isInitialized()) {
|
||||
dispose(nativeHandle_);
|
||||
}
|
||||
@ -127,10 +127,4 @@ public class ReadOptions {
|
||||
}
|
||||
private native void setTailing(
|
||||
long handle, boolean tailing);
|
||||
|
||||
protected long nativeHandle_;
|
||||
|
||||
private boolean isInitialized() {
|
||||
return nativeHandle_ != 0;
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import org.rocksdb.util.Environment;
|
||||
* 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 {
|
||||
public class RocksDB extends RocksObject {
|
||||
public static final int NOT_FOUND = -1;
|
||||
private static final String[] compressionLibs_ = {
|
||||
"snappy", "zlib", "bzip2", "lz4", "lz4hc"};
|
||||
@ -114,12 +114,21 @@ public class RocksDB {
|
||||
return db;
|
||||
}
|
||||
|
||||
public synchronized void close() {
|
||||
if (nativeHandle_ != 0) {
|
||||
close0();
|
||||
@Override public synchronized void dispose() {
|
||||
if (isInitialized()) {
|
||||
dispose(nativeHandle_);
|
||||
nativeHandle_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the RocksDB instance.
|
||||
* This function is equivalent to dispose().
|
||||
*/
|
||||
public void close() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the database entry for "key" to "value".
|
||||
*
|
||||
@ -314,7 +323,7 @@ public class RocksDB {
|
||||
* Private constructor.
|
||||
*/
|
||||
protected RocksDB() {
|
||||
nativeHandle_ = 0;
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -361,8 +370,7 @@ public class RocksDB {
|
||||
long handle, long writeOptHandle,
|
||||
byte[] key, int keyLen) throws RocksDBException;
|
||||
protected native long iterator0(long optHandle);
|
||||
protected native void close0();
|
||||
protected native void dispose(long handle);
|
||||
|
||||
protected long nativeHandle_;
|
||||
protected Filter filter_;
|
||||
}
|
||||
|
35
java/org/rocksdb/RocksObject.java
Normal file
35
java/org/rocksdb/RocksObject.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;
|
||||
|
||||
/**
|
||||
* RocksObject is the base-class of all RocksDB related class that has
|
||||
* a pointer to some c++ rocksdb object. Although RocksObject
|
||||
* will release its c++ resource on its finalize() once it has been
|
||||
* garbage-collected, it is suggested to call dispose() manually to
|
||||
* release its c++ resource once an instance of RocksObject is no
|
||||
* longer used.
|
||||
*/
|
||||
public abstract class RocksObject {
|
||||
protected RocksObject() {
|
||||
nativeHandle_ = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the c++ object pointed by the native handle.
|
||||
*/
|
||||
public abstract void dispose();
|
||||
|
||||
protected boolean isInitialized() {
|
||||
return (nativeHandle_ != 0);
|
||||
}
|
||||
|
||||
@Override protected void finalize() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
protected long nativeHandle_;
|
||||
}
|
@ -24,9 +24,9 @@ import java.util.*;
|
||||
* non-const method, all threads accessing the same WriteBatch must use
|
||||
* external synchronization.
|
||||
*/
|
||||
public class WriteBatch {
|
||||
public class WriteBatch extends RocksObject {
|
||||
public WriteBatch() {
|
||||
nativeHandle_ = 0;
|
||||
super();
|
||||
newWriteBatch(0);
|
||||
}
|
||||
|
||||
@ -86,16 +86,12 @@ public class WriteBatch {
|
||||
/**
|
||||
* Delete the c++ side pointer.
|
||||
*/
|
||||
public synchronized void dispose() {
|
||||
if (nativeHandle_ != 0) {
|
||||
@Override public synchronized void dispose() {
|
||||
if (isInitialized()) {
|
||||
dispose0();
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void finalize() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
private native void newWriteBatch(int reserved_bytes);
|
||||
private native void put(byte[] key, int keyLen,
|
||||
byte[] value, int valueLen);
|
||||
@ -104,8 +100,6 @@ public class WriteBatch {
|
||||
private native void remove(byte[] key, int keyLen);
|
||||
private native void putLogData(byte[] blob, int blobLen);
|
||||
private native void dispose0();
|
||||
|
||||
long nativeHandle_;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,14 +11,14 @@ package org.rocksdb;
|
||||
* Note that developers should call WriteOptions.dispose() to release the
|
||||
* c++ side memory before a WriteOptions instance runs out of scope.
|
||||
*/
|
||||
public class WriteOptions {
|
||||
public class WriteOptions extends RocksObject {
|
||||
public WriteOptions() {
|
||||
nativeHandle_ = 0;
|
||||
super();
|
||||
newWriteOptions();
|
||||
}
|
||||
|
||||
public synchronized void dispose() {
|
||||
if (nativeHandle_ != 0) {
|
||||
@Override public synchronized void dispose() {
|
||||
if (isInitialized()) {
|
||||
dispose0(nativeHandle_);
|
||||
}
|
||||
}
|
||||
@ -91,16 +91,10 @@ public class WriteOptions {
|
||||
return disableWAL(nativeHandle_);
|
||||
}
|
||||
|
||||
@Override protected void finalize() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
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 dispose0(long handle);
|
||||
|
||||
protected long nativeHandle_;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ jboolean Java_org_rocksdb_Iterator_isValid0(
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Iterator
|
||||
* Method: close0
|
||||
* Method: seekToFirst0
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_Iterator_seekToFirst0(
|
||||
@ -135,13 +135,11 @@ void Java_org_rocksdb_Iterator_status0(
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Iterator
|
||||
* Method: status0
|
||||
* Method: dispose
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_Iterator_close0(
|
||||
void Java_org_rocksdb_Iterator_dispose(
|
||||
JNIEnv* env, jobject jobj, jlong handle) {
|
||||
auto it = reinterpret_cast<rocksdb::Iterator*>(handle);
|
||||
delete it;
|
||||
|
||||
rocksdb::IteratorJni::setHandle(env, jobj, nullptr);
|
||||
}
|
||||
|
@ -415,16 +415,14 @@ void Java_org_rocksdb_RocksDB_remove__JJ_3BI(
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_RocksDB
|
||||
* Method: close0
|
||||
* Signature: ()V
|
||||
* Method: dispose
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_RocksDB_close0(
|
||||
JNIEnv* env, jobject java_db) {
|
||||
rocksdb::DB* db = rocksdb::RocksDBJni::getHandle(env, java_db);
|
||||
void Java_org_rocksdb_RocksDB_dispose(
|
||||
JNIEnv* env, jobject java_db, jlong jhandle) {
|
||||
auto db = reinterpret_cast<rocksdb::DB*>(jhandle);
|
||||
assert(db != nullptr);
|
||||
delete db;
|
||||
|
||||
rocksdb::RocksDBJni::setHandle(env, java_db, nullptr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user