either byte[] or DirectByteBuffer for accessing underlying data.main
parent
700f6ec3ff
commit
d6fe8dacc8
@ -0,0 +1,81 @@ |
||||
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
package org.rocksdb; |
||||
|
||||
/** |
||||
* Comparators are used by RocksDB to determine |
||||
* the ordering of keys. |
||||
* |
||||
* This class is package private, implementers |
||||
* should extend either of the public abstract classes: |
||||
* @see org.rocksdb.Comparator |
||||
* @see org.rocksdb.DirectComparator |
||||
*/ |
||||
abstract class AbstractComparator<T extends AbstractSlice> extends RocksObject { |
||||
|
||||
public abstract String name(); |
||||
|
||||
/** |
||||
* Three-way key comparison |
||||
* |
||||
* @param a Slice access to first key |
||||
* @param b Slice access to second key |
||||
* |
||||
* @return Should return either: |
||||
* 1) < 0 if "a" < "b" |
||||
* 2) == 0 if "a" == "b" |
||||
* 3) > 0 if "a" > "b" |
||||
*/ |
||||
public abstract int compare(final T a, final T b); |
||||
|
||||
/** |
||||
* Used to reduce the space requirements |
||||
* for internal data structures like index blocks. |
||||
* |
||||
* If start < limit, you may return a new start which is a |
||||
* shorter string in [start, limit). |
||||
* |
||||
* Simple comparator implementations may return null if they |
||||
* wish to use start unchanged. i.e., an implementation of |
||||
* this method that does nothing is correct. |
||||
* |
||||
* @return a shorter start, or null |
||||
*/ |
||||
public String findShortestSeparator(final String start, final T limit) { |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Used to reduce the space requirements |
||||
* for internal data structures like index blocks. |
||||
* |
||||
* You may return a new short key (key1) where |
||||
* key1 >= key. |
||||
* |
||||
* Simple comparator implementations may return null if they |
||||
* wish to leave the key unchanged. i.e., an implementation of |
||||
* this method that does nothing is correct. |
||||
* |
||||
* @return a shorter key, or null |
||||
*/ |
||||
public String findShortSuccessor(final String key) { |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Deletes underlying C++ comparator pointer. |
||||
* |
||||
* Note that this function should be called only after all |
||||
* RocksDB instances referencing the comparator are closed. |
||||
* Otherwise an undefined behavior will occur. |
||||
*/ |
||||
@Override protected void disposeInternal() { |
||||
assert(isInitialized()); |
||||
disposeInternal(nativeHandle_); |
||||
} |
||||
|
||||
private native void disposeInternal(long handle); |
||||
} |
@ -0,0 +1,156 @@ |
||||
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
package org.rocksdb; |
||||
|
||||
/** |
||||
* Slices are used by RocksDB to provide |
||||
* efficient access to keys and values. |
||||
* |
||||
* This class is package private, implementers |
||||
* should extend either of the public abstract classes: |
||||
* @see org.rocksdb.Slice |
||||
* @see org.rocksdb.DirectSlice |
||||
*/ |
||||
abstract class AbstractSlice<T> extends RocksObject { |
||||
|
||||
/** |
||||
* Returns the data. |
||||
* |
||||
* @return The data. Note, the type of access is |
||||
* determined by the subclass |
||||
* @see org.rocksdb.AbstractSlice#data0(long). |
||||
*/ |
||||
public T data() { |
||||
assert (isInitialized()); |
||||
return data0(nativeHandle_); |
||||
} |
||||
|
||||
/** |
||||
* Access to the data is provided by the |
||||
* subtype as it needs to handle the |
||||
* generic typing. |
||||
* |
||||
* @param handle The address of the underlying |
||||
* native object. |
||||
* |
||||
* @return Java typed access to the data. |
||||
*/ |
||||
protected abstract T data0(long handle); |
||||
|
||||
/** |
||||
* Return the length (in bytes) of the data. |
||||
* |
||||
* @return The length in bytes. |
||||
*/ |
||||
public int size() { |
||||
assert (isInitialized()); |
||||
return size0(nativeHandle_); |
||||
} |
||||
|
||||
/** |
||||
* Return true if the length of the |
||||
* data is zero. |
||||
* |
||||
* @return true if there is no data, false otherwise. |
||||
*/ |
||||
public boolean empty() { |
||||
assert (isInitialized()); |
||||
return empty0(nativeHandle_); |
||||
} |
||||
|
||||
/** |
||||
* Creates a string representation of the data |
||||
* |
||||
* @param hex When true, the representation |
||||
* will be encoded in hexidecimal. |
||||
* |
||||
* @return The string representation of the data. |
||||
*/ |
||||
public String toString(final boolean hex) { |
||||
assert (isInitialized()); |
||||
return toString0(nativeHandle_, hex); |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return toString(false); |
||||
} |
||||
|
||||
/** |
||||
* Three-way key comparison |
||||
* |
||||
* @param other A slice to compare against |
||||
* |
||||
* @return Should return either: |
||||
* 1) < 0 if this < other |
||||
* 2) == 0 if this == other |
||||
* 3) > 0 if this > other |
||||
*/ |
||||
public int compare(final AbstractSlice other) { |
||||
assert (other != null); |
||||
assert (isInitialized()); |
||||
return compare0(nativeHandle_, other.nativeHandle_); |
||||
} |
||||
|
||||
/** |
||||
* If other is a slice, then |
||||
* we defer to compare to check equality, |
||||
* otherwise we return false. |
||||
* |
||||
* @param other Object to test for equality |
||||
* |
||||
* @return true when this.compare(other) == 0, |
||||
* false otherwise. |
||||
*/ |
||||
@Override |
||||
public boolean equals(final Object other) { |
||||
if (other != null && other instanceof AbstractSlice) { |
||||
return compare((AbstractSlice)other) == 0; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Determines whether this starts with prefix |
||||
* |
||||
* @param prefix Another slice which may of may not |
||||
* be the prefix of this slice. |
||||
* |
||||
* @return true when slice `prefix` is a prefix |
||||
* of this slice |
||||
*/ |
||||
public boolean startsWith(final AbstractSlice prefix) { |
||||
if (prefix != null) { |
||||
assert (isInitialized()); |
||||
return startsWith0(nativeHandle_, prefix.nativeHandle_); |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Deletes underlying C++ slice pointer. |
||||
* <p/> |
||||
* 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() { |
||||
assert(isInitialized()); |
||||
disposeInternal(nativeHandle_); |
||||
} |
||||
|
||||
protected native void createNewSliceFromString(String str); |
||||
private native int size0(long handle); |
||||
private native boolean empty0(long handle); |
||||
private native String toString0(long handle, boolean hex); |
||||
private native int compare0(long handle, long otherHandle); |
||||
private native boolean startsWith0(long handle, long otherHandle); |
||||
private native void disposeInternal(long handle); |
||||
|
||||
} |
@ -0,0 +1,25 @@ |
||||
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
package org.rocksdb; |
||||
|
||||
/** |
||||
* Base class for comparators which will receive |
||||
* byte[] based access via org.rocksdb.Slice in their |
||||
* compare method implementation. |
||||
* |
||||
* byte[] based slices perform better when small keys |
||||
* are involved. When using larger keys consider |
||||
* using @see org.rocksdb.DirectComparator |
||||
*/ |
||||
public abstract class Comparator extends AbstractComparator<Slice> { |
||||
|
||||
public Comparator() { |
||||
super(); |
||||
createNewComparator0(); |
||||
} |
||||
|
||||
private native void createNewComparator0(); |
||||
} |
@ -0,0 +1,25 @@ |
||||
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
package org.rocksdb; |
||||
|
||||
/** |
||||
* Base class for comparators which will receive |
||||
* ByteBuffer based access via org.rocksdb.DirectSlice |
||||
* in their compare method implementation. |
||||
* |
||||
* ByteBuffer based slices perform better when large keys |
||||
* are involved. When using smaller keys consider |
||||
* using @see org.rocksdb.Comparator |
||||
*/ |
||||
public abstract class DirectComparator extends AbstractComparator<DirectSlice> { |
||||
|
||||
public DirectComparator() { |
||||
super(); |
||||
createNewDirectComparator0(); |
||||
} |
||||
|
||||
private native void createNewDirectComparator0(); |
||||
} |
@ -0,0 +1,99 @@ |
||||
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
package org.rocksdb; |
||||
|
||||
import java.nio.ByteBuffer; |
||||
|
||||
/** |
||||
* Base class for slices which will receive direct |
||||
* ByteBuffer based access to the underlying data. |
||||
* |
||||
* ByteBuffer backed slices typically perform better with |
||||
* larger keys and values. When using smaller keys and |
||||
* values consider using @see org.rocksdb.Slice |
||||
*/ |
||||
public class DirectSlice extends AbstractSlice<ByteBuffer> { |
||||
|
||||
/** |
||||
* Called from JNI to construct a new Java DirectSlice |
||||
* without an underlying C++ object set |
||||
* at creation time. |
||||
*/ |
||||
private DirectSlice() { |
||||
super(); |
||||
disOwnNativeHandle(); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a slice |
||||
* where the data is taken from |
||||
* a String. |
||||
*/ |
||||
public DirectSlice(final String str) { |
||||
super(); |
||||
createNewSliceFromString(str); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a slice where the data is |
||||
* read from the provided |
||||
* ByteBuffer up to a certain length |
||||
*/ |
||||
public DirectSlice(final ByteBuffer data, final int length) { |
||||
super(); |
||||
createNewDirectSlice0(data, length); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a slice where the data is |
||||
* read from the provided |
||||
* ByteBuffer |
||||
*/ |
||||
public DirectSlice(final ByteBuffer data) { |
||||
super(); |
||||
createNewDirectSlice1(data); |
||||
} |
||||
|
||||
/** |
||||
* Retrieves the byte at a specific offset |
||||
* from the underlying data |
||||
* |
||||
* @param offset The (zero-based) offset of the byte to retrieve |
||||
* |
||||
* @return the requested byte |
||||
*/ |
||||
public byte get(int offset) { |
||||
assert (isInitialized()); |
||||
return get0(nativeHandle_, offset); |
||||
} |
||||
|
||||
/** |
||||
* Clears the backing slice |
||||
*/ |
||||
public void clear() { |
||||
assert (isInitialized()); |
||||
clear0(nativeHandle_); |
||||
} |
||||
|
||||
/** |
||||
* Drops the specified n |
||||
* number of bytes from the start |
||||
* of the backing slice |
||||
* |
||||
* @param n The number of bytes to drop |
||||
*/ |
||||
public void removePrefix(final int n) { |
||||
assert (isInitialized()); |
||||
removePrefix0(nativeHandle_, n); |
||||
} |
||||
|
||||
private native void createNewDirectSlice0(ByteBuffer data, int length); |
||||
private native void createNewDirectSlice1(ByteBuffer data); |
||||
@Override protected final native ByteBuffer data0(long handle); |
||||
private native byte get0(long handle, int offset); |
||||
private native void clear0(long handle); |
||||
private native void removePrefix0(long handle, int length); |
||||
} |
@ -0,0 +1,61 @@ |
||||
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
package org.rocksdb; |
||||
|
||||
/** |
||||
* Base class for slices which will receive |
||||
* byte[] based access to the underlying data. |
||||
* |
||||
* byte[] backed slices typically perform better with |
||||
* small keys and values. When using larger keys and |
||||
* values consider using @see org.rocksdb.DirectSlice |
||||
*/ |
||||
public class Slice extends AbstractSlice<byte[]> { |
||||
|
||||
/** |
||||
* Called from JNI to construct a new Java Slice |
||||
* without an underlying C++ object set |
||||
* at creation time. |
||||
*/ |
||||
private Slice() { |
||||
super(); |
||||
disOwnNativeHandle(); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a slice |
||||
* where the data is taken from |
||||
* a String. |
||||
*/ |
||||
public Slice(final String str) { |
||||
super(); |
||||
createNewSliceFromString(str); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a slice |
||||
* where the data is a copy of |
||||
* the byte array from a specific offset. |
||||
*/ |
||||
public Slice(final byte[] data, final int offset) { |
||||
super(); |
||||
createNewSlice0(data, offset); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a slice |
||||
* where the data is a copy of |
||||
* the byte array. |
||||
*/ |
||||
public Slice(final byte[] data) { |
||||
super(); |
||||
createNewSlice1(data); |
||||
} |
||||
|
||||
@Override protected final native byte[] data0(long handle); |
||||
private native void createNewSlice0(byte[] data, int length); |
||||
private native void createNewSlice1(byte[] data); |
||||
} |
@ -0,0 +1,64 @@ |
||||
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
// This file implements the "bridge" between Java and C++ for
|
||||
// rocksdb::Comparator.
|
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <jni.h> |
||||
#include <string> |
||||
#include <functional> |
||||
|
||||
#include "include/org_rocksdb_AbstractComparator.h" |
||||
#include "include/org_rocksdb_Comparator.h" |
||||
#include "include/org_rocksdb_DirectComparator.h" |
||||
#include "rocksjni/comparatorjnicallback.h" |
||||
#include "rocksjni/portal.h" |
||||
|
||||
//<editor-fold desc="org.rocksdb.AbstractComparator>
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_AbstractComparator |
||||
* Method: disposeInternal |
||||
* Signature: (J)V |
||||
*/ |
||||
void Java_org_rocksdb_AbstractComparator_disposeInternal( |
||||
JNIEnv* env, jobject jobj, jlong handle) { |
||||
delete reinterpret_cast<rocksdb::BaseComparatorJniCallback*>(handle); |
||||
} |
||||
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold desc="org.rocksdb.Comparator>
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Comparator |
||||
* Method: createNewComparator0 |
||||
* Signature: ()V |
||||
*/ |
||||
void Java_org_rocksdb_Comparator_createNewComparator0( |
||||
JNIEnv* env, jobject jobj) { |
||||
const rocksdb::ComparatorJniCallback* c = new rocksdb::ComparatorJniCallback(env, jobj); |
||||
rocksdb::AbstractComparatorJni::setHandle(env, jobj, c); |
||||
} |
||||
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold desc="org.rocksdb.DirectComparator>
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_DirectComparator |
||||
* Method: createNewDirectComparator0 |
||||
* Signature: ()V |
||||
*/ |
||||
void Java_org_rocksdb_DirectComparator_createNewDirectComparator0( |
||||
JNIEnv* env, jobject jobj) { |
||||
const rocksdb::DirectComparatorJniCallback* c = new rocksdb::DirectComparatorJniCallback(env, jobj); |
||||
rocksdb::AbstractComparatorJni::setHandle(env, jobj, c); |
||||
} |
||||
|
||||
//</editor-fold>
|
||||
|
@ -0,0 +1,148 @@ |
||||
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
// This file implements the callback "bridge" between Java and C++ for
|
||||
// rocksdb::Comparator.
|
||||
|
||||
#include "rocksjni/comparatorjnicallback.h" |
||||
#include "portal.h" |
||||
|
||||
namespace rocksdb { |
||||
BaseComparatorJniCallback::BaseComparatorJniCallback( |
||||
JNIEnv* env, jobject jComparator) { |
||||
|
||||
// Note: Comparator methods may be accessed by multiple threads,
|
||||
// so we ref the jvm not the env
|
||||
const jint rs = env->GetJavaVM(&m_jvm); |
||||
assert(rs == JNI_OK); |
||||
|
||||
// Note: we want to access the Java Comparator instance
|
||||
// across multiple method calls, so we create a global ref
|
||||
m_jComparator = env->NewGlobalRef(jComparator); |
||||
|
||||
// Note: The name of a Comparator will not change during it's lifetime,
|
||||
// so we cache it in a global var
|
||||
jmethodID jNameMethodId = AbstractComparatorJni::getNameMethodId(env); |
||||
jstring jsName = (jstring)env->CallObjectMethod(m_jComparator, jNameMethodId); |
||||
m_name = JniUtil::copyString(env, jsName); //also releases jsName
|
||||
|
||||
m_jCompareMethodId = AbstractComparatorJni::getCompareMethodId(env); |
||||
m_jFindShortestSeparatorMethodId = AbstractComparatorJni::getFindShortestSeparatorMethodId(env); |
||||
m_jFindShortSuccessorMethodId = AbstractComparatorJni::getFindShortSuccessorMethodId(env); |
||||
} |
||||
|
||||
/**
|
||||
* Attach/Get a JNIEnv for the current native thread |
||||
*/ |
||||
JNIEnv* BaseComparatorJniCallback::getJniEnv() const { |
||||
JNIEnv *env; |
||||
jint rs = m_jvm->AttachCurrentThread((void **)&env, NULL); |
||||
assert(rs == JNI_OK); |
||||
return env; |
||||
}; |
||||
|
||||
const char* BaseComparatorJniCallback::Name() const { |
||||
return m_name.c_str(); |
||||
} |
||||
|
||||
int BaseComparatorJniCallback::Compare(const Slice& a, const Slice& b) const { |
||||
|
||||
JNIEnv* m_env = getJniEnv(); |
||||
|
||||
AbstractSliceJni::setHandle(m_env, m_jSliceA, &a); |
||||
AbstractSliceJni::setHandle(m_env, m_jSliceB, &b); |
||||
|
||||
jint result = m_env->CallIntMethod(m_jComparator, m_jCompareMethodId, m_jSliceA, m_jSliceB); |
||||
|
||||
m_jvm->DetachCurrentThread(); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
void BaseComparatorJniCallback::FindShortestSeparator(std::string* start, const Slice& limit) const { |
||||
|
||||
if (start == nullptr) { |
||||
return; |
||||
} |
||||
|
||||
JNIEnv* m_env = getJniEnv(); |
||||
|
||||
const char* startUtf = start->c_str(); |
||||
jstring jsStart = m_env->NewStringUTF(startUtf); |
||||
|
||||
AbstractSliceJni::setHandle(m_env, m_jSliceLimit, &limit); |
||||
|
||||
jstring jsResultStart = (jstring)m_env->CallObjectMethod(m_jComparator, m_jFindShortestSeparatorMethodId, jsStart, m_jSliceLimit); |
||||
|
||||
m_env->DeleteLocalRef(jsStart); |
||||
|
||||
if(jsResultStart != nullptr) { |
||||
//update start with result
|
||||
*start = JniUtil::copyString(m_env, jsResultStart); //also releases jsResultStart
|
||||
} |
||||
|
||||
m_jvm->DetachCurrentThread(); |
||||
} |
||||
|
||||
void BaseComparatorJniCallback::FindShortSuccessor(std::string* key) const { |
||||
|
||||
if (key == nullptr) { |
||||
return; |
||||
} |
||||
|
||||
JNIEnv* m_env = getJniEnv(); |
||||
|
||||
const char* keyUtf = key->c_str(); |
||||
jstring jsKey = m_env->NewStringUTF(keyUtf); |
||||
|
||||
jstring jsResultKey = (jstring)m_env->CallObjectMethod(m_jComparator, m_jFindShortSuccessorMethodId, jsKey); |
||||
|
||||
m_env->DeleteLocalRef(jsKey); |
||||
|
||||
if(jsResultKey != nullptr) { |
||||
//update key with result
|
||||
*key = JniUtil::copyString(m_env, jsResultKey); //also releases jsResultKey
|
||||
} |
||||
|
||||
m_jvm->DetachCurrentThread(); |
||||
} |
||||
|
||||
BaseComparatorJniCallback::~BaseComparatorJniCallback() { |
||||
|
||||
// NOTE: we do not need to delete m_name here,
|
||||
// I am not yet sure why, but doing so causes the error:
|
||||
// java(13051,0x109f54000) malloc: *** error for object 0x109f52fa9: pointer being freed was not allocated
|
||||
// *** set a breakpoint in malloc_error_break to debug
|
||||
//delete[] m_name;
|
||||
|
||||
JNIEnv* m_env = getJniEnv(); |
||||
|
||||
m_env->DeleteGlobalRef(m_jComparator); |
||||
m_env->DeleteGlobalRef(m_jSliceA); |
||||
m_env->DeleteGlobalRef(m_jSliceB); |
||||
m_env->DeleteGlobalRef(m_jSliceLimit); |
||||
|
||||
// Note: do not need to explicitly detach, as this function is effectively
|
||||
// called from the Java class's disposeInternal method, and so already
|
||||
// has an attached thread, getJniEnv above is just a no-op Attach to get the env
|
||||
//jvm->DetachCurrentThread();
|
||||
} |
||||
|
||||
ComparatorJniCallback::ComparatorJniCallback( |
||||
JNIEnv* env, jobject jComparator) : BaseComparatorJniCallback(env, jComparator) { |
||||
|
||||
m_jSliceA = env->NewGlobalRef(SliceJni::construct0(env)); |
||||
m_jSliceB = env->NewGlobalRef(SliceJni::construct0(env)); |
||||
m_jSliceLimit = env->NewGlobalRef(SliceJni::construct0(env)); |
||||
} |
||||
|
||||
DirectComparatorJniCallback::DirectComparatorJniCallback( |
||||
JNIEnv* env, jobject jComparator) : BaseComparatorJniCallback(env, jComparator) { |
||||
|
||||
m_jSliceA = env->NewGlobalRef(DirectSliceJni::construct0(env)); |
||||
m_jSliceB = env->NewGlobalRef(DirectSliceJni::construct0(env)); |
||||
m_jSliceLimit = env->NewGlobalRef(DirectSliceJni::construct0(env)); |
||||
} |
||||
} // namespace rocksdb
|
@ -0,0 +1,52 @@ |
||||
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
// This file implements the callback "bridge" between Java and C++ for
|
||||
// rocksdb::Comparator and rocksdb::DirectComparator.
|
||||
|
||||
#ifndef JAVA_ROCKSJNI_COMPARATORJNICALLBACK_H_ |
||||
#define JAVA_ROCKSJNI_COMPARATORJNICALLBACK_H_ |
||||
|
||||
#include <jni.h> |
||||
#include "rocksdb/comparator.h" |
||||
#include "rocksdb/slice.h" |
||||
|
||||
namespace rocksdb { |
||||
class BaseComparatorJniCallback : public Comparator { |
||||
public: |
||||
BaseComparatorJniCallback(JNIEnv* env, jobject jComparator); |
||||
virtual ~BaseComparatorJniCallback(); |
||||
virtual const char* Name() const; |
||||
virtual int Compare(const Slice& a, const Slice& b) const; |
||||
virtual void FindShortestSeparator(std::string* start, const Slice& limit) const; |
||||
virtual void FindShortSuccessor(std::string* key) const; |
||||
|
||||
private: |
||||
JavaVM* m_jvm; |
||||
jobject m_jComparator; |
||||
std::string m_name; |
||||
jmethodID m_jCompareMethodId; |
||||
jmethodID m_jFindShortestSeparatorMethodId; |
||||
jmethodID m_jFindShortSuccessorMethodId; |
||||
JNIEnv* getJniEnv() const; |
||||
|
||||
protected: |
||||
jobject m_jSliceA; |
||||
jobject m_jSliceB; |
||||
jobject m_jSliceLimit; |
||||
}; |
||||
|
||||
class ComparatorJniCallback : public BaseComparatorJniCallback { |
||||
public: |
||||
ComparatorJniCallback(JNIEnv* env, jobject jComparator); |
||||
}; |
||||
|
||||
class DirectComparatorJniCallback : public BaseComparatorJniCallback { |
||||
public: |
||||
DirectComparatorJniCallback(JNIEnv* env, jobject jComparator); |
||||
}; |
||||
} // namespace rocksdb
|
||||
|
||||
#endif // JAVA_ROCKSJNI_COMPARATORJNICALLBACK_H_
|
@ -0,0 +1,231 @@ |
||||
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
// This file implements the "bridge" between Java and C++ for
|
||||
// rocksdb::Slice.
|
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <jni.h> |
||||
#include <string> |
||||
|
||||
#include "include/org_rocksdb_AbstractSlice.h" |
||||
#include "include/org_rocksdb_Slice.h" |
||||
#include "include/org_rocksdb_DirectSlice.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;)V |
||||
*/ |
||||
void Java_org_rocksdb_AbstractSlice_createNewSliceFromString( |
||||
JNIEnv* env, jobject jobj, jstring str) { |
||||
const std::string s = rocksdb::JniUtil::copyString(env, str); |
||||
const rocksdb::Slice* slice = new rocksdb::Slice(s); |
||||
rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); |
||||
} |
||||
|
||||
/*
|
||||
* Class: org_rocksdb_AbstractSlice |
||||
* Method: size0 |
||||
* Signature: (J)I |
||||
*/ |
||||
jint Java_org_rocksdb_AbstractSlice_size0( |
||||
JNIEnv* env, jobject jobj, jlong handle) { |
||||
const rocksdb::Slice* slice = reinterpret_cast<rocksdb::Slice*>(handle); |
||||
return slice->size(); |
||||
} |
||||
|
||||
/*
|
||||
* Class: org_rocksdb_AbstractSlice |
||||
* Method: empty0 |
||||
* Signature: (J)Z |
||||
*/ |
||||
jboolean Java_org_rocksdb_AbstractSlice_empty0( |
||||
JNIEnv* env, jobject jobj, jlong handle) { |
||||
const rocksdb::Slice* 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 rocksdb::Slice* 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 rocksdb::Slice* slice = reinterpret_cast<rocksdb::Slice*>(handle); |
||||
const rocksdb::Slice* 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 rocksdb::Slice* slice = reinterpret_cast<rocksdb::Slice*>(handle); |
||||
const rocksdb::Slice* 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)V |
||||
*/ |
||||
void Java_org_rocksdb_Slice_createNewSlice0( |
||||
JNIEnv * env, jobject jobj, jbyteArray data, jint offset) { |
||||
|
||||
const jsize dataSize = env->GetArrayLength(data); |
||||
const int len = dataSize - offset; |
||||
//jbyte ptrData[len];
|
||||
jbyte* ptrData = new jbyte[len]; |
||||
env->GetByteArrayRegion(data, offset, len, ptrData); |
||||
|
||||
const rocksdb::Slice* slice = new rocksdb::Slice((const char*)ptrData, len); |
||||
rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); |
||||
|
||||
} |
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Slice |
||||
* Method: createNewSlice1 |
||||
* Signature: ([B)V |
||||
*/ |
||||
void Java_org_rocksdb_Slice_createNewSlice1( |
||||
JNIEnv * env, jobject jobj, jbyteArray data) { |
||||
|
||||
jboolean isCopy; |
||||
jbyte* ptrData = env->GetByteArrayElements(data, &isCopy); |
||||
|
||||
const rocksdb::Slice* slice = new rocksdb::Slice((const char*)ptrData, env->GetArrayLength(data)); |
||||
rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); |
||||
|
||||
env->ReleaseByteArrayElements(data, ptrData, JNI_COMMIT); |
||||
|
||||
//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?
|
||||
} |
||||
|
||||
/*
|
||||
* Class: org_rocksdb_Slice |
||||
* Method: data0 |
||||
* Signature: (J)[B |
||||
*/ |
||||
jbyteArray Java_org_rocksdb_Slice_data0( |
||||
JNIEnv* env, jobject jobj, jlong handle) { |
||||
const rocksdb::Slice* slice = reinterpret_cast<rocksdb::Slice*>(handle); |
||||
const int len = slice->size(); |
||||
const jbyteArray data = env->NewByteArray(len); |
||||
env->SetByteArrayRegion(data, 0, len, (jbyte*)slice->data()); |
||||
return data; |
||||
} |
||||
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold desc="org.rocksdb.DirectSlice>
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_DirectSlice |
||||
* Method: createNewDirectSlice0 |
||||
* Signature: (Ljava/nio/ByteBuffer;I)V |
||||
*/ |
||||
void Java_org_rocksdb_DirectSlice_createNewDirectSlice0( |
||||
JNIEnv* env, jobject jobj, jobject data, jint length) { |
||||
const char* ptrData = (char*)env->GetDirectBufferAddress(data); |
||||
const rocksdb::Slice* slice = new rocksdb::Slice(ptrData, length); |
||||
rocksdb::AbstractSliceJni::setHandle(env, jobj, slice); |
||||
} |
||||
|
||||
/*
|
||||
* Class: org_rocksdb_DirectSlice |
||||
* Method: createNewDirectSlice1 |
||||
* Signature: (Ljava/nio/ByteBuffer;)V |
||||
*/ |
||||
void Java_org_rocksdb_DirectSlice_createNewDirectSlice1( |
||||
JNIEnv* env, jobject jobj, jobject data) { |
||||
const char* ptrData = (char*)env->GetDirectBufferAddress(data); |
||||
const rocksdb::Slice* slice = new rocksdb::Slice(ptrData); |
||||
rocksdb::AbstractSliceJni::setHandle(env, jobj, 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 rocksdb::Slice* slice = reinterpret_cast<rocksdb::Slice*>(handle); |
||||
return env->NewDirectByteBuffer((void*)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) { |
||||
rocksdb::Slice* slice = reinterpret_cast<rocksdb::Slice*>(handle); |
||||
return (*slice)[offset]; |
||||
} |
||||
|
||||
/*
|
||||
* Class: org_rocksdb_DirectSlice |
||||
* Method: clear0 |
||||
* Signature: (J)V |
||||
*/ |
||||
void Java_org_rocksdb_DirectSlice_clear0( |
||||
JNIEnv* env, jobject jobj, jlong handle) { |
||||
rocksdb::Slice* slice = reinterpret_cast<rocksdb::Slice*>(handle); |
||||
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) { |
||||
rocksdb::Slice* slice = reinterpret_cast<rocksdb::Slice*>(handle); |
||||
slice->remove_prefix(length); |
||||
} |
||||
|
||||
//</editor-fold>
|
Loading…
Reference in new issue