mirror of
https://github.com/facebook/rocksdb.git
synced 2024-11-26 16:30:56 +00:00
Feature - Implement Java API for Comparator and Slice. Allows use of
either byte[] or DirectByteBuffer for accessing underlying data.
This commit is contained in:
parent
700f6ec3ff
commit
d6fe8dacc8
|
@ -1,4 +1,4 @@
|
||||||
NATIVE_JAVA_CLASSES = org.rocksdb.RocksDB org.rocksdb.Options org.rocksdb.WriteBatch org.rocksdb.WriteBatchInternal org.rocksdb.WriteBatchTest org.rocksdb.WriteOptions org.rocksdb.BackupableDB org.rocksdb.BackupableDBOptions org.rocksdb.Statistics org.rocksdb.RocksIterator org.rocksdb.VectorMemTableConfig org.rocksdb.SkipListMemTableConfig org.rocksdb.HashLinkedListMemTableConfig org.rocksdb.HashSkipListMemTableConfig org.rocksdb.PlainTableConfig org.rocksdb.BlockBasedTableConfig org.rocksdb.ReadOptions org.rocksdb.Filter org.rocksdb.BloomFilter org.rocksdb.RestoreOptions org.rocksdb.RestoreBackupableDB org.rocksdb.RocksEnv org.rocksdb.GenericRateLimiterConfig org.rocksdb.ColumnFamilyHandle
|
NATIVE_JAVA_CLASSES = org.rocksdb.RocksDB org.rocksdb.Options org.rocksdb.WriteBatch org.rocksdb.WriteBatchInternal org.rocksdb.WriteBatchTest org.rocksdb.WriteOptions org.rocksdb.BackupableDB org.rocksdb.BackupableDBOptions org.rocksdb.Statistics org.rocksdb.RocksIterator org.rocksdb.VectorMemTableConfig org.rocksdb.SkipListMemTableConfig org.rocksdb.HashLinkedListMemTableConfig org.rocksdb.HashSkipListMemTableConfig org.rocksdb.PlainTableConfig org.rocksdb.BlockBasedTableConfig org.rocksdb.ReadOptions org.rocksdb.Filter org.rocksdb.BloomFilter org.rocksdb.AbstractComparator org.rocksdb.Comparator org.rocksdb.DirectComparator org.rocksdb.AbstractSlice org.rocksdb.Slice org.rocksdb.DirectSlice org.rocksdb.RestoreOptions org.rocksdb.RestoreBackupableDB org.rocksdb.RocksEnv org.rocksdb.GenericRateLimiterConfig org.rocksdb.ColumnFamilyHandle
|
||||||
|
|
||||||
ROCKSDB_MAJOR = $(shell egrep "ROCKSDB_MAJOR.[0-9]" ../include/rocksdb/version.h | cut -d ' ' -f 3)
|
ROCKSDB_MAJOR = $(shell egrep "ROCKSDB_MAJOR.[0-9]" ../include/rocksdb/version.h | cut -d ' ' -f 3)
|
||||||
ROCKSDB_MINOR = $(shell egrep "ROCKSDB_MINOR.[0-9]" ../include/rocksdb/version.h | cut -d ' ' -f 3)
|
ROCKSDB_MINOR = $(shell egrep "ROCKSDB_MINOR.[0-9]" ../include/rocksdb/version.h | cut -d ' ' -f 3)
|
||||||
|
|
81
java/org/rocksdb/AbstractComparator.java
Normal file
81
java/org/rocksdb/AbstractComparator.java
Normal file
|
@ -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);
|
||||||
|
}
|
156
java/org/rocksdb/AbstractSlice.java
Normal file
156
java/org/rocksdb/AbstractSlice.java
Normal file
|
@ -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);
|
||||||
|
|
||||||
|
}
|
25
java/org/rocksdb/Comparator.java
Normal file
25
java/org/rocksdb/Comparator.java
Normal file
|
@ -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();
|
||||||
|
}
|
25
java/org/rocksdb/DirectComparator.java
Normal file
25
java/org/rocksdb/DirectComparator.java
Normal file
|
@ -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();
|
||||||
|
}
|
99
java/org/rocksdb/DirectSlice.java
Normal file
99
java/org/rocksdb/DirectSlice.java
Normal file
|
@ -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);
|
||||||
|
}
|
|
@ -193,6 +193,27 @@ public class Options extends RocksObject {
|
||||||
return maxWriteBufferNumber(nativeHandle_);
|
return maxWriteBufferNumber(nativeHandle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the specified comparator for key ordering.
|
||||||
|
*
|
||||||
|
* Comparator should not be disposed before options instances using this comparator is
|
||||||
|
* disposed. If dispose() function is not called, then comparator object will be
|
||||||
|
* GC'd automatically.
|
||||||
|
*
|
||||||
|
* Comparator instance can be re-used in multiple options instances.
|
||||||
|
*
|
||||||
|
* @param comparator java instance.
|
||||||
|
* @return the instance of the current Options.
|
||||||
|
* @see RocksDB.open()
|
||||||
|
*/
|
||||||
|
public Options setComparator(AbstractComparator comparator) {
|
||||||
|
assert (isInitialized());
|
||||||
|
setComparatorHandle(nativeHandle_, comparator.nativeHandle_);
|
||||||
|
comparator_ = comparator;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
private native void setComparatorHandle(long optHandle, long comparatorHandle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true, an error will be thrown during RocksDB.open() if the
|
* If true, an error will be thrown during RocksDB.open() if the
|
||||||
* database already exists.
|
* database already exists.
|
||||||
|
@ -2282,6 +2303,7 @@ public class Options extends RocksObject {
|
||||||
|
|
||||||
long cacheSize_;
|
long cacheSize_;
|
||||||
int numShardBits_;
|
int numShardBits_;
|
||||||
|
AbstractComparator comparator_;
|
||||||
RocksEnv env_;
|
RocksEnv env_;
|
||||||
MemTableConfig memTableConfig_;
|
MemTableConfig memTableConfig_;
|
||||||
TableFormatConfig tableFormatConfig_;
|
TableFormatConfig tableFormatConfig_;
|
||||||
|
|
61
java/org/rocksdb/Slice.java
Normal file
61
java/org/rocksdb/Slice.java
Normal file
|
@ -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);
|
||||||
|
}
|
64
java/rocksjni/comparator.cc
Normal file
64
java/rocksjni/comparator.cc
Normal file
|
@ -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>
|
||||||
|
|
148
java/rocksjni/comparatorjnicallback.cc
Normal file
148
java/rocksjni/comparatorjnicallback.cc
Normal file
|
@ -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
|
52
java/rocksjni/comparatorjnicallback.h
Normal file
52
java/rocksjni/comparatorjnicallback.h
Normal file
|
@ -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_
|
|
@ -164,6 +164,17 @@ jlong Java_org_rocksdb_Options_statisticsPtr(
|
||||||
return reinterpret_cast<jlong>(st);
|
return reinterpret_cast<jlong>(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_rocksdb_Options
|
||||||
|
* Method: setComparatorHandle
|
||||||
|
* Signature: (JJ)V
|
||||||
|
*/
|
||||||
|
void Java_org_rocksdb_Options_setComparatorHandle(
|
||||||
|
JNIEnv* env, jobject jobj, jlong jopt_handle, jlong jcomparator_handle) {
|
||||||
|
reinterpret_cast<rocksdb::Options*>(jopt_handle)->comparator =
|
||||||
|
reinterpret_cast<rocksdb::Comparator*>(jcomparator_handle);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: org_rocksdb_Options
|
* Class: org_rocksdb_Options
|
||||||
* Method: maxWriteBufferNumber
|
* Method: maxWriteBufferNumber
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "rocksdb/filter_policy.h"
|
#include "rocksdb/filter_policy.h"
|
||||||
#include "rocksdb/status.h"
|
#include "rocksdb/status.h"
|
||||||
#include "rocksdb/utilities/backupable_db.h"
|
#include "rocksdb/utilities/backupable_db.h"
|
||||||
|
#include "rocksjni/comparatorjnicallback.h"
|
||||||
|
|
||||||
namespace rocksdb {
|
namespace rocksdb {
|
||||||
|
|
||||||
|
@ -362,6 +363,136 @@ class ColumnFamilyHandleJni {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class AbstractComparatorJni {
|
||||||
|
public:
|
||||||
|
// Get the java class id of org.rocksdb.Comparator.
|
||||||
|
static jclass getJClass(JNIEnv* env) {
|
||||||
|
jclass jclazz = env->FindClass("org/rocksdb/AbstractComparator");
|
||||||
|
assert(jclazz != nullptr);
|
||||||
|
return jclazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the field id of the member variable of org.rocksdb.Comparator
|
||||||
|
// that stores the pointer to rocksdb::Comparator.
|
||||||
|
static jfieldID getHandleFieldID(JNIEnv* env) {
|
||||||
|
static jfieldID fid = env->GetFieldID(
|
||||||
|
getJClass(env), "nativeHandle_", "J");
|
||||||
|
assert(fid != nullptr);
|
||||||
|
return fid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the java method `name` of org.rocksdb.Comparator.
|
||||||
|
static jmethodID getNameMethodId(JNIEnv* env) {
|
||||||
|
static jmethodID mid = env->GetMethodID(
|
||||||
|
getJClass(env), "name", "()Ljava/lang/String;");
|
||||||
|
assert(mid != nullptr);
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the java method `compare` of org.rocksdb.Comparator.
|
||||||
|
static jmethodID getCompareMethodId(JNIEnv* env) {
|
||||||
|
static jmethodID mid = env->GetMethodID(
|
||||||
|
getJClass(env), "compare", "(Lorg/rocksdb/AbstractSlice;Lorg/rocksdb/AbstractSlice;)I");
|
||||||
|
assert(mid != nullptr);
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the java method `findShortestSeparator` of org.rocksdb.Comparator.
|
||||||
|
static jmethodID getFindShortestSeparatorMethodId(JNIEnv* env) {
|
||||||
|
static jmethodID mid = env->GetMethodID(
|
||||||
|
getJClass(env), "findShortestSeparator", "(Ljava/lang/String;Lorg/rocksdb/AbstractSlice;)Ljava/lang/String;");
|
||||||
|
assert(mid != nullptr);
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the java method `findShortSuccessor` of org.rocksdb.Comparator.
|
||||||
|
static jmethodID getFindShortSuccessorMethodId(JNIEnv* env) {
|
||||||
|
static jmethodID mid = env->GetMethodID(
|
||||||
|
getJClass(env), "findShortSuccessor", "(Ljava/lang/String;)Ljava/lang/String;");
|
||||||
|
assert(mid != nullptr);
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the pointer to ComparatorJniCallback.
|
||||||
|
static rocksdb::BaseComparatorJniCallback* getHandle(JNIEnv* env, jobject jobj) {
|
||||||
|
return reinterpret_cast<rocksdb::BaseComparatorJniCallback*>(
|
||||||
|
env->GetLongField(jobj, getHandleFieldID(env)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass the ComparatorJniCallback pointer to the java side.
|
||||||
|
static void setHandle(
|
||||||
|
JNIEnv* env, jobject jobj, const rocksdb::BaseComparatorJniCallback* op) {
|
||||||
|
env->SetLongField(
|
||||||
|
jobj, getHandleFieldID(env),
|
||||||
|
reinterpret_cast<jlong>(op));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AbstractSliceJni {
|
||||||
|
public:
|
||||||
|
// Get the java class id of org.rocksdb.Slice.
|
||||||
|
static jclass getJClass(JNIEnv* env) {
|
||||||
|
jclass jclazz = env->FindClass("org/rocksdb/AbstractSlice");
|
||||||
|
assert(jclazz != nullptr);
|
||||||
|
return jclazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the field id of the member variable of org.rocksdb.Slice
|
||||||
|
// that stores the pointer to rocksdb::Slice.
|
||||||
|
static jfieldID getHandleFieldID(JNIEnv* env) {
|
||||||
|
static jfieldID fid = env->GetFieldID(
|
||||||
|
getJClass(env), "nativeHandle_", "J");
|
||||||
|
assert(fid != nullptr);
|
||||||
|
return fid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the pointer to Slice.
|
||||||
|
static rocksdb::Slice* getHandle(JNIEnv* env, jobject jobj) {
|
||||||
|
return reinterpret_cast<rocksdb::Slice*>(
|
||||||
|
env->GetLongField(jobj, getHandleFieldID(env)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass the Slice pointer to the java side.
|
||||||
|
static void setHandle(
|
||||||
|
JNIEnv* env, jobject jobj, const rocksdb::Slice* op) {
|
||||||
|
env->SetLongField(
|
||||||
|
jobj, getHandleFieldID(env),
|
||||||
|
reinterpret_cast<jlong>(op));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SliceJni {
|
||||||
|
public:
|
||||||
|
// Get the java class id of org.rocksdb.Slice.
|
||||||
|
static jclass getJClass(JNIEnv* env) {
|
||||||
|
jclass jclazz = env->FindClass("org/rocksdb/Slice");
|
||||||
|
assert(jclazz != nullptr);
|
||||||
|
return jclazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
static jobject construct0(JNIEnv* env) {
|
||||||
|
static jmethodID mid = env->GetMethodID(getJClass(env), "<init>", "()V");
|
||||||
|
assert(mid != nullptr);
|
||||||
|
return env->NewObject(getJClass(env), mid);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DirectSliceJni {
|
||||||
|
public:
|
||||||
|
// Get the java class id of org.rocksdb.DirectSlice.
|
||||||
|
static jclass getJClass(JNIEnv* env) {
|
||||||
|
jclass jclazz = env->FindClass("org/rocksdb/DirectSlice");
|
||||||
|
assert(jclazz != nullptr);
|
||||||
|
return jclazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
static jobject construct0(JNIEnv* env) {
|
||||||
|
static jmethodID mid = env->GetMethodID(getJClass(env), "<init>", "()V");
|
||||||
|
assert(mid != nullptr);
|
||||||
|
return env->NewObject(getJClass(env), mid);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class ListJni {
|
class ListJni {
|
||||||
public:
|
public:
|
||||||
// Get the java class id of java.util.List.
|
// Get the java class id of java.util.List.
|
||||||
|
@ -425,5 +556,21 @@ class ListJni {
|
||||||
return mid;
|
return mid;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class JniUtil {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies a jstring to a std::string
|
||||||
|
* and releases the original jstring
|
||||||
|
*/
|
||||||
|
static std::string copyString(JNIEnv* env, jstring js) {
|
||||||
|
const char *utf = env->GetStringUTFChars(js, NULL);
|
||||||
|
std::string name(utf);
|
||||||
|
env->ReleaseStringUTFChars(js, utf);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace rocksdb
|
} // namespace rocksdb
|
||||||
#endif // JAVA_ROCKSJNI_PORTAL_H_
|
#endif // JAVA_ROCKSJNI_PORTAL_H_
|
||||||
|
|
231
java/rocksjni/slice.cc
Normal file
231
java/rocksjni/slice.cc
Normal file
|
@ -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 a new issue