summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/java/rocksjni/wal_filter_jnicallback.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/rocksdb/java/rocksjni/wal_filter_jnicallback.cc139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/rocksdb/java/rocksjni/wal_filter_jnicallback.cc b/src/rocksdb/java/rocksjni/wal_filter_jnicallback.cc
new file mode 100644
index 000000000..d2e3c9076
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/wal_filter_jnicallback.cc
@@ -0,0 +1,139 @@
+// 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
+// ROCKSDB_NAMESPACE::WalFilter.
+
+#include "rocksjni/wal_filter_jnicallback.h"
+
+#include "rocksjni/cplusplus_to_java_convert.h"
+#include "rocksjni/portal.h"
+
+namespace ROCKSDB_NAMESPACE {
+WalFilterJniCallback::WalFilterJniCallback(JNIEnv* env, jobject jwal_filter)
+ : JniCallback(env, jwal_filter) {
+ // Note: The name of a WalFilter will not change during it's lifetime,
+ // so we cache it in a global var
+ jmethodID jname_mid = AbstractWalFilterJni::getNameMethodId(env);
+ if (jname_mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+ jstring jname = (jstring)env->CallObjectMethod(m_jcallback_obj, jname_mid);
+ if (env->ExceptionCheck()) {
+ // exception thrown
+ return;
+ }
+ jboolean has_exception = JNI_FALSE;
+ m_name = JniUtil::copyString(env, jname,
+ &has_exception); // also releases jname
+ if (has_exception == JNI_TRUE) {
+ // exception thrown
+ return;
+ }
+
+ m_column_family_log_number_map_mid =
+ AbstractWalFilterJni::getColumnFamilyLogNumberMapMethodId(env);
+ if (m_column_family_log_number_map_mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+
+ m_log_record_found_proxy_mid =
+ AbstractWalFilterJni::getLogRecordFoundProxyMethodId(env);
+ if (m_log_record_found_proxy_mid == nullptr) {
+ // exception thrown: NoSuchMethodException or OutOfMemoryError
+ return;
+ }
+}
+
+void WalFilterJniCallback::ColumnFamilyLogNumberMap(
+ const std::map<uint32_t, uint64_t>& cf_lognumber_map,
+ const std::map<std::string, uint32_t>& cf_name_id_map) {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ if (env == nullptr) {
+ return;
+ }
+
+ jobject jcf_lognumber_map =
+ ROCKSDB_NAMESPACE::HashMapJni::fromCppMap(env, &cf_lognumber_map);
+ if (jcf_lognumber_map == nullptr) {
+ // exception occurred
+ env->ExceptionDescribe(); // print out exception to stderr
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ jobject jcf_name_id_map =
+ ROCKSDB_NAMESPACE::HashMapJni::fromCppMap(env, &cf_name_id_map);
+ if (jcf_name_id_map == nullptr) {
+ // exception occurred
+ env->ExceptionDescribe(); // print out exception to stderr
+ env->DeleteLocalRef(jcf_lognumber_map);
+ releaseJniEnv(attached_thread);
+ return;
+ }
+
+ env->CallVoidMethod(m_jcallback_obj, m_column_family_log_number_map_mid,
+ jcf_lognumber_map, jcf_name_id_map);
+
+ env->DeleteLocalRef(jcf_lognumber_map);
+ env->DeleteLocalRef(jcf_name_id_map);
+
+ if (env->ExceptionCheck()) {
+ // exception thrown from CallVoidMethod
+ env->ExceptionDescribe(); // print out exception to stderr
+ }
+
+ releaseJniEnv(attached_thread);
+}
+
+WalFilter::WalProcessingOption WalFilterJniCallback::LogRecordFound(
+ unsigned long long log_number, const std::string& log_file_name,
+ const WriteBatch& batch, WriteBatch* new_batch, bool* batch_changed) {
+ jboolean attached_thread = JNI_FALSE;
+ JNIEnv* env = getJniEnv(&attached_thread);
+ if (env == nullptr) {
+ return WalFilter::WalProcessingOption::kCorruptedRecord;
+ }
+
+ jstring jlog_file_name = JniUtil::toJavaString(env, &log_file_name);
+ if (jlog_file_name == nullptr) {
+ // exception occcurred
+ env->ExceptionDescribe(); // print out exception to stderr
+ releaseJniEnv(attached_thread);
+ return WalFilter::WalProcessingOption::kCorruptedRecord;
+ }
+
+ jshort jlog_record_found_result = env->CallShortMethod(
+ m_jcallback_obj, m_log_record_found_proxy_mid,
+ static_cast<jlong>(log_number), jlog_file_name,
+ GET_CPLUSPLUS_POINTER(&batch), GET_CPLUSPLUS_POINTER(new_batch));
+
+ env->DeleteLocalRef(jlog_file_name);
+
+ if (env->ExceptionCheck()) {
+ // exception thrown from CallShortMethod
+ env->ExceptionDescribe(); // print out exception to stderr
+ releaseJniEnv(attached_thread);
+ return WalFilter::WalProcessingOption::kCorruptedRecord;
+ }
+
+ // unpack WalProcessingOption and batch_changed from jlog_record_found_result
+ jbyte jwal_processing_option_value = (jlog_record_found_result >> 8) & 0xFF;
+ jbyte jbatch_changed_value = jlog_record_found_result & 0xFF;
+
+ releaseJniEnv(attached_thread);
+
+ *batch_changed = jbatch_changed_value == JNI_TRUE;
+
+ return WalProcessingOptionJni::toCppWalProcessingOption(
+ jwal_processing_option_value);
+}
+
+const char* WalFilterJniCallback::Name() const { return m_name.get(); }
+
+} // namespace ROCKSDB_NAMESPACE