]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/java/rocksjni/event_listener_jnicallback.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / java / rocksjni / event_listener_jnicallback.cc
CommitLineData
20effc67
TL
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
1e59de90 7// ROCKSDB_NAMESPACE::EventListener.
20effc67
TL
8
9#include "rocksjni/event_listener_jnicallback.h"
10
11#include "rocksjni/portal.h"
12
1e59de90 13namespace ROCKSDB_NAMESPACE {
20effc67
TL
14EventListenerJniCallback::EventListenerJniCallback(
15 JNIEnv* env, jobject jevent_listener,
16 const std::set<EnabledEventCallback>& enabled_event_callbacks)
17 : JniCallback(env, jevent_listener),
18 m_enabled_event_callbacks(enabled_event_callbacks) {
19 InitCallbackMethodId(
20 m_on_flush_completed_proxy_mid, EnabledEventCallback::ON_FLUSH_COMPLETED,
21 env, AbstractEventListenerJni::getOnFlushCompletedProxyMethodId);
22
23 InitCallbackMethodId(m_on_flush_begin_proxy_mid,
24 EnabledEventCallback::ON_FLUSH_BEGIN, env,
25 AbstractEventListenerJni::getOnFlushBeginProxyMethodId);
26
27 InitCallbackMethodId(m_on_table_file_deleted_mid,
28 EnabledEventCallback::ON_TABLE_FILE_DELETED, env,
29 AbstractEventListenerJni::getOnTableFileDeletedMethodId);
30
31 InitCallbackMethodId(
32 m_on_compaction_begin_proxy_mid,
33 EnabledEventCallback::ON_COMPACTION_BEGIN, env,
34 AbstractEventListenerJni::getOnCompactionBeginProxyMethodId);
35
36 InitCallbackMethodId(
37 m_on_compaction_completed_proxy_mid,
38 EnabledEventCallback::ON_COMPACTION_COMPLETED, env,
39 AbstractEventListenerJni::getOnCompactionCompletedProxyMethodId);
40
41 InitCallbackMethodId(m_on_table_file_created_mid,
42 EnabledEventCallback::ON_TABLE_FILE_CREATED, env,
43 AbstractEventListenerJni::getOnTableFileCreatedMethodId);
44
45 InitCallbackMethodId(
46 m_on_table_file_creation_started_mid,
47 EnabledEventCallback::ON_TABLE_FILE_CREATION_STARTED, env,
48 AbstractEventListenerJni::getOnTableFileCreationStartedMethodId);
49
50 InitCallbackMethodId(m_on_mem_table_sealed_mid,
51 EnabledEventCallback::ON_MEMTABLE_SEALED, env,
52 AbstractEventListenerJni::getOnMemTableSealedMethodId);
53
54 InitCallbackMethodId(
55 m_on_column_family_handle_deletion_started_mid,
56 EnabledEventCallback::ON_COLUMN_FAMILY_HANDLE_DELETION_STARTED, env,
57 AbstractEventListenerJni::getOnColumnFamilyHandleDeletionStartedMethodId);
58
59 InitCallbackMethodId(
60 m_on_external_file_ingested_proxy_mid,
61 EnabledEventCallback::ON_EXTERNAL_FILE_INGESTED, env,
62 AbstractEventListenerJni::getOnExternalFileIngestedProxyMethodId);
63
64 InitCallbackMethodId(
65 m_on_background_error_proxy_mid,
66 EnabledEventCallback::ON_BACKGROUND_ERROR, env,
67 AbstractEventListenerJni::getOnBackgroundErrorProxyMethodId);
68
69 InitCallbackMethodId(
70 m_on_stall_conditions_changed_mid,
71 EnabledEventCallback::ON_STALL_CONDITIONS_CHANGED, env,
72 AbstractEventListenerJni::getOnStallConditionsChangedMethodId);
73
74 InitCallbackMethodId(m_on_file_read_finish_mid,
75 EnabledEventCallback::ON_FILE_READ_FINISH, env,
76 AbstractEventListenerJni::getOnFileReadFinishMethodId);
77
78 InitCallbackMethodId(m_on_file_write_finish_mid,
79 EnabledEventCallback::ON_FILE_WRITE_FINISH, env,
80 AbstractEventListenerJni::getOnFileWriteFinishMethodId);
81
82 InitCallbackMethodId(m_on_file_flush_finish_mid,
83 EnabledEventCallback::ON_FILE_FLUSH_FINISH, env,
84 AbstractEventListenerJni::getOnFileFlushFinishMethodId);
85
86 InitCallbackMethodId(m_on_file_sync_finish_mid,
87 EnabledEventCallback::ON_FILE_SYNC_FINISH, env,
88 AbstractEventListenerJni::getOnFileSyncFinishMethodId);
89
90 InitCallbackMethodId(
91 m_on_file_range_sync_finish_mid,
92 EnabledEventCallback::ON_FILE_RANGE_SYNC_FINISH, env,
93 AbstractEventListenerJni::getOnFileRangeSyncFinishMethodId);
94
95 InitCallbackMethodId(
96 m_on_file_truncate_finish_mid,
97 EnabledEventCallback::ON_FILE_TRUNCATE_FINISH, env,
98 AbstractEventListenerJni::getOnFileTruncateFinishMethodId);
99
100 InitCallbackMethodId(m_on_file_close_finish_mid,
101 EnabledEventCallback::ON_FILE_CLOSE_FINISH, env,
102 AbstractEventListenerJni::getOnFileCloseFinishMethodId);
103
104 InitCallbackMethodId(
105 m_should_be_notified_on_file_io,
106 EnabledEventCallback::SHOULD_BE_NOTIFIED_ON_FILE_IO, env,
107 AbstractEventListenerJni::getShouldBeNotifiedOnFileIOMethodId);
108
109 InitCallbackMethodId(
110 m_on_error_recovery_begin_proxy_mid,
111 EnabledEventCallback::ON_ERROR_RECOVERY_BEGIN, env,
112 AbstractEventListenerJni::getOnErrorRecoveryBeginProxyMethodId);
113
114 InitCallbackMethodId(
115 m_on_error_recovery_completed_mid,
116 EnabledEventCallback::ON_ERROR_RECOVERY_COMPLETED, env,
117 AbstractEventListenerJni::getOnErrorRecoveryCompletedMethodId);
118}
119
120EventListenerJniCallback::~EventListenerJniCallback() {}
121
122void EventListenerJniCallback::OnFlushCompleted(
123 DB* db, const FlushJobInfo& flush_job_info) {
124 if (m_on_flush_completed_proxy_mid == nullptr) {
125 return;
126 }
127
128 JNIEnv* env;
129 jboolean attached_thread;
130 jobject jflush_job_info = SetupCallbackInvocation<FlushJobInfo>(
131 env, attached_thread, flush_job_info,
132 FlushJobInfoJni::fromCppFlushJobInfo);
133
134 if (jflush_job_info != nullptr) {
135 env->CallVoidMethod(m_jcallback_obj, m_on_flush_completed_proxy_mid,
136 reinterpret_cast<jlong>(db), jflush_job_info);
137 }
138
139 CleanupCallbackInvocation(env, attached_thread, {&jflush_job_info});
140}
141
142void EventListenerJniCallback::OnFlushBegin(
143 DB* db, const FlushJobInfo& flush_job_info) {
144 if (m_on_flush_begin_proxy_mid == nullptr) {
145 return;
146 }
147
148 JNIEnv* env;
149 jboolean attached_thread;
150 jobject jflush_job_info = SetupCallbackInvocation<FlushJobInfo>(
151 env, attached_thread, flush_job_info,
152 FlushJobInfoJni::fromCppFlushJobInfo);
153
154 if (jflush_job_info != nullptr) {
155 env->CallVoidMethod(m_jcallback_obj, m_on_flush_begin_proxy_mid,
156 reinterpret_cast<jlong>(db), jflush_job_info);
157 }
158
159 CleanupCallbackInvocation(env, attached_thread, {&jflush_job_info});
160}
161
162void EventListenerJniCallback::OnTableFileDeleted(
163 const TableFileDeletionInfo& info) {
164 if (m_on_table_file_deleted_mid == nullptr) {
165 return;
166 }
167
168 JNIEnv* env;
169 jboolean attached_thread;
170 jobject jdeletion_info = SetupCallbackInvocation<TableFileDeletionInfo>(
171 env, attached_thread, info,
172 TableFileDeletionInfoJni::fromCppTableFileDeletionInfo);
173
174 if (jdeletion_info != nullptr) {
175 env->CallVoidMethod(m_jcallback_obj, m_on_table_file_deleted_mid,
176 jdeletion_info);
177 }
178
179 CleanupCallbackInvocation(env, attached_thread, {&jdeletion_info});
180}
181
182void EventListenerJniCallback::OnCompactionBegin(DB* db,
183 const CompactionJobInfo& ci) {
184 if (m_on_compaction_begin_proxy_mid == nullptr) {
185 return;
186 }
187
188 JNIEnv* env;
189 jboolean attached_thread;
190 jobject jcompaction_job_info = SetupCallbackInvocation<CompactionJobInfo>(
191 env, attached_thread, ci, CompactionJobInfoJni::fromCppCompactionJobInfo);
192
193 if (jcompaction_job_info != nullptr) {
194 env->CallVoidMethod(m_jcallback_obj, m_on_compaction_begin_proxy_mid,
195 reinterpret_cast<jlong>(db), jcompaction_job_info);
196 }
197
198 CleanupCallbackInvocation(env, attached_thread, {&jcompaction_job_info});
199}
200
201void EventListenerJniCallback::OnCompactionCompleted(
202 DB* db, const CompactionJobInfo& ci) {
203 if (m_on_compaction_completed_proxy_mid == nullptr) {
204 return;
205 }
206
207 JNIEnv* env;
208 jboolean attached_thread;
209 jobject jcompaction_job_info = SetupCallbackInvocation<CompactionJobInfo>(
210 env, attached_thread, ci, CompactionJobInfoJni::fromCppCompactionJobInfo);
211
212 if (jcompaction_job_info != nullptr) {
213 env->CallVoidMethod(m_jcallback_obj, m_on_compaction_completed_proxy_mid,
214 reinterpret_cast<jlong>(db), jcompaction_job_info);
215 }
216
217 CleanupCallbackInvocation(env, attached_thread, {&jcompaction_job_info});
218}
219
220void EventListenerJniCallback::OnTableFileCreated(
221 const TableFileCreationInfo& info) {
222 if (m_on_table_file_created_mid == nullptr) {
223 return;
224 }
225
226 JNIEnv* env;
227 jboolean attached_thread;
228 jobject jfile_creation_info = SetupCallbackInvocation<TableFileCreationInfo>(
229 env, attached_thread, info,
230 TableFileCreationInfoJni::fromCppTableFileCreationInfo);
231
232 if (jfile_creation_info != nullptr) {
233 env->CallVoidMethod(m_jcallback_obj, m_on_table_file_created_mid,
234 jfile_creation_info);
235 }
236
237 CleanupCallbackInvocation(env, attached_thread, {&jfile_creation_info});
238}
239
240void EventListenerJniCallback::OnTableFileCreationStarted(
241 const TableFileCreationBriefInfo& info) {
242 if (m_on_table_file_creation_started_mid == nullptr) {
243 return;
244 }
245
246 JNIEnv* env;
247 jboolean attached_thread;
248 jobject jcreation_brief_info =
249 SetupCallbackInvocation<TableFileCreationBriefInfo>(
250 env, attached_thread, info,
251 TableFileCreationBriefInfoJni::fromCppTableFileCreationBriefInfo);
252
253 if (jcreation_brief_info != nullptr) {
254 env->CallVoidMethod(m_jcallback_obj, m_on_table_file_creation_started_mid,
255 jcreation_brief_info);
256 }
257
258 CleanupCallbackInvocation(env, attached_thread, {&jcreation_brief_info});
259}
260
261void EventListenerJniCallback::OnMemTableSealed(const MemTableInfo& info) {
262 if (m_on_mem_table_sealed_mid == nullptr) {
263 return;
264 }
265
266 JNIEnv* env;
267 jboolean attached_thread;
268 jobject jmem_table_info = SetupCallbackInvocation<MemTableInfo>(
269 env, attached_thread, info, MemTableInfoJni::fromCppMemTableInfo);
270
271 if (jmem_table_info != nullptr) {
272 env->CallVoidMethod(m_jcallback_obj, m_on_mem_table_sealed_mid,
273 jmem_table_info);
274 }
275
276 CleanupCallbackInvocation(env, attached_thread, {&jmem_table_info});
277}
278
279void EventListenerJniCallback::OnColumnFamilyHandleDeletionStarted(
280 ColumnFamilyHandle* handle) {
281 if (m_on_column_family_handle_deletion_started_mid == nullptr) {
282 return;
283 }
284
285 JNIEnv* env;
286 jboolean attached_thread;
287 jobject jcf_handle = SetupCallbackInvocation<ColumnFamilyHandle>(
288 env, attached_thread, *handle,
289 ColumnFamilyHandleJni::fromCppColumnFamilyHandle);
290
291 if (jcf_handle != nullptr) {
292 env->CallVoidMethod(m_jcallback_obj,
293 m_on_column_family_handle_deletion_started_mid,
294 jcf_handle);
295 }
296
297 CleanupCallbackInvocation(env, attached_thread, {&jcf_handle});
298}
299
300void EventListenerJniCallback::OnExternalFileIngested(
301 DB* db, const ExternalFileIngestionInfo& info) {
302 if (m_on_external_file_ingested_proxy_mid == nullptr) {
303 return;
304 }
305
306 JNIEnv* env;
307 jboolean attached_thread;
308 jobject jingestion_info = SetupCallbackInvocation<ExternalFileIngestionInfo>(
309 env, attached_thread, info,
310 ExternalFileIngestionInfoJni::fromCppExternalFileIngestionInfo);
311
312 if (jingestion_info != nullptr) {
313 env->CallVoidMethod(m_jcallback_obj, m_on_external_file_ingested_proxy_mid,
314 reinterpret_cast<jlong>(db), jingestion_info);
315 }
316
317 CleanupCallbackInvocation(env, attached_thread, {&jingestion_info});
318}
319
320void EventListenerJniCallback::OnBackgroundError(BackgroundErrorReason reason,
321 Status* bg_error) {
322 if (m_on_background_error_proxy_mid == nullptr) {
323 return;
324 }
325
326 JNIEnv* env;
327 jboolean attached_thread;
328 jobject jstatus = SetupCallbackInvocation<Status>(
329 env, attached_thread, *bg_error, StatusJni::construct);
330
331 if (jstatus != nullptr) {
332 env->CallVoidMethod(m_jcallback_obj, m_on_background_error_proxy_mid,
333 static_cast<jbyte>(reason), jstatus);
334 }
335
336 CleanupCallbackInvocation(env, attached_thread, {&jstatus});
337}
338
339void EventListenerJniCallback::OnStallConditionsChanged(
340 const WriteStallInfo& info) {
341 if (m_on_stall_conditions_changed_mid == nullptr) {
342 return;
343 }
344
345 JNIEnv* env;
346 jboolean attached_thread;
347 jobject jwrite_stall_info = SetupCallbackInvocation<WriteStallInfo>(
348 env, attached_thread, info, WriteStallInfoJni::fromCppWriteStallInfo);
349
350 if (jwrite_stall_info != nullptr) {
351 env->CallVoidMethod(m_jcallback_obj, m_on_stall_conditions_changed_mid,
352 jwrite_stall_info);
353 }
354
355 CleanupCallbackInvocation(env, attached_thread, {&jwrite_stall_info});
356}
357
358void EventListenerJniCallback::OnFileReadFinish(const FileOperationInfo& info) {
359 OnFileOperation(m_on_file_read_finish_mid, info);
360}
361
362void EventListenerJniCallback::OnFileWriteFinish(
363 const FileOperationInfo& info) {
364 OnFileOperation(m_on_file_write_finish_mid, info);
365}
366
367void EventListenerJniCallback::OnFileFlushFinish(
368 const FileOperationInfo& info) {
369 OnFileOperation(m_on_file_flush_finish_mid, info);
370}
371
372void EventListenerJniCallback::OnFileSyncFinish(const FileOperationInfo& info) {
373 OnFileOperation(m_on_file_sync_finish_mid, info);
374}
375
376void EventListenerJniCallback::OnFileRangeSyncFinish(
377 const FileOperationInfo& info) {
378 OnFileOperation(m_on_file_range_sync_finish_mid, info);
379}
380
381void EventListenerJniCallback::OnFileTruncateFinish(
382 const FileOperationInfo& info) {
383 OnFileOperation(m_on_file_truncate_finish_mid, info);
384}
385
386void EventListenerJniCallback::OnFileCloseFinish(
387 const FileOperationInfo& info) {
388 OnFileOperation(m_on_file_close_finish_mid, info);
389}
390
391bool EventListenerJniCallback::ShouldBeNotifiedOnFileIO() {
392 if (m_should_be_notified_on_file_io == nullptr) {
393 return false;
394 }
395
396 jboolean attached_thread = JNI_FALSE;
397 JNIEnv* env = getJniEnv(&attached_thread);
398 assert(env != nullptr);
399
400 jboolean jshould_be_notified =
401 env->CallBooleanMethod(m_jcallback_obj, m_should_be_notified_on_file_io);
402
403 CleanupCallbackInvocation(env, attached_thread, {});
404
405 return static_cast<bool>(jshould_be_notified);
406}
407
408void EventListenerJniCallback::OnErrorRecoveryBegin(
409 BackgroundErrorReason reason, Status bg_error, bool* auto_recovery) {
410 if (m_on_error_recovery_begin_proxy_mid == nullptr) {
411 return;
412 }
413
414 JNIEnv* env;
415 jboolean attached_thread;
416 jobject jbg_error = SetupCallbackInvocation<Status>(
417 env, attached_thread, bg_error, StatusJni::construct);
418
419 if (jbg_error != nullptr) {
420 jboolean jauto_recovery = env->CallBooleanMethod(
421 m_jcallback_obj, m_on_error_recovery_begin_proxy_mid,
422 static_cast<jbyte>(reason), jbg_error);
423 *auto_recovery = jauto_recovery == JNI_TRUE;
424 }
425
426 CleanupCallbackInvocation(env, attached_thread, {&jbg_error});
427}
428
429void EventListenerJniCallback::OnErrorRecoveryCompleted(Status old_bg_error) {
430 if (m_on_error_recovery_completed_mid == nullptr) {
431 return;
432 }
433
434 JNIEnv* env;
435 jboolean attached_thread;
436 jobject jold_bg_error = SetupCallbackInvocation<Status>(
437 env, attached_thread, old_bg_error, StatusJni::construct);
438
439 if (jold_bg_error != nullptr) {
440 env->CallVoidMethod(m_jcallback_obj, m_on_error_recovery_completed_mid,
441 jold_bg_error);
442 }
443
444 CleanupCallbackInvocation(env, attached_thread, {&jold_bg_error});
445}
446
447void EventListenerJniCallback::InitCallbackMethodId(
448 jmethodID& mid, EnabledEventCallback eec, JNIEnv* env,
449 jmethodID (*get_id)(JNIEnv* env)) {
450 if (m_enabled_event_callbacks.count(eec) == 1) {
451 mid = get_id(env);
452 } else {
453 mid = nullptr;
454 }
455}
456
457template <class T>
458jobject EventListenerJniCallback::SetupCallbackInvocation(
459 JNIEnv*& env, jboolean& attached_thread, const T& cpp_obj,
460 jobject (*convert)(JNIEnv* env, const T* cpp_obj)) {
461 attached_thread = JNI_FALSE;
462 env = getJniEnv(&attached_thread);
463 assert(env != nullptr);
464
465 return convert(env, &cpp_obj);
466}
467
468void EventListenerJniCallback::CleanupCallbackInvocation(
469 JNIEnv* env, jboolean attached_thread,
470 std::initializer_list<jobject*> refs) {
471 for (auto* ref : refs) {
472 if (*ref == nullptr) continue;
473 env->DeleteLocalRef(*ref);
474 }
475
476 if (env->ExceptionCheck()) {
477 // exception thrown from CallVoidMethod
478 env->ExceptionDescribe(); // print out exception to stderr
479 }
480
481 releaseJniEnv(attached_thread);
482}
483
484void EventListenerJniCallback::OnFileOperation(const jmethodID& mid,
485 const FileOperationInfo& info) {
486 if (mid == nullptr) {
487 return;
488 }
489
490 JNIEnv* env;
491 jboolean attached_thread;
492 jobject jop_info = SetupCallbackInvocation<FileOperationInfo>(
493 env, attached_thread, info,
494 FileOperationInfoJni::fromCppFileOperationInfo);
495
496 if (jop_info != nullptr) {
497 env->CallVoidMethod(m_jcallback_obj, mid, jop_info);
498 }
499
500 CleanupCallbackInvocation(env, attached_thread, {&jop_info});
501}
1e59de90 502} // namespace ROCKSDB_NAMESPACE