2019-02-22 22:36:38 +00:00
|
|
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
|
|
|
// This source code is licensed under both the GPLv2 (found in the
|
|
|
|
// COPYING file in the root directory) and Apache 2.0 License
|
|
|
|
// (found in the LICENSE.Apache file in the root directory).
|
|
|
|
//
|
|
|
|
// This file implements the callback "bridge" between Java and C++ for
|
2020-02-20 20:07:53 +00:00
|
|
|
// ROCKSDB_NAMESPACE::TraceWriter.
|
2019-02-22 22:36:38 +00:00
|
|
|
|
|
|
|
#include "rocksjni/trace_writer_jnicallback.h"
|
2022-10-25 16:26:51 +00:00
|
|
|
|
2019-02-22 22:36:38 +00:00
|
|
|
#include "rocksjni/portal.h"
|
|
|
|
|
2020-02-20 20:07:53 +00:00
|
|
|
namespace ROCKSDB_NAMESPACE {
|
2022-10-25 16:26:51 +00:00
|
|
|
TraceWriterJniCallback::TraceWriterJniCallback(JNIEnv* env,
|
|
|
|
jobject jtrace_writer)
|
2019-02-22 22:36:38 +00:00
|
|
|
: JniCallback(env, jtrace_writer) {
|
2022-10-25 16:26:51 +00:00
|
|
|
m_jwrite_proxy_methodid = AbstractTraceWriterJni::getWriteProxyMethodId(env);
|
|
|
|
if (m_jwrite_proxy_methodid == nullptr) {
|
2019-02-22 22:36:38 +00:00
|
|
|
// exception thrown: NoSuchMethodException or OutOfMemoryError
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_jclose_writer_proxy_methodid =
|
|
|
|
AbstractTraceWriterJni::getCloseWriterProxyMethodId(env);
|
2022-10-25 16:26:51 +00:00
|
|
|
if (m_jclose_writer_proxy_methodid == nullptr) {
|
2019-02-22 22:36:38 +00:00
|
|
|
// exception thrown: NoSuchMethodException or OutOfMemoryError
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_jget_file_size_methodid =
|
|
|
|
AbstractTraceWriterJni::getGetFileSizeMethodId(env);
|
2022-10-25 16:26:51 +00:00
|
|
|
if (m_jget_file_size_methodid == nullptr) {
|
2019-02-22 22:36:38 +00:00
|
|
|
// exception thrown: NoSuchMethodException or OutOfMemoryError
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Status TraceWriterJniCallback::Write(const Slice& data) {
|
|
|
|
jboolean attached_thread = JNI_FALSE;
|
|
|
|
JNIEnv* env = getJniEnv(&attached_thread);
|
|
|
|
if (env == nullptr) {
|
|
|
|
return Status::IOError("Unable to attach JNI Environment");
|
|
|
|
}
|
|
|
|
|
2022-10-25 16:26:51 +00:00
|
|
|
jshort jstatus =
|
|
|
|
env->CallShortMethod(m_jcallback_obj, m_jwrite_proxy_methodid, &data);
|
2019-02-22 22:36:38 +00:00
|
|
|
|
2022-10-25 16:26:51 +00:00
|
|
|
if (env->ExceptionCheck()) {
|
2019-02-22 22:36:38 +00:00
|
|
|
// exception thrown from CallShortMethod
|
|
|
|
env->ExceptionDescribe(); // print out exception to stderr
|
|
|
|
releaseJniEnv(attached_thread);
|
2022-10-25 16:26:51 +00:00
|
|
|
return Status::IOError(
|
|
|
|
"Unable to call AbstractTraceWriter#writeProxy(long)");
|
2019-02-22 22:36:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// unpack status code and status sub-code from jstatus
|
|
|
|
jbyte jcode_value = (jstatus >> 8) & 0xFF;
|
|
|
|
jbyte jsub_code_value = jstatus & 0xFF;
|
2022-10-25 16:26:51 +00:00
|
|
|
std::unique_ptr<Status> s =
|
|
|
|
StatusJni::toCppStatus(jcode_value, jsub_code_value);
|
2019-02-22 22:36:38 +00:00
|
|
|
|
|
|
|
releaseJniEnv(attached_thread);
|
|
|
|
|
|
|
|
return Status(*s);
|
|
|
|
}
|
|
|
|
|
|
|
|
Status TraceWriterJniCallback::Close() {
|
|
|
|
jboolean attached_thread = JNI_FALSE;
|
|
|
|
JNIEnv* env = getJniEnv(&attached_thread);
|
|
|
|
if (env == nullptr) {
|
|
|
|
return Status::IOError("Unable to attach JNI Environment");
|
|
|
|
}
|
|
|
|
|
2022-10-25 16:26:51 +00:00
|
|
|
jshort jstatus =
|
|
|
|
env->CallShortMethod(m_jcallback_obj, m_jclose_writer_proxy_methodid);
|
2019-02-22 22:36:38 +00:00
|
|
|
|
2022-10-25 16:26:51 +00:00
|
|
|
if (env->ExceptionCheck()) {
|
2019-02-22 22:36:38 +00:00
|
|
|
// exception thrown from CallShortMethod
|
|
|
|
env->ExceptionDescribe(); // print out exception to stderr
|
|
|
|
releaseJniEnv(attached_thread);
|
2022-10-25 16:26:51 +00:00
|
|
|
return Status::IOError(
|
|
|
|
"Unable to call AbstractTraceWriter#closeWriterProxy()");
|
2019-02-22 22:36:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// unpack status code and status sub-code from jstatus
|
|
|
|
jbyte code_value = (jstatus >> 8) & 0xFF;
|
|
|
|
jbyte sub_code_value = jstatus & 0xFF;
|
2022-10-25 16:26:51 +00:00
|
|
|
std::unique_ptr<Status> s =
|
|
|
|
StatusJni::toCppStatus(code_value, sub_code_value);
|
2019-02-22 22:36:38 +00:00
|
|
|
|
|
|
|
releaseJniEnv(attached_thread);
|
|
|
|
|
|
|
|
return Status(*s);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t TraceWriterJniCallback::GetFileSize() {
|
|
|
|
jboolean attached_thread = JNI_FALSE;
|
|
|
|
JNIEnv* env = getJniEnv(&attached_thread);
|
|
|
|
if (env == nullptr) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-10-25 16:26:51 +00:00
|
|
|
jlong jfile_size =
|
|
|
|
env->CallLongMethod(m_jcallback_obj, m_jget_file_size_methodid);
|
2019-02-22 22:36:38 +00:00
|
|
|
|
2022-10-25 16:26:51 +00:00
|
|
|
if (env->ExceptionCheck()) {
|
2019-02-22 22:36:38 +00:00
|
|
|
// exception thrown from CallLongMethod
|
|
|
|
env->ExceptionDescribe(); // print out exception to stderr
|
|
|
|
releaseJniEnv(attached_thread);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
releaseJniEnv(attached_thread);
|
|
|
|
|
|
|
|
return static_cast<uint64_t>(jfile_size);
|
|
|
|
}
|
|
|
|
|
2020-02-20 20:07:53 +00:00
|
|
|
} // namespace ROCKSDB_NAMESPACE
|