1 //  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 //
6 // This file implements the callback "bridge" between Java and C++ for
7 // ROCKSDB_NAMESPACE::CompactionFilterFactory.
8 
9 #include "rocksjni/compaction_filter_factory_jnicallback.h"
10 #include "rocksjni/portal.h"
11 
12 namespace ROCKSDB_NAMESPACE {
CompactionFilterFactoryJniCallback(JNIEnv * env,jobject jcompaction_filter_factory)13 CompactionFilterFactoryJniCallback::CompactionFilterFactoryJniCallback(
14     JNIEnv* env, jobject jcompaction_filter_factory)
15     : JniCallback(env, jcompaction_filter_factory) {
16 
17   // Note: The name of a CompactionFilterFactory will not change during
18   // it's lifetime, so we cache it in a global var
19   jmethodID jname_method_id =
20       AbstractCompactionFilterFactoryJni::getNameMethodId(env);
21   if(jname_method_id == nullptr) {
22     // exception thrown: NoSuchMethodException or OutOfMemoryError
23     return;
24   }
25 
26   jstring jname =
27       (jstring)env->CallObjectMethod(m_jcallback_obj, jname_method_id);
28   if(env->ExceptionCheck()) {
29     // exception thrown
30     return;
31   }
32   jboolean has_exception = JNI_FALSE;
33   m_name = JniUtil::copyString(env, jname, &has_exception);  // also releases jname
34   if (has_exception == JNI_TRUE) {
35     // exception thrown
36     return;
37   }
38 
39   m_jcreate_compaction_filter_methodid =
40       AbstractCompactionFilterFactoryJni::getCreateCompactionFilterMethodId(env);
41   if(m_jcreate_compaction_filter_methodid == nullptr) {
42     // exception thrown: NoSuchMethodException or OutOfMemoryError
43     return;
44   }
45 }
46 
Name() const47 const char* CompactionFilterFactoryJniCallback::Name() const {
48   return m_name.get();
49 }
50 
CreateCompactionFilter(const CompactionFilter::Context & context)51 std::unique_ptr<CompactionFilter> CompactionFilterFactoryJniCallback::CreateCompactionFilter(
52     const CompactionFilter::Context& context) {
53   jboolean attached_thread = JNI_FALSE;
54   JNIEnv* env = getJniEnv(&attached_thread);
55   assert(env != nullptr);
56 
57   jlong addr_compaction_filter = env->CallLongMethod(m_jcallback_obj,
58       m_jcreate_compaction_filter_methodid,
59       static_cast<jboolean>(context.is_full_compaction),
60       static_cast<jboolean>(context.is_manual_compaction));
61 
62   if(env->ExceptionCheck()) {
63     // exception thrown from CallLongMethod
64     env->ExceptionDescribe();  // print out exception to stderr
65     releaseJniEnv(attached_thread);
66     return nullptr;
67   }
68 
69   auto* cff = reinterpret_cast<CompactionFilter*>(addr_compaction_filter);
70 
71   releaseJniEnv(attached_thread);
72 
73   return std::unique_ptr<CompactionFilter>(cff);
74 }
75 
76 }  // namespace ROCKSDB_NAMESPACE
77