mirror of
https://github.com/facebook/rocksdb.git
synced 2024-11-26 16:30:56 +00:00
Fix code review comments raised in https://reviews.facebook.net/D22779
This commit is contained in:
parent
c63494fb61
commit
a6fb7f312d
|
@ -14,8 +14,22 @@ package org.rocksdb;
|
||||||
* @see org.rocksdb.Comparator
|
* @see org.rocksdb.Comparator
|
||||||
* @see org.rocksdb.DirectComparator
|
* @see org.rocksdb.DirectComparator
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractComparator<T extends AbstractSlice> extends RocksObject {
|
public abstract class AbstractComparator<T extends AbstractSlice>
|
||||||
|
extends RocksObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the comparator. Used to check for comparator
|
||||||
|
* mismatches (i.e., a DB created with one comparator is
|
||||||
|
* accessed using a different comparator).
|
||||||
|
*
|
||||||
|
* A new name should be used whenever
|
||||||
|
* the comparator implementation changes in a way that will cause
|
||||||
|
* the relative ordering of any two keys to change.
|
||||||
|
*
|
||||||
|
* Names starting with "rocksdb." are reserved and should not be used.
|
||||||
|
*
|
||||||
|
* @return The name of this comparator implementation
|
||||||
|
*/
|
||||||
public abstract String name();
|
public abstract String name();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,13 +13,23 @@ package org.rocksdb;
|
||||||
* should extend either of the public abstract classes:
|
* should extend either of the public abstract classes:
|
||||||
* @see org.rocksdb.Slice
|
* @see org.rocksdb.Slice
|
||||||
* @see org.rocksdb.DirectSlice
|
* @see org.rocksdb.DirectSlice
|
||||||
|
*
|
||||||
|
* Regards the lifecycle of Java Slices in RocksDB:
|
||||||
|
* At present when you configure a Comparator from Java, it creates an
|
||||||
|
* instance of a C++ BaseComparatorJniCallback subclass and
|
||||||
|
* passes that to RocksDB as the comparator. That subclass of
|
||||||
|
* BaseComparatorJniCallback creates the Java
|
||||||
|
* {@see org.rocksdb.AbstractSlice} subclass Objects. When you dispose
|
||||||
|
* the Java {@see org.rocksdb.AbstractComparator} subclass, it disposes the
|
||||||
|
* C++ BaseComparatorJniCallback subclass, which in turn destroys the
|
||||||
|
* Java {@see org.rocksdb.AbstractSlice} subclass Objects.
|
||||||
*/
|
*/
|
||||||
abstract class AbstractSlice<T> extends RocksObject {
|
abstract class AbstractSlice<T> extends RocksObject {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the data.
|
* Returns the data of the slice.
|
||||||
*
|
*
|
||||||
* @return The data. Note, the type of access is
|
* @return The slice data. Note, the type of access is
|
||||||
* determined by the subclass
|
* determined by the subclass
|
||||||
* @see org.rocksdb.AbstractSlice#data0(long).
|
* @see org.rocksdb.AbstractSlice#data0(long).
|
||||||
*/
|
*/
|
||||||
|
@ -65,7 +75,7 @@ abstract class AbstractSlice<T> extends RocksObject {
|
||||||
* Creates a string representation of the data
|
* Creates a string representation of the data
|
||||||
*
|
*
|
||||||
* @param hex When true, the representation
|
* @param hex When true, the representation
|
||||||
* will be encoded in hexidecimal.
|
* will be encoded in hexadecimal.
|
||||||
*
|
*
|
||||||
* @return The string representation of the data.
|
* @return The string representation of the data.
|
||||||
*/
|
*/
|
||||||
|
@ -96,13 +106,13 @@ abstract class AbstractSlice<T> extends RocksObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If other is a slice, then
|
* If other is a slice object, then
|
||||||
* we defer to compare to check equality,
|
* we defer to {@link #compare(AbstractSlice) compare}
|
||||||
* otherwise we return false.
|
* to check equality, otherwise we return false.
|
||||||
*
|
*
|
||||||
* @param other Object to test for equality
|
* @param other Object to test for equality
|
||||||
*
|
*
|
||||||
* @return true when this.compare(other) == 0,
|
* @return true when {@code this.compare(other) == 0},
|
||||||
* false otherwise.
|
* false otherwise.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -115,13 +125,14 @@ abstract class AbstractSlice<T> extends RocksObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether this starts with prefix
|
* Determines whether this slice starts with
|
||||||
|
* another slice
|
||||||
*
|
*
|
||||||
* @param prefix Another slice which may of may not
|
* @param prefix Another slice which may of may not
|
||||||
* be the prefix of this slice.
|
* be a prefix of this slice.
|
||||||
*
|
*
|
||||||
* @return true when slice `prefix` is a prefix
|
* @return true when this slice starts with the
|
||||||
* of this slice
|
* {@code prefix} slice
|
||||||
*/
|
*/
|
||||||
public boolean startsWith(final AbstractSlice prefix) {
|
public boolean startsWith(final AbstractSlice prefix) {
|
||||||
if (prefix != null) {
|
if (prefix != null) {
|
||||||
|
|
|
@ -15,7 +15,6 @@ package org.rocksdb;
|
||||||
* using @see org.rocksdb.DirectComparator
|
* using @see org.rocksdb.DirectComparator
|
||||||
*/
|
*/
|
||||||
public abstract class Comparator extends AbstractComparator<Slice> {
|
public abstract class Comparator extends AbstractComparator<Slice> {
|
||||||
|
|
||||||
public Comparator(final ComparatorOptions copt) {
|
public Comparator(final ComparatorOptions copt) {
|
||||||
super();
|
super();
|
||||||
createNewComparator0(copt.nativeHandle_);
|
createNewComparator0(copt.nativeHandle_);
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
package org.rocksdb;
|
package org.rocksdb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class controls the behaviour
|
||||||
|
* of Java implementations of
|
||||||
|
* AbstractComparator
|
||||||
|
*
|
||||||
|
* Note that dispose() must be called before a ComparatorOptions
|
||||||
|
* instance becomes out-of-scope to release the allocated memory in C++.
|
||||||
|
*/
|
||||||
public class ComparatorOptions extends RocksObject {
|
public class ComparatorOptions extends RocksObject {
|
||||||
|
|
||||||
public ComparatorOptions() {
|
public ComparatorOptions() {
|
||||||
super();
|
super();
|
||||||
newComparatorOptions();
|
newComparatorOptions();
|
||||||
|
@ -44,6 +51,7 @@ public class ComparatorOptions extends RocksObject {
|
||||||
|
|
||||||
private native void newComparatorOptions();
|
private native void newComparatorOptions();
|
||||||
private native boolean useAdaptiveMutex(final long handle);
|
private native boolean useAdaptiveMutex(final long handle);
|
||||||
private native void setUseAdaptiveMutex(final long handle, final boolean useAdaptiveMutex);
|
private native void setUseAdaptiveMutex(final long handle,
|
||||||
|
final boolean useAdaptiveMutex);
|
||||||
private native void disposeInternal(long handle);
|
private native void disposeInternal(long handle);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ package org.rocksdb;
|
||||||
* using @see org.rocksdb.Comparator
|
* using @see org.rocksdb.Comparator
|
||||||
*/
|
*/
|
||||||
public abstract class DirectComparator extends AbstractComparator<DirectSlice> {
|
public abstract class DirectComparator extends AbstractComparator<DirectSlice> {
|
||||||
|
|
||||||
public DirectComparator(final ComparatorOptions copt) {
|
public DirectComparator(final ComparatorOptions copt) {
|
||||||
super();
|
super();
|
||||||
createNewDirectComparator0(copt.nativeHandle_);
|
createNewDirectComparator0(copt.nativeHandle_);
|
||||||
|
|
|
@ -16,11 +16,18 @@ import java.nio.ByteBuffer;
|
||||||
* values consider using @see org.rocksdb.Slice
|
* values consider using @see org.rocksdb.Slice
|
||||||
*/
|
*/
|
||||||
public class DirectSlice extends AbstractSlice<ByteBuffer> {
|
public class DirectSlice extends AbstractSlice<ByteBuffer> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from JNI to construct a new Java DirectSlice
|
* Called from JNI to construct a new Java DirectSlice
|
||||||
* without an underlying C++ object set
|
* without an underlying C++ object set
|
||||||
* at creation time.
|
* at creation time.
|
||||||
|
*
|
||||||
|
* Note: You should be aware that
|
||||||
|
* {@see org.rocksdb.RocksObject#disOwnNativeHandle()} is intentionally
|
||||||
|
* called from the default DirectSlice constructor, and that it is marked as
|
||||||
|
* private. This is so that developers cannot construct their own default
|
||||||
|
* DirectSlice objects (at present). As developers cannot construct their own
|
||||||
|
* DirectSlice objects through this, they are not creating underlying C++
|
||||||
|
* DirectSlice objects, and so there is nothing to free (dispose) from Java.
|
||||||
*/
|
*/
|
||||||
private DirectSlice() {
|
private DirectSlice() {
|
||||||
super();
|
super();
|
||||||
|
@ -31,6 +38,8 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
|
||||||
* Constructs a slice
|
* Constructs a slice
|
||||||
* where the data is taken from
|
* where the data is taken from
|
||||||
* a String.
|
* a String.
|
||||||
|
*
|
||||||
|
* @param str The string
|
||||||
*/
|
*/
|
||||||
public DirectSlice(final String str) {
|
public DirectSlice(final String str) {
|
||||||
super();
|
super();
|
||||||
|
@ -41,6 +50,9 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
|
||||||
* Constructs a slice where the data is
|
* Constructs a slice where the data is
|
||||||
* read from the provided
|
* read from the provided
|
||||||
* ByteBuffer up to a certain length
|
* ByteBuffer up to a certain length
|
||||||
|
*
|
||||||
|
* @param data The buffer containing the data
|
||||||
|
* @param length The length of the data to use for the slice
|
||||||
*/
|
*/
|
||||||
public DirectSlice(final ByteBuffer data, final int length) {
|
public DirectSlice(final ByteBuffer data, final int length) {
|
||||||
super();
|
super();
|
||||||
|
@ -51,6 +63,8 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
|
||||||
* Constructs a slice where the data is
|
* Constructs a slice where the data is
|
||||||
* read from the provided
|
* read from the provided
|
||||||
* ByteBuffer
|
* ByteBuffer
|
||||||
|
*
|
||||||
|
* @param data The bugger containing the data
|
||||||
*/
|
*/
|
||||||
public DirectSlice(final ByteBuffer data) {
|
public DirectSlice(final ByteBuffer data) {
|
||||||
super();
|
super();
|
||||||
|
@ -79,7 +93,7 @@ public class DirectSlice extends AbstractSlice<ByteBuffer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drops the specified n
|
* Drops the specified {@code n}
|
||||||
* number of bytes from the start
|
* number of bytes from the start
|
||||||
* of the backing slice
|
* of the backing slice
|
||||||
*
|
*
|
||||||
|
|
|
@ -14,11 +14,18 @@ package org.rocksdb;
|
||||||
* values consider using @see org.rocksdb.DirectSlice
|
* values consider using @see org.rocksdb.DirectSlice
|
||||||
*/
|
*/
|
||||||
public class Slice extends AbstractSlice<byte[]> {
|
public class Slice extends AbstractSlice<byte[]> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from JNI to construct a new Java Slice
|
* Called from JNI to construct a new Java Slice
|
||||||
* without an underlying C++ object set
|
* without an underlying C++ object set
|
||||||
* at creation time.
|
* at creation time.
|
||||||
|
*
|
||||||
|
* Note: You should be aware that
|
||||||
|
* {@see org.rocksdb.RocksObject#disOwnNativeHandle()} is intentionally
|
||||||
|
* called from the default Slice constructor, and that it is marked as
|
||||||
|
* private. This is so that developers cannot construct their own default
|
||||||
|
* Slice objects (at present). As developers cannot construct their own
|
||||||
|
* Slice objects through this, they are not creating underlying C++ Slice
|
||||||
|
* objects, and so there is nothing to free (dispose) from Java.
|
||||||
*/
|
*/
|
||||||
private Slice() {
|
private Slice() {
|
||||||
super();
|
super();
|
||||||
|
|
|
@ -52,9 +52,9 @@ public abstract class AbstractComparatorTest {
|
||||||
|
|
||||||
db = RocksDB.open(opt, db_path.toString());
|
db = RocksDB.open(opt, db_path.toString());
|
||||||
final Random random = new Random();
|
final Random random = new Random();
|
||||||
for(int i = 0; i < ITERATIONS; i++) {
|
for (int i = 0; i < ITERATIONS; i++) {
|
||||||
final byte key[] = intToByte(random.nextInt());
|
final byte key[] = intToByte(random.nextInt());
|
||||||
if(i > 0 && db.get(key) != null) { // does key already exist (avoid duplicates)
|
if (i > 0 && db.get(key) != null) { // does key already exist (avoid duplicates)
|
||||||
i--; // generate a different key
|
i--; // generate a different key
|
||||||
} else {
|
} else {
|
||||||
db.put(key, "value".getBytes());
|
db.put(key, "value".getBytes());
|
||||||
|
@ -71,7 +71,7 @@ public abstract class AbstractComparatorTest {
|
||||||
it.seekToFirst();
|
it.seekToFirst();
|
||||||
int lastKey = Integer.MIN_VALUE;
|
int lastKey = Integer.MIN_VALUE;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for(it.seekToFirst(); it.isValid(); it.next()) {
|
for (it.seekToFirst(); it.isValid(); it.next()) {
|
||||||
final int thisKey = byteToInt(it.key());
|
final int thisKey = byteToInt(it.key());
|
||||||
assert(thisKey > lastKey);
|
assert(thisKey > lastKey);
|
||||||
lastKey = thisKey;
|
lastKey = thisKey;
|
||||||
|
@ -85,11 +85,11 @@ public abstract class AbstractComparatorTest {
|
||||||
System.err.format("[ERROR]: %s%n", e);
|
System.err.format("[ERROR]: %s%n", e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
if(db != null) {
|
if (db != null) {
|
||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(opt != null) {
|
if (opt != null) {
|
||||||
opt.dispose();
|
opt.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ public abstract class AbstractComparatorTest {
|
||||||
// protect against int key calculation overflow
|
// protect against int key calculation overflow
|
||||||
final double diff = (double)iA - iB;
|
final double diff = (double)iA - iB;
|
||||||
final int result;
|
final int result;
|
||||||
if(diff < Integer.MIN_VALUE) {
|
if (diff < Integer.MIN_VALUE) {
|
||||||
result = Integer.MIN_VALUE;
|
result = Integer.MIN_VALUE;
|
||||||
} else if(diff > Integer.MAX_VALUE) {
|
} else if(diff > Integer.MAX_VALUE) {
|
||||||
result = Integer.MAX_VALUE;
|
result = Integer.MAX_VALUE;
|
||||||
|
|
|
@ -18,27 +18,6 @@
|
||||||
#include "rocksjni/comparatorjnicallback.h"
|
#include "rocksjni/comparatorjnicallback.h"
|
||||||
#include "rocksjni/portal.h"
|
#include "rocksjni/portal.h"
|
||||||
|
|
||||||
// <editor-fold desc="org.rocksdb.ComparatorOptions">
|
|
||||||
|
|
||||||
void Java_org_rocksdb_ComparatorOptions_newComparatorOptions(
|
|
||||||
JNIEnv* env, jobject jobj, jstring jpath, jboolean jshare_table_files,
|
|
||||||
jboolean jsync, jboolean jdestroy_old_data, jboolean jbackup_log_files,
|
|
||||||
jlong jbackup_rate_limit, jlong jrestore_rate_limit) {
|
|
||||||
jbackup_rate_limit = (jbackup_rate_limit <= 0) ? 0 : jbackup_rate_limit;
|
|
||||||
jrestore_rate_limit = (jrestore_rate_limit <= 0) ? 0 : jrestore_rate_limit;
|
|
||||||
|
|
||||||
const char* cpath = env->GetStringUTFChars(jpath, 0);
|
|
||||||
|
|
||||||
auto bopt = new rocksdb::BackupableDBOptions(cpath, nullptr,
|
|
||||||
jshare_table_files, nullptr, jsync, jdestroy_old_data, jbackup_log_files,
|
|
||||||
jbackup_rate_limit, jrestore_rate_limit);
|
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(jpath, cpath);
|
|
||||||
|
|
||||||
rocksdb::BackupableDBOptionsJni::setHandle(env, jobj, bopt);
|
|
||||||
}
|
|
||||||
// </editor-fold>
|
|
||||||
|
|
||||||
// <editor-fold desc="org.rocksdb.AbstractComparator>
|
// <editor-fold desc="org.rocksdb.AbstractComparator>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -12,11 +12,9 @@
|
||||||
namespace rocksdb {
|
namespace rocksdb {
|
||||||
BaseComparatorJniCallback::BaseComparatorJniCallback(
|
BaseComparatorJniCallback::BaseComparatorJniCallback(
|
||||||
JNIEnv* env, jobject jComparator,
|
JNIEnv* env, jobject jComparator,
|
||||||
const ComparatorJniCallbackOptions* copt) {
|
const ComparatorJniCallbackOptions* copt)
|
||||||
|
: mtx_compare(new port::Mutex(copt->use_adaptive_mutex)),
|
||||||
// mutex is used for synchronisation when we are re-using
|
mtx_findShortestSeparator(new port::Mutex(copt->use_adaptive_mutex)) {
|
||||||
// the global java slice objects
|
|
||||||
mutex_ = new port::Mutex(copt->use_adaptive_mutex);
|
|
||||||
|
|
||||||
// Note: Comparator methods may be accessed by multiple threads,
|
// Note: Comparator methods may be accessed by multiple threads,
|
||||||
// so we ref the jvm not the env
|
// so we ref the jvm not the env
|
||||||
|
@ -57,7 +55,10 @@ const char* BaseComparatorJniCallback::Name() const {
|
||||||
int BaseComparatorJniCallback::Compare(const Slice& a, const Slice& b) const {
|
int BaseComparatorJniCallback::Compare(const Slice& a, const Slice& b) const {
|
||||||
JNIEnv* m_env = getJniEnv();
|
JNIEnv* m_env = getJniEnv();
|
||||||
|
|
||||||
mutex_->Lock();
|
// TODO(adamretter): slice objects can potentially be cached using thread
|
||||||
|
// local variables to avoid locking. Could make this configurable depending on
|
||||||
|
// performance.
|
||||||
|
mtx_compare->Lock();
|
||||||
|
|
||||||
AbstractSliceJni::setHandle(m_env, m_jSliceA, &a);
|
AbstractSliceJni::setHandle(m_env, m_jSliceA, &a);
|
||||||
AbstractSliceJni::setHandle(m_env, m_jSliceB, &b);
|
AbstractSliceJni::setHandle(m_env, m_jSliceB, &b);
|
||||||
|
@ -65,7 +66,7 @@ int BaseComparatorJniCallback::Compare(const Slice& a, const Slice& b) const {
|
||||||
m_env->CallIntMethod(m_jComparator, m_jCompareMethodId, m_jSliceA,
|
m_env->CallIntMethod(m_jComparator, m_jCompareMethodId, m_jSliceA,
|
||||||
m_jSliceB);
|
m_jSliceB);
|
||||||
|
|
||||||
mutex_->Unlock();
|
mtx_compare->Unlock();
|
||||||
|
|
||||||
m_jvm->DetachCurrentThread();
|
m_jvm->DetachCurrentThread();
|
||||||
|
|
||||||
|
@ -83,14 +84,17 @@ void BaseComparatorJniCallback::FindShortestSeparator(
|
||||||
const char* startUtf = start->c_str();
|
const char* startUtf = start->c_str();
|
||||||
jstring jsStart = m_env->NewStringUTF(startUtf);
|
jstring jsStart = m_env->NewStringUTF(startUtf);
|
||||||
|
|
||||||
mutex_->Lock();
|
// TODO(adamretter): slice object can potentially be cached using thread local
|
||||||
|
// variable to avoid locking. Could make this configurable depending on
|
||||||
|
// performance.
|
||||||
|
mtx_findShortestSeparator->Lock();
|
||||||
|
|
||||||
AbstractSliceJni::setHandle(m_env, m_jSliceLimit, &limit);
|
AbstractSliceJni::setHandle(m_env, m_jSliceLimit, &limit);
|
||||||
jstring jsResultStart =
|
jstring jsResultStart =
|
||||||
(jstring)m_env->CallObjectMethod(m_jComparator,
|
(jstring)m_env->CallObjectMethod(m_jComparator,
|
||||||
m_jFindShortestSeparatorMethodId, jsStart, m_jSliceLimit);
|
m_jFindShortestSeparatorMethodId, jsStart, m_jSliceLimit);
|
||||||
|
|
||||||
mutex_->Unlock();
|
mtx_findShortestSeparator->Unlock();
|
||||||
|
|
||||||
m_env->DeleteLocalRef(jsStart);
|
m_env->DeleteLocalRef(jsStart);
|
||||||
|
|
||||||
|
@ -120,9 +124,8 @@ void BaseComparatorJniCallback::FindShortSuccessor(std::string* key) const {
|
||||||
m_env->DeleteLocalRef(jsKey);
|
m_env->DeleteLocalRef(jsKey);
|
||||||
|
|
||||||
if (jsResultKey != nullptr) {
|
if (jsResultKey != nullptr) {
|
||||||
// update key with result
|
// updates key with result, also releases jsResultKey.
|
||||||
*key =
|
*key = JniUtil::copyString(m_env, jsResultKey);
|
||||||
JniUtil::copyString(m_env, jsResultKey); // also releases jsResultKey
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_jvm->DetachCurrentThread();
|
m_jvm->DetachCurrentThread();
|
||||||
|
@ -132,9 +135,6 @@ BaseComparatorJniCallback::~BaseComparatorJniCallback() {
|
||||||
JNIEnv* m_env = getJniEnv();
|
JNIEnv* m_env = getJniEnv();
|
||||||
|
|
||||||
m_env->DeleteGlobalRef(m_jComparator);
|
m_env->DeleteGlobalRef(m_jComparator);
|
||||||
m_env->DeleteGlobalRef(m_jSliceA);
|
|
||||||
m_env->DeleteGlobalRef(m_jSliceB);
|
|
||||||
m_env->DeleteGlobalRef(m_jSliceLimit);
|
|
||||||
|
|
||||||
// Note: do not need to explicitly detach, as this function is effectively
|
// Note: do not need to explicitly detach, as this function is effectively
|
||||||
// called from the Java class's disposeInternal method, and so already
|
// called from the Java class's disposeInternal method, and so already
|
||||||
|
@ -151,6 +151,13 @@ ComparatorJniCallback::ComparatorJniCallback(
|
||||||
m_jSliceLimit = env->NewGlobalRef(SliceJni::construct0(env));
|
m_jSliceLimit = env->NewGlobalRef(SliceJni::construct0(env));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ComparatorJniCallback::~ComparatorJniCallback() {
|
||||||
|
JNIEnv* m_env = getJniEnv();
|
||||||
|
m_env->DeleteGlobalRef(m_jSliceA);
|
||||||
|
m_env->DeleteGlobalRef(m_jSliceB);
|
||||||
|
m_env->DeleteGlobalRef(m_jSliceLimit);
|
||||||
|
}
|
||||||
|
|
||||||
DirectComparatorJniCallback::DirectComparatorJniCallback(
|
DirectComparatorJniCallback::DirectComparatorJniCallback(
|
||||||
JNIEnv* env, jobject jComparator,
|
JNIEnv* env, jobject jComparator,
|
||||||
const ComparatorJniCallbackOptions* copt) :
|
const ComparatorJniCallbackOptions* copt) :
|
||||||
|
@ -159,4 +166,11 @@ DirectComparatorJniCallback::DirectComparatorJniCallback(
|
||||||
m_jSliceB = env->NewGlobalRef(DirectSliceJni::construct0(env));
|
m_jSliceB = env->NewGlobalRef(DirectSliceJni::construct0(env));
|
||||||
m_jSliceLimit = env->NewGlobalRef(DirectSliceJni::construct0(env));
|
m_jSliceLimit = env->NewGlobalRef(DirectSliceJni::construct0(env));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DirectComparatorJniCallback::~DirectComparatorJniCallback() {
|
||||||
|
JNIEnv* m_env = getJniEnv();
|
||||||
|
m_env->DeleteGlobalRef(m_jSliceA);
|
||||||
|
m_env->DeleteGlobalRef(m_jSliceB);
|
||||||
|
m_env->DeleteGlobalRef(m_jSliceLimit);
|
||||||
|
}
|
||||||
} // namespace rocksdb
|
} // namespace rocksdb
|
||||||
|
|
|
@ -41,7 +41,8 @@ struct ComparatorJniCallbackOptions {
|
||||||
* method callbacks. Instead of creating new objects for each callback
|
* method callbacks. Instead of creating new objects for each callback
|
||||||
* of those functions, by reuse via setHandle we are a lot
|
* of those functions, by reuse via setHandle we are a lot
|
||||||
* faster; Unfortunately this means that we have to
|
* faster; Unfortunately this means that we have to
|
||||||
* introduce locking in regions of those methods via mutex_.
|
* introduce independent locking in regions of each of those methods
|
||||||
|
* via the mutexs mtx_compare and mtx_findShortestSeparator respectively
|
||||||
*/
|
*/
|
||||||
class BaseComparatorJniCallback : public Comparator {
|
class BaseComparatorJniCallback : public Comparator {
|
||||||
public:
|
public:
|
||||||
|
@ -56,16 +57,19 @@ class BaseComparatorJniCallback : public Comparator {
|
||||||
virtual void FindShortSuccessor(std::string* key) const;
|
virtual void FindShortSuccessor(std::string* key) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
port::Mutex* mutex_;
|
// used for synchronisation in compare method
|
||||||
|
port::Mutex* mtx_compare;
|
||||||
|
// used for synchronisation in findShortestSeparator method
|
||||||
|
port::Mutex* mtx_findShortestSeparator;
|
||||||
JavaVM* m_jvm;
|
JavaVM* m_jvm;
|
||||||
jobject m_jComparator;
|
jobject m_jComparator;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
jmethodID m_jCompareMethodId;
|
jmethodID m_jCompareMethodId;
|
||||||
jmethodID m_jFindShortestSeparatorMethodId;
|
jmethodID m_jFindShortestSeparatorMethodId;
|
||||||
jmethodID m_jFindShortSuccessorMethodId;
|
jmethodID m_jFindShortSuccessorMethodId;
|
||||||
JNIEnv* getJniEnv() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
JNIEnv* getJniEnv() const;
|
||||||
jobject m_jSliceA;
|
jobject m_jSliceA;
|
||||||
jobject m_jSliceB;
|
jobject m_jSliceB;
|
||||||
jobject m_jSliceLimit;
|
jobject m_jSliceLimit;
|
||||||
|
@ -76,6 +80,7 @@ class ComparatorJniCallback : public BaseComparatorJniCallback {
|
||||||
ComparatorJniCallback(
|
ComparatorJniCallback(
|
||||||
JNIEnv* env, jobject jComparator,
|
JNIEnv* env, jobject jComparator,
|
||||||
const ComparatorJniCallbackOptions* copt);
|
const ComparatorJniCallbackOptions* copt);
|
||||||
|
~ComparatorJniCallback();
|
||||||
};
|
};
|
||||||
|
|
||||||
class DirectComparatorJniCallback : public BaseComparatorJniCallback {
|
class DirectComparatorJniCallback : public BaseComparatorJniCallback {
|
||||||
|
@ -83,6 +88,7 @@ class DirectComparatorJniCallback : public BaseComparatorJniCallback {
|
||||||
DirectComparatorJniCallback(
|
DirectComparatorJniCallback(
|
||||||
JNIEnv* env, jobject jComparator,
|
JNIEnv* env, jobject jComparator,
|
||||||
const ComparatorJniCallbackOptions* copt);
|
const ComparatorJniCallbackOptions* copt);
|
||||||
|
~DirectComparatorJniCallback();
|
||||||
};
|
};
|
||||||
} // namespace rocksdb
|
} // namespace rocksdb
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue