summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/java/rocksjni/trace_writer_jnicallback.cc
blob: b6566d335b27d49b80beeb926d41fbfb8fe0fd30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//  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::TraceWriter.

#include "rocksjni/trace_writer_jnicallback.h"
#include "rocksjni/portal.h"

namespace ROCKSDB_NAMESPACE {
TraceWriterJniCallback::TraceWriterJniCallback(
    JNIEnv* env, jobject jtrace_writer)
    : JniCallback(env, jtrace_writer) {
  m_jwrite_proxy_methodid =
      AbstractTraceWriterJni::getWriteProxyMethodId(env);
  if(m_jwrite_proxy_methodid == nullptr) {
    // exception thrown: NoSuchMethodException or OutOfMemoryError
    return;
  }

  m_jclose_writer_proxy_methodid =
      AbstractTraceWriterJni::getCloseWriterProxyMethodId(env);
  if(m_jclose_writer_proxy_methodid == nullptr) {
    // exception thrown: NoSuchMethodException or OutOfMemoryError
    return;
  }

  m_jget_file_size_methodid =
      AbstractTraceWriterJni::getGetFileSizeMethodId(env);
  if(m_jget_file_size_methodid == nullptr) {
    // 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");
  }

  jshort jstatus = env->CallShortMethod(m_jcallback_obj,
      m_jwrite_proxy_methodid,
      &data);

  if(env->ExceptionCheck()) {
    // exception thrown from CallShortMethod
    env->ExceptionDescribe();  // print out exception to stderr
    releaseJniEnv(attached_thread);
    return Status::IOError("Unable to call AbstractTraceWriter#writeProxy(long)");
  }

  // unpack status code and status sub-code from jstatus
  jbyte jcode_value = (jstatus >> 8) & 0xFF;
  jbyte jsub_code_value = jstatus & 0xFF;
  std::unique_ptr<Status> s = StatusJni::toCppStatus(jcode_value, jsub_code_value);

  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");
  }

  jshort jstatus = env->CallShortMethod(m_jcallback_obj,
      m_jclose_writer_proxy_methodid);

  if(env->ExceptionCheck()) {
    // exception thrown from CallShortMethod
    env->ExceptionDescribe();  // print out exception to stderr
    releaseJniEnv(attached_thread);
    return Status::IOError("Unable to call AbstractTraceWriter#closeWriterProxy()");
  }

  // unpack status code and status sub-code from jstatus
  jbyte code_value = (jstatus >> 8) & 0xFF;
  jbyte sub_code_value = jstatus & 0xFF;
  std::unique_ptr<Status> s = StatusJni::toCppStatus(code_value, sub_code_value);

  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;
  }

  jlong jfile_size = env->CallLongMethod(m_jcallback_obj,
      m_jget_file_size_methodid);

  if(env->ExceptionCheck()) {
    // 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);
}

}  // namespace ROCKSDB_NAMESPACE