diff --git a/java/org/rocksdb/Slice.java b/java/org/rocksdb/Slice.java index 28c29c43d..e6932cc76 100644 --- a/java/org/rocksdb/Slice.java +++ b/java/org/rocksdb/Slice.java @@ -55,7 +55,23 @@ public class Slice extends AbstractSlice { createNewSlice1(data); } + /** + * Deletes underlying C++ slice pointer + * and any buffered data. + * + *

+ * Note that this function should be called only after all + * RocksDB instances referencing the slice are closed. + * Otherwise an undefined behavior will occur. + */ + @Override + protected void disposeInternal() { + super.disposeInternal(); + disposeInternalBuf(nativeHandle_); + } + @Override protected final native byte[] data0(long handle); private native void createNewSlice0(byte[] data, int length); private native void createNewSlice1(byte[] data); + private native void disposeInternalBuf(long handle); } diff --git a/java/rocksjni/slice.cc b/java/rocksjni/slice.cc index a0a6f71e6..e54b9a745 100644 --- a/java/rocksjni/slice.cc +++ b/java/rocksjni/slice.cc @@ -130,16 +130,19 @@ void Java_org_rocksdb_Slice_createNewSlice0( void Java_org_rocksdb_Slice_createNewSlice1( JNIEnv * env, jobject jobj, jbyteArray data) { + const int len = env->GetArrayLength(data); + jboolean isCopy; jbyte* ptrData = env->GetByteArrayElements(data, &isCopy); + const char* buf = new char[len]; + memcpy((void*)buf, ptrData, len); - const rocksdb::Slice* slice = new rocksdb::Slice((const char*)ptrData, env->GetArrayLength(data)); + const rocksdb::Slice* slice = new rocksdb::Slice(buf, env->GetArrayLength(data)); rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); - env->ReleaseByteArrayElements(data, ptrData, JNI_COMMIT); + env->ReleaseByteArrayElements(data, ptrData, JNI_ABORT); - //TODO where do we free ptrData later? - //do we need to call env->ReleaseByteArrayElements(data, ptrData, JNI_ABORT) in the org.rocksdb.Slice#dispose() method? + //NOTE: buf will be deleted in the org.rocksdb.Slice#dispose method } /* @@ -156,6 +159,17 @@ jbyteArray Java_org_rocksdb_Slice_data0( return data; } +/* + * Class: org_rocksdb_Slice + * Method: disposeInternalBuf + * Signature: (J)V + */ +void Java_org_rocksdb_Slice_disposeInternalBuf( + JNIEnv * env, jobject jobj, jlong handle) { + const rocksdb::Slice* slice = reinterpret_cast(handle); + delete [] slice->data_; +} + // //