summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/java/rocksjni/slice.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/rocksdb/java/rocksjni/slice.cc356
1 files changed, 356 insertions, 0 deletions
diff --git a/src/rocksdb/java/rocksjni/slice.cc b/src/rocksdb/java/rocksjni/slice.cc
new file mode 100644
index 00000000..e617cde2
--- /dev/null
+++ b/src/rocksdb/java/rocksjni/slice.cc
@@ -0,0 +1,356 @@
+// 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 "bridge" between Java and C++ for
+// rocksdb::Slice.
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+
+#include "include/org_rocksdb_AbstractSlice.h"
+#include "include/org_rocksdb_DirectSlice.h"
+#include "include/org_rocksdb_Slice.h"
+#include "rocksdb/slice.h"
+#include "rocksjni/portal.h"
+
+// <editor-fold desc="org.rocksdb.AbstractSlice>
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: createNewSliceFromString
+ * Signature: (Ljava/lang/String;)J
+ */
+jlong Java_org_rocksdb_AbstractSlice_createNewSliceFromString(JNIEnv* env,
+ jclass /*jcls*/,
+ jstring jstr) {
+ const auto* str = env->GetStringUTFChars(jstr, nullptr);
+ if (str == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+
+ const size_t len = strlen(str);
+
+ // NOTE: buf will be deleted in the
+ // Java_org_rocksdb_Slice_disposeInternalBuf or
+ // or Java_org_rocksdb_DirectSlice_disposeInternalBuf methods
+ char* buf = new char[len + 1];
+ memcpy(buf, str, len);
+ buf[len] = 0;
+ env->ReleaseStringUTFChars(jstr, str);
+
+ const auto* slice = new rocksdb::Slice(buf);
+ return reinterpret_cast<jlong>(slice);
+}
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: size0
+ * Signature: (J)I
+ */
+jint Java_org_rocksdb_AbstractSlice_size0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ return static_cast<jint>(slice->size());
+}
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: empty0
+ * Signature: (J)Z
+ */
+jboolean Java_org_rocksdb_AbstractSlice_empty0(JNIEnv* /*env*/,
+ jobject /*jobj*/, jlong handle) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ return slice->empty();
+}
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: toString0
+ * Signature: (JZ)Ljava/lang/String;
+ */
+jstring Java_org_rocksdb_AbstractSlice_toString0(JNIEnv* env, jobject /*jobj*/,
+ jlong handle, jboolean hex) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ const std::string s = slice->ToString(hex);
+ return env->NewStringUTF(s.c_str());
+}
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: compare0
+ * Signature: (JJ)I;
+ */
+jint Java_org_rocksdb_AbstractSlice_compare0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle, jlong otherHandle) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ const auto* otherSlice = reinterpret_cast<rocksdb::Slice*>(otherHandle);
+ return slice->compare(*otherSlice);
+}
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: startsWith0
+ * Signature: (JJ)Z;
+ */
+jboolean Java_org_rocksdb_AbstractSlice_startsWith0(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle,
+ jlong otherHandle) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ const auto* otherSlice = reinterpret_cast<rocksdb::Slice*>(otherHandle);
+ return slice->starts_with(*otherSlice);
+}
+
+/*
+ * Class: org_rocksdb_AbstractSlice
+ * Method: disposeInternal
+ * Signature: (J)V
+ */
+void Java_org_rocksdb_AbstractSlice_disposeInternal(JNIEnv* /*env*/,
+ jobject /*jobj*/,
+ jlong handle) {
+ delete reinterpret_cast<rocksdb::Slice*>(handle);
+}
+
+// </editor-fold>
+
+// <editor-fold desc="org.rocksdb.Slice>
+
+/*
+ * Class: org_rocksdb_Slice
+ * Method: createNewSlice0
+ * Signature: ([BI)J
+ */
+jlong Java_org_rocksdb_Slice_createNewSlice0(JNIEnv* env, jclass /*jcls*/,
+ jbyteArray data, jint offset) {
+ const jsize dataSize = env->GetArrayLength(data);
+ const int len = dataSize - offset;
+
+ // NOTE: buf will be deleted in the Java_org_rocksdb_Slice_disposeInternalBuf
+ // method
+ jbyte* buf = new jbyte[len];
+ env->GetByteArrayRegion(data, offset, len, buf);
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ return 0;
+ }
+
+ const auto* slice = new rocksdb::Slice((const char*)buf, len);
+ return reinterpret_cast<jlong>(slice);
+}
+
+/*
+ * Class: org_rocksdb_Slice
+ * Method: createNewSlice1
+ * Signature: ([B)J
+ */
+jlong Java_org_rocksdb_Slice_createNewSlice1(JNIEnv* env, jclass /*jcls*/,
+ jbyteArray data) {
+ jbyte* ptrData = env->GetByteArrayElements(data, nullptr);
+ if (ptrData == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return 0;
+ }
+ const int len = env->GetArrayLength(data) + 1;
+
+ // NOTE: buf will be deleted in the Java_org_rocksdb_Slice_disposeInternalBuf
+ // method
+ char* buf = new char[len];
+ memcpy(buf, ptrData, len - 1);
+ buf[len - 1] = '\0';
+
+ const auto* slice = new rocksdb::Slice(buf, len - 1);
+
+ env->ReleaseByteArrayElements(data, ptrData, JNI_ABORT);
+
+ return reinterpret_cast<jlong>(slice);
+}
+
+/*
+ * Class: org_rocksdb_Slice
+ * Method: data0
+ * Signature: (J)[B
+ */
+jbyteArray Java_org_rocksdb_Slice_data0(JNIEnv* env, jobject /*jobj*/,
+ jlong handle) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ const jsize len = static_cast<jsize>(slice->size());
+ const jbyteArray data = env->NewByteArray(len);
+ if (data == nullptr) {
+ // exception thrown: OutOfMemoryError
+ return nullptr;
+ }
+
+ env->SetByteArrayRegion(
+ data, 0, len,
+ const_cast<jbyte*>(reinterpret_cast<const jbyte*>(slice->data())));
+ if (env->ExceptionCheck()) {
+ // exception thrown: ArrayIndexOutOfBoundsException
+ env->DeleteLocalRef(data);
+ return nullptr;
+ }
+
+ return data;
+}
+
+/*
+ * Class: org_rocksdb_Slice
+ * Method: clear0
+ * Signature: (JZJ)V
+ */
+void Java_org_rocksdb_Slice_clear0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle, jboolean shouldRelease,
+ jlong internalBufferOffset) {
+ auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ if (shouldRelease == JNI_TRUE) {
+ const char* buf = slice->data_ - internalBufferOffset;
+ delete[] buf;
+ }
+ slice->clear();
+}
+
+/*
+ * Class: org_rocksdb_Slice
+ * Method: removePrefix0
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_Slice_removePrefix0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle, jint length) {
+ auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ slice->remove_prefix(length);
+}
+
+/*
+ * Class: org_rocksdb_Slice
+ * Method: disposeInternalBuf
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_Slice_disposeInternalBuf(JNIEnv* /*env*/,
+ jobject /*jobj*/, jlong handle,
+ jlong internalBufferOffset) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ const char* buf = slice->data_ - internalBufferOffset;
+ delete[] buf;
+}
+
+// </editor-fold>
+
+// <editor-fold desc="org.rocksdb.DirectSlice>
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: createNewDirectSlice0
+ * Signature: (Ljava/nio/ByteBuffer;I)J
+ */
+jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice0(JNIEnv* env,
+ jclass /*jcls*/,
+ jobject data,
+ jint length) {
+ assert(data != nullptr);
+ void* data_addr = env->GetDirectBufferAddress(data);
+ if (data_addr == nullptr) {
+ // error: memory region is undefined, given object is not a direct
+ // java.nio.Buffer, or JNI access to direct buffers is not supported by JVM
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Could not access DirectBuffer"));
+ return 0;
+ }
+
+ const auto* ptrData = reinterpret_cast<char*>(data_addr);
+ const auto* slice = new rocksdb::Slice(ptrData, length);
+ return reinterpret_cast<jlong>(slice);
+}
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: createNewDirectSlice1
+ * Signature: (Ljava/nio/ByteBuffer;)J
+ */
+jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice1(JNIEnv* env,
+ jclass /*jcls*/,
+ jobject data) {
+ void* data_addr = env->GetDirectBufferAddress(data);
+ if (data_addr == nullptr) {
+ // error: memory region is undefined, given object is not a direct
+ // java.nio.Buffer, or JNI access to direct buffers is not supported by JVM
+ rocksdb::IllegalArgumentExceptionJni::ThrowNew(
+ env, rocksdb::Status::InvalidArgument("Could not access DirectBuffer"));
+ return 0;
+ }
+
+ const auto* ptrData = reinterpret_cast<char*>(data_addr);
+ const auto* slice = new rocksdb::Slice(ptrData);
+ return reinterpret_cast<jlong>(slice);
+}
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: data0
+ * Signature: (J)Ljava/lang/Object;
+ */
+jobject Java_org_rocksdb_DirectSlice_data0(JNIEnv* env, jobject /*jobj*/,
+ jlong handle) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ return env->NewDirectByteBuffer(const_cast<char*>(slice->data()),
+ slice->size());
+}
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: get0
+ * Signature: (JI)B
+ */
+jbyte Java_org_rocksdb_DirectSlice_get0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle, jint offset) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ return (*slice)[offset];
+}
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: clear0
+ * Signature: (JZJ)V
+ */
+void Java_org_rocksdb_DirectSlice_clear0(JNIEnv* /*env*/, jobject /*jobj*/,
+ jlong handle, jboolean shouldRelease,
+ jlong internalBufferOffset) {
+ auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ if (shouldRelease == JNI_TRUE) {
+ const char* buf = slice->data_ - internalBufferOffset;
+ delete[] buf;
+ }
+ slice->clear();
+}
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: removePrefix0
+ * Signature: (JI)V
+ */
+void Java_org_rocksdb_DirectSlice_removePrefix0(JNIEnv* /*env*/,
+ jobject /*jobj*/, jlong handle,
+ jint length) {
+ auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ slice->remove_prefix(length);
+}
+
+/*
+ * Class: org_rocksdb_DirectSlice
+ * Method: disposeInternalBuf
+ * Signature: (JJ)V
+ */
+void Java_org_rocksdb_DirectSlice_disposeInternalBuf(
+ JNIEnv* /*env*/, jobject /*jobj*/, jlong handle,
+ jlong internalBufferOffset) {
+ const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
+ const char* buf = slice->data_ - internalBufferOffset;
+ delete[] buf;
+}
+
+// </editor-fold>