@ -7,18 +7,18 @@
// ROCKSDB_NAMESPACE::Comparator.
// ROCKSDB_NAMESPACE::Comparator.
# include "rocksjni/comparatorjnicallback.h"
# include "rocksjni/comparatorjnicallback.h"
# include "rocksjni/portal.h"
# include "rocksjni/portal.h"
namespace ROCKSDB_NAMESPACE {
namespace ROCKSDB_NAMESPACE {
ComparatorJniCallback : : ComparatorJniCallback (
ComparatorJniCallback : : ComparatorJniCallback (
JNIEnv * env , jobject jcomparator ,
JNIEnv * env , jobject jcomparator ,
const ComparatorJniCallbackOptions * options )
const ComparatorJniCallbackOptions * options )
: JniCallback ( env , jcomparator ) ,
: JniCallback ( env , jcomparator ) , m_options ( options ) {
m_options ( options ) {
// cache the AbstractComparatorJniBridge class as we will reuse it many times
// for each callback
// cache the AbstractComparatorJniBridge class as we will reuse it many times for each callback
m_abstract_comparator_jni_bridge_clazz = static_cast < jclass > (
m_abstract_comparator_jni_bridge_clazz =
env - > NewGlobalRef ( AbstractComparatorJniBridge : : getJClass ( env ) ) ) ;
static_cast < jclass > ( env - > NewGlobalRef ( AbstractComparatorJniBridge : : getJClass ( env ) ) ) ;
// Note: The name of a Comparator will not change during it's lifetime,
// Note: The name of a Comparator will not change during it's lifetime,
// so we cache it in a global var
// so we cache it in a global var
@ -34,7 +34,7 @@ ComparatorJniCallback::ComparatorJniCallback(
}
}
jboolean has_exception = JNI_FALSE ;
jboolean has_exception = JNI_FALSE ;
m_name = JniUtil : : copyString ( env , js_name ,
m_name = JniUtil : : copyString ( env , js_name ,
& has_exception ) ; // also releases jsName
& has_exception ) ; // also releases jsName
if ( has_exception = = JNI_TRUE ) {
if ( has_exception = = JNI_TRUE ) {
// exception thrown
// exception thrown
return ;
return ;
@ -52,16 +52,16 @@ ComparatorJniCallback::ComparatorJniCallback(
}
}
m_jshortest_mid =
m_jshortest_mid =
AbstractComparatorJniBridge : : getFindShortestSeparatorInternalMethodId (
AbstractComparatorJniBridge : : getFindShortestSeparatorInternalMethodId (
env , m_abstract_comparator_jni_bridge_clazz ) ;
env , m_abstract_comparator_jni_bridge_clazz ) ;
if ( m_jshortest_mid = = nullptr ) {
if ( m_jshortest_mid = = nullptr ) {
// exception thrown: NoSuchMethodException or OutOfMemoryError
// exception thrown: NoSuchMethodException or OutOfMemoryError
return ;
return ;
}
}
m_jshort_mid =
m_jshort_mid =
AbstractComparatorJniBridge : : getFindShortSuccessorInternalMethodId ( env ,
AbstractComparatorJniBridge : : getFindShortSuccessorInternalMethodId (
m_abstract_comparator_jni_bridge_clazz ) ;
env , m_abstract_comparator_jni_bridge_clazz ) ;
if ( m_jshort_mid = = nullptr ) {
if ( m_jshort_mid = = nullptr ) {
// exception thrown: NoSuchMethodException or OutOfMemoryError
// exception thrown: NoSuchMethodException or OutOfMemoryError
return ;
return ;
@ -69,9 +69,8 @@ ComparatorJniCallback::ComparatorJniCallback(
// do we need reusable buffers?
// do we need reusable buffers?
if ( m_options - > max_reused_buffer_size > - 1 ) {
if ( m_options - > max_reused_buffer_size > - 1 ) {
if ( m_options - > reused_synchronisation_type = =
if ( m_options - > reused_synchronisation_type
ReusedSynchronisationType : : THREAD_LOCAL ) {
= = ReusedSynchronisationType : : THREAD_LOCAL ) {
// buffers reused per thread
// buffers reused per thread
UnrefHandler unref = [ ] ( void * ptr ) {
UnrefHandler unref = [ ] ( void * ptr ) {
ThreadLocalBuf * tlb = reinterpret_cast < ThreadLocalBuf * > ( ptr ) ;
ThreadLocalBuf * tlb = reinterpret_cast < ThreadLocalBuf * > ( ptr ) ;
@ -97,9 +96,9 @@ ComparatorJniCallback::ComparatorJniCallback(
m_jshort_buf_key = nullptr ;
m_jshort_buf_key = nullptr ;
} else {
} else {
//buffers reused and shared across threads
// buffers reused and shared across threads
const bool adaptive =
const bool adaptive = m_options - > reused_synchronisation_type = =
m_options - > reused_synchronisation_type = = ReusedSynchronisationType : : ADAPTIVE_MUTEX ;
ReusedSynchronisationType : : ADAPTIVE_MUTEX ;
mtx_compare = std : : unique_ptr < port : : Mutex > ( new port : : Mutex ( adaptive ) ) ;
mtx_compare = std : : unique_ptr < port : : Mutex > ( new port : : Mutex ( adaptive ) ) ;
mtx_shortest = std : : unique_ptr < port : : Mutex > ( new port : : Mutex ( adaptive ) ) ;
mtx_shortest = std : : unique_ptr < port : : Mutex > ( new port : : Mutex ( adaptive ) ) ;
mtx_short = std : : unique_ptr < port : : Mutex > ( new port : : Mutex ( adaptive ) ) ;
mtx_short = std : : unique_ptr < port : : Mutex > ( new port : : Mutex ( adaptive ) ) ;
@ -220,9 +219,7 @@ ComparatorJniCallback::~ComparatorJniCallback() {
releaseJniEnv ( attached_thread ) ;
releaseJniEnv ( attached_thread ) ;
}
}
const char * ComparatorJniCallback : : Name ( ) const {
const char * ComparatorJniCallback : : Name ( ) const { return m_name . get ( ) ; }
return m_name . get ( ) ;
}
int ComparatorJniCallback : : Compare ( const Slice & a , const Slice & b ) const {
int ComparatorJniCallback : : Compare ( const Slice & a , const Slice & b ) const {
jboolean attached_thread = JNI_FALSE ;
jboolean attached_thread = JNI_FALSE ;
@ -236,38 +233,38 @@ int ComparatorJniCallback::Compare(const Slice& a, const Slice& b) const {
MaybeLockForReuse ( mtx_compare , reuse_jbuf_a | | reuse_jbuf_b ) ;
MaybeLockForReuse ( mtx_compare , reuse_jbuf_a | | reuse_jbuf_b ) ;
jobject jcompare_buf_a = GetBuffer ( env , a , reuse_jbuf_a , m_tl_buf_a , m_jcompare_buf_a ) ;
jobject jcompare_buf_a =
GetBuffer ( env , a , reuse_jbuf_a , m_tl_buf_a , m_jcompare_buf_a ) ;
if ( jcompare_buf_a = = nullptr ) {
if ( jcompare_buf_a = = nullptr ) {
// exception occurred
// exception occurred
MaybeUnlockForReuse ( mtx_compare , reuse_jbuf_a | | reuse_jbuf_b ) ;
MaybeUnlockForReuse ( mtx_compare , reuse_jbuf_a | | reuse_jbuf_b ) ;
env - > ExceptionDescribe ( ) ; // print out exception to stderr
env - > ExceptionDescribe ( ) ; // print out exception to stderr
releaseJniEnv ( attached_thread ) ;
releaseJniEnv ( attached_thread ) ;
return 0 ;
return 0 ;
}
}
jobject jcompare_buf_b = GetBuffer ( env , b , reuse_jbuf_b , m_tl_buf_b , m_jcompare_buf_b ) ;
jobject jcompare_buf_b =
GetBuffer ( env , b , reuse_jbuf_b , m_tl_buf_b , m_jcompare_buf_b ) ;
if ( jcompare_buf_b = = nullptr ) {
if ( jcompare_buf_b = = nullptr ) {
// exception occurred
// exception occurred
if ( ! reuse_jbuf_a ) {
if ( ! reuse_jbuf_a ) {
DeleteBuffer ( env , jcompare_buf_a ) ;
DeleteBuffer ( env , jcompare_buf_a ) ;
}
}
MaybeUnlockForReuse ( mtx_compare , reuse_jbuf_a | | reuse_jbuf_b ) ;
MaybeUnlockForReuse ( mtx_compare , reuse_jbuf_a | | reuse_jbuf_b ) ;
env - > ExceptionDescribe ( ) ; // print out exception to stderr
env - > ExceptionDescribe ( ) ; // print out exception to stderr
releaseJniEnv ( attached_thread ) ;
releaseJniEnv ( attached_thread ) ;
return 0 ;
return 0 ;
}
}
jint result =
jint result = env - > CallStaticIntMethod (
env - > CallStaticIntMethod (
m_abstract_comparator_jni_bridge_clazz , m_jcompare_mid , m_jcallback_obj ,
m_abstract_comparator_jni_bridge_clazz , m_jcompare_mid ,
jcompare_buf_a , reuse_jbuf_a ? a . size ( ) : - 1 , jcompare_buf_b ,
m_jcallback_obj ,
reuse_jbuf_b ? b . size ( ) : - 1 ) ;
jcompare_buf_a , reuse_jbuf_a ? a . size ( ) : - 1 ,
jcompare_buf_b , reuse_jbuf_b ? b . size ( ) : - 1 ) ;
if ( env - > ExceptionCheck ( ) ) {
if ( env - > ExceptionCheck ( ) ) {
// exception thrown from CallIntMethod
// exception thrown from CallIntMethod
env - > ExceptionDescribe ( ) ; // print out exception to stderr
env - > ExceptionDescribe ( ) ; // print out exception to stderr
result = 0 ; // we could not get a result from java callback so use 0
result = 0 ; // we could not get a result from java callback so use 0
}
}
if ( ! reuse_jbuf_a ) {
if ( ! reuse_jbuf_a ) {
@ -284,8 +281,8 @@ int ComparatorJniCallback::Compare(const Slice& a, const Slice& b) const {
return result ;
return result ;
}
}
void ComparatorJniCallback : : FindShortestSeparator (
void ComparatorJniCallback : : FindShortestSeparator ( std : : string * start ,
std : : string * start , const Slice & limit ) const {
const Slice & limit ) const {
if ( start = = nullptr ) {
if ( start = = nullptr ) {
return ;
return ;
}
}
@ -294,88 +291,90 @@ void ComparatorJniCallback::FindShortestSeparator(
JNIEnv * env = getJniEnv ( & attached_thread ) ;
JNIEnv * env = getJniEnv ( & attached_thread ) ;
assert ( env ! = nullptr ) ;
assert ( env ! = nullptr ) ;
const bool reuse_jbuf_start =
const bool reuse_jbuf_start = static_cast < int64_t > ( start - > length ( ) ) < =
static_cast < int64_t > ( start - > length ( ) ) < = m_options - > max_reused_buffer_size ;
m_options - > max_reused_buffer_size ;
const bool reuse_jbuf_limit =
const bool reuse_jbuf_limit =
static_cast < int64_t > ( limit . size ( ) ) < = m_options - > max_reused_buffer_size ;
static_cast < int64_t > ( limit . size ( ) ) < = m_options - > max_reused_buffer_size ;
MaybeLockForReuse ( mtx_shortest , reuse_jbuf_start | | reuse_jbuf_limit ) ;
MaybeLockForReuse ( mtx_shortest , reuse_jbuf_start | | reuse_jbuf_limit ) ;
Slice sstart ( start - > data ( ) , start - > length ( ) ) ;
Slice sstart ( start - > data ( ) , start - > length ( ) ) ;
jobject j_start_buf = GetBuffer ( env , sstart , reuse_jbuf_start , m_tl_buf_a , m_jshortest_buf_start ) ;
jobject j_start_buf = GetBuffer ( env , sstart , reuse_jbuf_start , m_tl_buf_a ,
m_jshortest_buf_start ) ;
if ( j_start_buf = = nullptr ) {
if ( j_start_buf = = nullptr ) {
// exception occurred
// exception occurred
MaybeUnlockForReuse ( mtx_shortest , reuse_jbuf_start | | reuse_jbuf_limit ) ;
MaybeUnlockForReuse ( mtx_shortest , reuse_jbuf_start | | reuse_jbuf_limit ) ;
env - > ExceptionDescribe ( ) ; // print out exception to stderr
env - > ExceptionDescribe ( ) ; // print out exception to stderr
releaseJniEnv ( attached_thread ) ;
releaseJniEnv ( attached_thread ) ;
return ;
return ;
}
}
jobject j_limit_buf = GetBuffer ( env , limit , reuse_jbuf_limit , m_tl_buf_b , m_jshortest_buf_limit ) ;
jobject j_limit_buf = GetBuffer ( env , limit , reuse_jbuf_limit , m_tl_buf_b ,
m_jshortest_buf_limit ) ;
if ( j_limit_buf = = nullptr ) {
if ( j_limit_buf = = nullptr ) {
// exception occurred
// exception occurred
if ( ! reuse_jbuf_start ) {
if ( ! reuse_jbuf_start ) {
DeleteBuffer ( env , j_start_buf ) ;
DeleteBuffer ( env , j_start_buf ) ;
}
}
MaybeUnlockForReuse ( mtx_shortest , reuse_jbuf_start | | reuse_jbuf_limit ) ;
MaybeUnlockForReuse ( mtx_shortest , reuse_jbuf_start | | reuse_jbuf_limit ) ;
env - > ExceptionDescribe ( ) ; // print out exception to stderr
env - > ExceptionDescribe ( ) ; // print out exception to stderr
releaseJniEnv ( attached_thread ) ;
releaseJniEnv ( attached_thread ) ;
return ;
return ;
}
}
jint jstart_len = env - > CallStaticIntMethod (
jint jstart_len = env - > CallStaticIntMethod (
m_abstract_comparator_jni_bridge_clazz , m_jshortest_mid ,
m_abstract_comparator_jni_bridge_clazz , m_jshortest_mid , m_jcallback_obj ,
m_jcallback_obj ,
j_start_buf , reuse_jbuf_start ? start - > length ( ) : - 1 , j_limit_buf ,
j_start_buf , reuse_jbuf_start ? start - > length ( ) : - 1 ,
reuse_jbuf_limit ? limit . size ( ) : - 1 ) ;
j_limit_buf , reuse_jbuf_limit ? limit . size ( ) : - 1 ) ;
if ( env - > ExceptionCheck ( ) ) {
if ( env - > ExceptionCheck ( ) ) {
// exception thrown from CallIntMethod
// exception thrown from CallIntMethod
env - > ExceptionDescribe ( ) ; // print out exception to stderr
env - > ExceptionDescribe ( ) ; // print out exception to stderr
} else if ( static_cast < size_t > ( jstart_len ) ! = start - > length ( ) ) {
} else if ( static_cast < size_t > ( jstart_len ) ! = start - > length ( ) ) {
// start buffer has changed in Java, so update `start` with the result
// start buffer has changed in Java, so update `start` with the result
bool copy_from_non_direct = false ;
bool copy_from_non_direct = false ;
if ( reuse_jbuf_start ) {
if ( reuse_jbuf_start ) {
// reused a buffer
// reused a buffer
if ( m_options - > direct_buffer ) {
if ( m_options - > direct_buffer ) {
// reused direct buffer
// reused direct buffer
void * start_buf = env - > GetDirectBufferAddress ( j_start_buf ) ;
void * start_buf = env - > GetDirectBufferAddress ( j_start_buf ) ;
if ( start_buf = = nullptr ) {
if ( start_buf = = nullptr ) {
if ( ! reuse_jbuf_start ) {
if ( ! reuse_jbuf_start ) {
DeleteBuffer ( env , j_start_buf ) ;
DeleteBuffer ( env , j_start_buf ) ;
}
if ( ! reuse_jbuf_limit ) {
DeleteBuffer ( env , j_limit_buf ) ;
}
MaybeUnlockForReuse ( mtx_shortest , reuse_jbuf_start | | reuse_jbuf_limit ) ;
ROCKSDB_NAMESPACE : : RocksDBExceptionJni : : ThrowNew (
env , " Unable to get Direct Buffer Address " ) ;
env - > ExceptionDescribe ( ) ; // print out exception to stderr
releaseJniEnv ( attached_thread ) ;
return ;
}
}
start - > assign ( static_cast < const char * > ( start_buf ) , jstart_len ) ;
if ( ! reuse_jbuf_limit ) {
DeleteBuffer ( env , j_limit_buf ) ;
} else {
}
MaybeUnlockForReuse ( mtx_shortest ,
// reused non-direct buffer
reuse_jbuf_start | | reuse_jbuf_limit ) ;
copy_from_non_direct = true ;
ROCKSDB_NAMESPACE : : RocksDBExceptionJni : : ThrowNew (
env , " Unable to get Direct Buffer Address " ) ;
env - > ExceptionDescribe ( ) ; // print out exception to stderr
releaseJniEnv ( attached_thread ) ;
return ;
}
}
start - > assign ( static_cast < const char * > ( start_buf ) , jstart_len ) ;
} else {
// reused non-direct buffer
copy_from_non_direct = true ;
}
} else {
} else {
// there was a new buffer
// there was a new buffer
if ( m_options - > direct_buffer ) {
if ( m_options - > direct_buffer ) {
// it was direct... don't forget to potentially truncate the `start` string
// it was direct... don't forget to potentially truncate the `start`
start - > resize ( jstart_len ) ;
// string
} else {
start - > resize ( jstart_len ) ;
// it was non-direct
} else {
copy_from_non_direct = true ;
// it was non-direct
}
copy_from_non_direct = true ;
}
}
}
if ( copy_from_non_direct ) {
if ( copy_from_non_direct ) {
jbyteArray jarray = ByteBufferJni : : array ( env , j_start_buf ,
jbyteArray jarray =
m_jbytebuffer_clazz ) ;
ByteBufferJni : : array ( env , j_start_buf , m_jbytebuffer_clazz ) ;
if ( jarray = = nullptr ) {
if ( jarray = = nullptr ) {
if ( ! reuse_jbuf_start ) {
if ( ! reuse_jbuf_start ) {
DeleteBuffer ( env , j_start_buf ) ;
DeleteBuffer ( env , j_start_buf ) ;
@ -389,9 +388,12 @@ void ComparatorJniCallback::FindShortestSeparator(
return ;
return ;
}
}
jboolean has_exception = JNI_FALSE ;
jboolean has_exception = JNI_FALSE ;
JniUtil : : byteString < std : : string > ( env , jarray , [ start , jstart_len ] ( const char * data , const size_t ) {
JniUtil : : byteString < std : : string > (
return start - > assign ( data , static_cast < size_t > ( jstart_len ) ) ;
env , jarray ,
} , & has_exception ) ;
[ start , jstart_len ] ( const char * data , const size_t ) {
return start - > assign ( data , static_cast < size_t > ( jstart_len ) ) ;
} ,
& has_exception ) ;
env - > DeleteLocalRef ( jarray ) ;
env - > DeleteLocalRef ( jarray ) ;
if ( has_exception = = JNI_TRUE ) {
if ( has_exception = = JNI_TRUE ) {
if ( ! reuse_jbuf_start ) {
if ( ! reuse_jbuf_start ) {
@ -420,8 +422,7 @@ void ComparatorJniCallback::FindShortestSeparator(
releaseJniEnv ( attached_thread ) ;
releaseJniEnv ( attached_thread ) ;
}
}
void ComparatorJniCallback : : FindShortSuccessor (
void ComparatorJniCallback : : FindShortSuccessor ( std : : string * key ) const {
std : : string * key ) const {
if ( key = = nullptr ) {
if ( key = = nullptr ) {
return ;
return ;
}
}
@ -436,18 +437,18 @@ void ComparatorJniCallback::FindShortSuccessor(
MaybeLockForReuse ( mtx_short , reuse_jbuf_key ) ;
MaybeLockForReuse ( mtx_short , reuse_jbuf_key ) ;
Slice skey ( key - > data ( ) , key - > length ( ) ) ;
Slice skey ( key - > data ( ) , key - > length ( ) ) ;
jobject j_key_buf = GetBuffer ( env , skey , reuse_jbuf_key , m_tl_buf_a , m_jshort_buf_key ) ;
jobject j_key_buf =
GetBuffer ( env , skey , reuse_jbuf_key , m_tl_buf_a , m_jshort_buf_key ) ;
if ( j_key_buf = = nullptr ) {
if ( j_key_buf = = nullptr ) {
// exception occurred
// exception occurred
MaybeUnlockForReuse ( mtx_short , reuse_jbuf_key ) ;
MaybeUnlockForReuse ( mtx_short , reuse_jbuf_key ) ;
env - > ExceptionDescribe ( ) ; // print out exception to stderr
env - > ExceptionDescribe ( ) ; // print out exception to stderr
releaseJniEnv ( attached_thread ) ;
releaseJniEnv ( attached_thread ) ;
return ;
return ;
}
}
jint jkey_len = env - > CallStaticIntMethod (
jint jkey_len = env - > CallStaticIntMethod (
m_abstract_comparator_jni_bridge_clazz , m_jshort_mid ,
m_abstract_comparator_jni_bridge_clazz , m_jshort_mid , m_jcallback_obj ,
m_jcallback_obj ,
j_key_buf , reuse_jbuf_key ? key - > length ( ) : - 1 ) ;
j_key_buf , reuse_jbuf_key ? key - > length ( ) : - 1 ) ;
if ( env - > ExceptionCheck ( ) ) {
if ( env - > ExceptionCheck ( ) ) {
@ -459,49 +460,48 @@ void ComparatorJniCallback::FindShortSuccessor(
env - > ExceptionDescribe ( ) ; // print out exception to stderr
env - > ExceptionDescribe ( ) ; // print out exception to stderr
releaseJniEnv ( attached_thread ) ;
releaseJniEnv ( attached_thread ) ;
return ;
return ;
}
}
if ( static_cast < size_t > ( jkey_len ) ! = key - > length ( ) ) {
if ( static_cast < size_t > ( jkey_len ) ! = key - > length ( ) ) {
// key buffer has changed in Java, so update `key` with the result
// key buffer has changed in Java, so update `key` with the result
bool copy_from_non_direct = false ;
bool copy_from_non_direct = false ;
if ( reuse_jbuf_key ) {
if ( reuse_jbuf_key ) {
// reused a buffer
// reused a buffer
if ( m_options - > direct_buffer ) {
if ( m_options - > direct_buffer ) {
// reused direct buffer
// reused direct buffer
void * key_buf = env - > GetDirectBufferAddress ( j_key_buf ) ;
void * key_buf = env - > GetDirectBufferAddress ( j_key_buf ) ;
if ( key_buf = = nullptr ) {
if ( key_buf = = nullptr ) {
ROCKSDB_NAMESPACE : : RocksDBExceptionJni : : ThrowNew (
ROCKSDB_NAMESPACE : : RocksDBExceptionJni : : ThrowNew (
env , " Unable to get Direct Buffer Address " ) ;
env , " Unable to get Direct Buffer Address " ) ;
if ( ! reuse_jbuf_key ) {
if ( ! reuse_jbuf_key ) {
DeleteBuffer ( env , j_key_buf ) ;
DeleteBuffer ( env , j_key_buf ) ;
}
MaybeUnlockForReuse ( mtx_short , reuse_jbuf_key ) ;
env - > ExceptionDescribe ( ) ; // print out exception to stderr
releaseJniEnv ( attached_thread ) ;
return ;
}
}
key - > assign ( static_cast < const char * > ( key_buf ) , jkey_len ) ;
MaybeUnlockForReuse ( mtx_short , reuse_jbuf_key ) ;
} else {
env - > ExceptionDescribe ( ) ; // print out exception to stderr
// reused non-direct buffer
releaseJniEnv ( attached_thread ) ;
copy_from_non_direct = true ;
return ;
}
}
key - > assign ( static_cast < const char * > ( key_buf ) , jkey_len ) ;
} else {
// reused non-direct buffer
copy_from_non_direct = true ;
}
} else {
} else {
// there was a new buffer
// there was a new buffer
if ( m_options - > direct_buffer ) {
if ( m_options - > direct_buffer ) {
// it was direct... don't forget to potentially truncate the `key` string
// it was direct... don't forget to potentially truncate the `key`
key - > resize ( jkey_len ) ;
// string
} else {
key - > resize ( jkey_len ) ;
// it was non-direct
} else {
copy_from_non_direct = true ;
// it was non-direct
}
copy_from_non_direct = true ;
}
}
}
if ( copy_from_non_direct ) {
if ( copy_from_non_direct ) {
jbyteArray jarray = ByteBufferJni : : array ( env , j_key_buf ,
jbyteArray jarray =
m_jbytebuffer_clazz ) ;
ByteBufferJni : : array ( env , j_key_buf , m_jbytebuffer_clazz ) ;
if ( jarray = = nullptr ) {
if ( jarray = = nullptr ) {
if ( ! reuse_jbuf_key ) {
if ( ! reuse_jbuf_key ) {
DeleteBuffer ( env , j_key_buf ) ;
DeleteBuffer ( env , j_key_buf ) ;
}
}
@ -511,9 +511,12 @@ void ComparatorJniCallback::FindShortSuccessor(
return ;
return ;
}
}
jboolean has_exception = JNI_FALSE ;
jboolean has_exception = JNI_FALSE ;
JniUtil : : byteString < std : : string > ( env , jarray , [ key , jkey_len ] ( const char * data , const size_t ) {
JniUtil : : byteString < std : : string > (
return key - > assign ( data , static_cast < size_t > ( jkey_len ) ) ;
env , jarray ,
} , & has_exception ) ;
[ key , jkey_len ] ( const char * data , const size_t ) {
return key - > assign ( data , static_cast < size_t > ( jkey_len ) ) ;
} ,
& has_exception ) ;
env - > DeleteLocalRef ( jarray ) ;
env - > DeleteLocalRef ( jarray ) ;
if ( has_exception = = JNI_TRUE ) {
if ( has_exception = = JNI_TRUE ) {
if ( ! reuse_jbuf_key ) {
if ( ! reuse_jbuf_key ) {
@ -539,8 +542,9 @@ void ComparatorJniCallback::FindShortSuccessor(
inline void ComparatorJniCallback : : MaybeLockForReuse (
inline void ComparatorJniCallback : : MaybeLockForReuse (
const std : : unique_ptr < port : : Mutex > & mutex , const bool cond ) const {
const std : : unique_ptr < port : : Mutex > & mutex , const bool cond ) const {
// no need to lock if using thread_local
// no need to lock if using thread_local
if ( m_options - > reused_synchronisation_type ! = ReusedSynchronisationType : : THREAD_LOCAL
if ( m_options - > reused_synchronisation_type ! =
& & cond ) {
ReusedSynchronisationType : : THREAD_LOCAL & &
cond ) {
mutex . get ( ) - > Lock ( ) ;
mutex . get ( ) - > Lock ( ) ;
}
}
}
}
@ -548,18 +552,20 @@ inline void ComparatorJniCallback::MaybeLockForReuse(
inline void ComparatorJniCallback : : MaybeUnlockForReuse (
inline void ComparatorJniCallback : : MaybeUnlockForReuse (
const std : : unique_ptr < port : : Mutex > & mutex , const bool cond ) const {
const std : : unique_ptr < port : : Mutex > & mutex , const bool cond ) const {
// no need to unlock if using thread_local
// no need to unlock if using thread_local
if ( m_options - > reused_synchronisation_type ! = ReusedSynchronisationType : : THREAD_LOCAL
if ( m_options - > reused_synchronisation_type ! =
& & cond ) {
ReusedSynchronisationType : : THREAD_LOCAL & &
cond ) {
mutex . get ( ) - > Unlock ( ) ;
mutex . get ( ) - > Unlock ( ) ;
}
}
}
}
jobject ComparatorJniCallback : : GetBuffer ( JNIEnv * env , const Slice & src ,
jobject ComparatorJniCallback : : GetBuffer ( JNIEnv * env , const Slice & src ,
bool reuse_buffer , ThreadLocalPtr * tl_buf , jobject jreuse_buffer ) const {
bool reuse_buffer ,
ThreadLocalPtr * tl_buf ,
jobject jreuse_buffer ) const {
if ( reuse_buffer ) {
if ( reuse_buffer ) {
if ( m_options - > reused_synchronisation_type
if ( m_options - > reused_synchronisation_type = =
= = ReusedSynchronisationType : : THREAD_LOCAL ) {
ReusedSynchronisationType : : THREAD_LOCAL ) {
// reuse thread-local bufffer
// reuse thread-local bufffer
ThreadLocalBuf * tlb = reinterpret_cast < ThreadLocalBuf * > ( tl_buf - > Get ( ) ) ;
ThreadLocalBuf * tlb = reinterpret_cast < ThreadLocalBuf * > ( tl_buf - > Get ( ) ) ;
if ( tlb = = nullptr ) {
if ( tlb = = nullptr ) {
@ -576,25 +582,25 @@ jobject ComparatorJniCallback::GetBuffer(JNIEnv* env, const Slice& src,
}
}
return ReuseBuffer ( env , src , tlb - > jbuf ) ;
return ReuseBuffer ( env , src , tlb - > jbuf ) ;
} else {
} else {
// reuse class member buffer
// reuse class member buffer
return ReuseBuffer ( env , src , jreuse_buffer ) ;
return ReuseBuffer ( env , src , jreuse_buffer ) ;
}
}
} else {
} else {
// new buffer
// new buffer
return NewBuffer ( env , src ) ;
return NewBuffer ( env , src ) ;
}
}
}
}
jobject ComparatorJniCallback : : ReuseBuffer (
jobject ComparatorJniCallback : : ReuseBuffer ( JNIEnv * env , const Slice & src ,
JNIEnv * env , const Slice & src , jobject jreuse_buffer ) const {
jobject jreuse_buffer ) const {
// we can reuse the buffer
// we can reuse the buffer
if ( m_options - > direct_buffer ) {
if ( m_options - > direct_buffer ) {
// copy into direct buffer
// copy into direct buffer
void * buf = env - > GetDirectBufferAddress ( jreuse_buffer ) ;
void * buf = env - > GetDirectBufferAddress ( jreuse_buffer ) ;
if ( buf = = nullptr ) {
if ( buf = = nullptr ) {
// either memory region is undefined, given object is not a direct java.nio.Buffer, or JNI access to direct buffers is not supported by this virtual machine.
// either memory region is undefined, given object is not a direct
// java.nio.Buffer, or JNI access to direct buffers is not supported by
// this virtual machine.
ROCKSDB_NAMESPACE : : RocksDBExceptionJni : : ThrowNew (
ROCKSDB_NAMESPACE : : RocksDBExceptionJni : : ThrowNew (
env , " Unable to get Direct Buffer Address " ) ;
env , " Unable to get Direct Buffer Address " ) ;
return nullptr ;
return nullptr ;
@ -602,13 +608,14 @@ jobject ComparatorJniCallback::ReuseBuffer(
memcpy ( buf , src . data ( ) , src . size ( ) ) ;
memcpy ( buf , src . data ( ) , src . size ( ) ) ;
} else {
} else {
// copy into non-direct buffer
// copy into non-direct buffer
const jbyteArray jarray = ByteBufferJni : : array ( env , jreuse_buffer ,
const jbyteArray jarray =
m_jbytebuffer_clazz ) ;
ByteBufferJni : : array ( env , jreuse_buffer , m_jbytebuffer_clazz ) ;
if ( jarray = = nullptr ) {
if ( jarray = = nullptr ) {
// exception occurred
// exception occurred
return nullptr ;
return nullptr ;
}
}
env - > SetByteArrayRegion ( jarray , 0 , static_cast < jsize > ( src . size ( ) ) ,
env - > SetByteArrayRegion (
jarray , 0 , static_cast < jsize > ( src . size ( ) ) ,
const_cast < jbyte * > ( reinterpret_cast < const jbyte * > ( src . data ( ) ) ) ) ;
const_cast < jbyte * > ( reinterpret_cast < const jbyte * > ( src . data ( ) ) ) ) ;
if ( env - > ExceptionCheck ( ) ) {
if ( env - > ExceptionCheck ( ) ) {
// exception occurred
// exception occurred
@ -622,8 +629,9 @@ jobject ComparatorJniCallback::ReuseBuffer(
jobject ComparatorJniCallback : : NewBuffer ( JNIEnv * env , const Slice & src ) const {
jobject ComparatorJniCallback : : NewBuffer ( JNIEnv * env , const Slice & src ) const {
// we need a new buffer
// we need a new buffer
jobject jbuf = ByteBufferJni : : constructWith ( env , m_options - > direct_buffer ,
jobject jbuf =
src . data ( ) , src . size ( ) , m_jbytebuffer_clazz ) ;
ByteBufferJni : : constructWith ( env , m_options - > direct_buffer , src . data ( ) ,
src . size ( ) , m_jbytebuffer_clazz ) ;
if ( jbuf = = nullptr ) {
if ( jbuf = = nullptr ) {
// exception occurred
// exception occurred
return nullptr ;
return nullptr ;