diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
commit | e6918187568dbd01842d8d1d2c808ce16a894239 (patch) | |
tree | 64f88b554b444a49f656b6c656111a145cbbaa28 /src/rocksdb/java/rocksjni/slice.cc | |
parent | Initial commit. (diff) | |
download | ceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip |
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/rocksdb/java/rocksjni/slice.cc | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/src/rocksdb/java/rocksjni/slice.cc b/src/rocksdb/java/rocksjni/slice.cc new file mode 100644 index 000000000..63c6b1b9f --- /dev/null +++ b/src/rocksdb/java/rocksjni/slice.cc @@ -0,0 +1,374 @@ +// 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_NAMESPACE::Slice. + +#include "rocksdb/slice.h" + +#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 "rocksjni/cplusplus_to_java_convert.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_NAMESPACE::Slice(buf); + return GET_CPLUSPLUS_POINTER(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_NAMESPACE::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_NAMESPACE::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_NAMESPACE::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_NAMESPACE::Slice*>(handle); + const auto* otherSlice = + reinterpret_cast<ROCKSDB_NAMESPACE::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_NAMESPACE::Slice*>(handle); + const auto* otherSlice = + reinterpret_cast<ROCKSDB_NAMESPACE::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_NAMESPACE::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_NAMESPACE::Slice((const char*)buf, len); + return GET_CPLUSPLUS_POINTER(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_NAMESPACE::Slice(buf, len - 1); + + env->ReleaseByteArrayElements(data, ptrData, JNI_ABORT); + + return GET_CPLUSPLUS_POINTER(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_NAMESPACE::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_NAMESPACE::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_NAMESPACE::Slice*>(handle); + slice->remove_prefix(length); +} + +/* + * Class: org_rocksdb_DirectSlice + * Method: setLength0 + * Signature: (JI)V + */ +void Java_org_rocksdb_DirectSlice_setLength0(JNIEnv* /*env*/, jobject /*jobj*/, + jlong handle, jint length) { + auto* slice = reinterpret_cast<ROCKSDB_NAMESPACE::Slice*>(handle); + slice->size_ = 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_NAMESPACE::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_NAMESPACE::IllegalArgumentExceptionJni::ThrowNew( + env, ROCKSDB_NAMESPACE::Status::InvalidArgument( + "Could not access DirectBuffer")); + return 0; + } + + const auto* ptrData = reinterpret_cast<char*>(data_addr); + const auto* slice = new ROCKSDB_NAMESPACE::Slice(ptrData, length); + return GET_CPLUSPLUS_POINTER(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_NAMESPACE::IllegalArgumentExceptionJni::ThrowNew( + env, ROCKSDB_NAMESPACE::Status::InvalidArgument( + "Could not access DirectBuffer")); + return 0; + } + + const auto* ptrData = reinterpret_cast<char*>(data_addr); + const auto* slice = new ROCKSDB_NAMESPACE::Slice(ptrData); + return GET_CPLUSPLUS_POINTER(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_NAMESPACE::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_NAMESPACE::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_NAMESPACE::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_NAMESPACE::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_NAMESPACE::Slice*>(handle); + const char* buf = slice->data_ - internalBufferOffset; + delete[] buf; +} + +// </editor-fold> |