32-Bit RocksJava resolution for jlong overflows

Summary:
This pull request solves the jlong overflow problem on 32-Bit machines as described in https://github.com/facebook/rocksdb/issues/278:

1. There is a new org.rocksdb.test.PlatformRandomHelper to assist in getting random values. For 32 Bit the getLong method is overriden by xpromaches code above. For 64 Bit it behaves as is.
2. The detection should be cross-platform (Windows is supported though it is not ported completely yet).
3. Every JNI method which sets jlong values must check if the value fits into size_t. If it overflows size_t a InvalidArgument Status object will be returned. If its ok a OK Status will be returned.
4. Setters which have this check will throw a RocksDBException if its no OK Status.

Additionally some other parts of code were corrected using the wrong type casts.

Test Plan:
make rocksdbjava
make jtest

Differential Revision: https://reviews.facebook.net/D24531
This commit is contained in:
fyrz 2014-10-09 23:16:41 +02:00
parent 833357402c
commit 4f5a687254
16 changed files with 317 additions and 134 deletions

View File

@ -35,13 +35,18 @@ public class RocksDBSample {
assert(db == null);
}
options.setCreateIfMissing(true)
.createStatistics()
.setWriteBufferSize(8 * SizeUnit.KB)
.setMaxWriteBufferNumber(3)
.setMaxBackgroundCompactions(10)
.setCompressionType(CompressionType.SNAPPY_COMPRESSION)
.setCompactionStyle(CompactionStyle.UNIVERSAL);
try {
options.setCreateIfMissing(true)
.createStatistics()
.setWriteBufferSize(8 * SizeUnit.KB)
.setMaxWriteBufferNumber(3)
.setMaxBackgroundCompactions(10)
.setCompressionType(CompressionType.SNAPPY_COMPRESSION)
.setCompactionStyle(CompactionStyle.UNIVERSAL);
} catch (RocksDBException e) {
assert(false);
}
Statistics stats = options.statisticsPtr();
assert(options.createIfMissing() == true);
@ -50,36 +55,38 @@ public class RocksDBSample {
assert(options.maxBackgroundCompactions() == 10);
assert(options.compressionType() == CompressionType.SNAPPY_COMPRESSION);
assert(options.compactionStyle() == CompactionStyle.UNIVERSAL);
try {
assert(options.memTableFactoryName().equals("SkipListFactory"));
options.setMemTableConfig(
new HashSkipListMemTableConfig()
.setHeight(4)
.setBranchingFactor(4)
.setBucketCount(2000000));
assert(options.memTableFactoryName().equals("HashSkipListRepFactory"));
assert(options.memTableFactoryName().equals("SkipListFactory"));
options.setMemTableConfig(
new HashSkipListMemTableConfig()
.setHeight(4)
.setBranchingFactor(4)
.setBucketCount(2000000));
assert(options.memTableFactoryName().equals("HashSkipListRepFactory"));
options.setMemTableConfig(
new HashLinkedListMemTableConfig()
.setBucketCount(100000));
assert(options.memTableFactoryName().equals("HashLinkedListRepFactory"));
options.setMemTableConfig(
new HashLinkedListMemTableConfig()
.setBucketCount(100000));
assert(options.memTableFactoryName().equals("HashLinkedListRepFactory"));
options.setMemTableConfig(
new VectorMemTableConfig().setReservedSize(10000));
assert(options.memTableFactoryName().equals("VectorRepFactory"));
options.setMemTableConfig(
new VectorMemTableConfig().setReservedSize(10000));
assert(options.memTableFactoryName().equals("VectorRepFactory"));
options.setMemTableConfig(new SkipListMemTableConfig());
assert(options.memTableFactoryName().equals("SkipListFactory"));
options.setMemTableConfig(new SkipListMemTableConfig());
assert(options.memTableFactoryName().equals("SkipListFactory"));
options.setTableFormatConfig(new PlainTableConfig());
// Plain-Table requires mmap read
options.setAllowMmapReads(true);
assert(options.tableFactoryName().equals("PlainTable"));
options.setRateLimiterConfig(new GenericRateLimiterConfig(10000000,
10000, 10));
options.setRateLimiterConfig(new GenericRateLimiterConfig(10000000));
options.setTableFormatConfig(new PlainTableConfig());
// Plain-Table requires mmap read
options.setAllowMmapReads(true);
assert(options.tableFactoryName().equals("PlainTable"));
options.setRateLimiterConfig(new GenericRateLimiterConfig(10000000,
10000, 10));
options.setRateLimiterConfig(new GenericRateLimiterConfig(10000000));
} catch (RocksDBException e) {
assert(false);
}
Filter bloomFilter = new BloomFilter(10);
BlockBasedTableConfig table_options = new BlockBasedTableConfig();
table_options.setBlockCacheSize(64 * SizeUnit.KB)

View File

@ -42,11 +42,13 @@ public class HashLinkedListMemTableConfig extends MemTableConfig {
return bucketCount_;
}
@Override protected long newMemTableFactoryHandle() {
@Override protected long newMemTableFactoryHandle()
throws RocksDBException {
return newMemTableFactoryHandle(bucketCount_);
}
private native long newMemTableFactoryHandle(long bucketCount);
private native long newMemTableFactoryHandle(long bucketCount)
throws RocksDBException;
private long bucketCount_;
}

View File

@ -83,13 +83,15 @@ public class HashSkipListMemTableConfig extends MemTableConfig {
return branchingFactor_;
}
@Override protected long newMemTableFactoryHandle() {
@Override protected long newMemTableFactoryHandle()
throws RocksDBException {
return newMemTableFactoryHandle(
bucketCount_, height_, branchingFactor_);
}
private native long newMemTableFactoryHandle(
long bucketCount, int height, int branchingFactor);
long bucketCount, int height, int branchingFactor)
throws RocksDBException;
private long bucketCount_;
private int branchingFactor_;

View File

@ -23,5 +23,6 @@ public abstract class MemTableConfig {
*
* @see Options#setMemTableConfig(MemTableConfig)
*/
abstract protected long newMemTableFactoryHandle();
abstract protected long newMemTableFactoryHandle()
throws RocksDBException;
}

View File

@ -118,8 +118,10 @@ public class Options extends RocksObject {
* @param writeBufferSize the size of write buffer.
* @return the instance of the current Options.
* @see org.rocksdb.RocksDB#open(Options, String)
* @throws RocksDBException
*/
public Options setWriteBufferSize(long writeBufferSize) {
public Options setWriteBufferSize(long writeBufferSize)
throws RocksDBException {
assert(isInitialized());
setWriteBufferSize(nativeHandle_, writeBufferSize);
return this;
@ -561,13 +563,16 @@ public class Options extends RocksObject {
*
* @param maxLogFileSize the maximum size of a info log file.
* @return the reference to the current option.
* @throws RocksDBException
*/
public Options setMaxLogFileSize(long maxLogFileSize) {
public Options setMaxLogFileSize(long maxLogFileSize)
throws RocksDBException {
assert(isInitialized());
setMaxLogFileSize(nativeHandle_, maxLogFileSize);
return this;
}
private native void setMaxLogFileSize(long handle, long maxLogFileSize);
private native void setMaxLogFileSize(long handle, long maxLogFileSize)
throws RocksDBException;
/**
* Returns the time interval for the info log file to roll (in seconds).
@ -591,14 +596,16 @@ public class Options extends RocksObject {
*
* @param logFileTimeToRoll the time interval in seconds.
* @return the reference to the current option.
* @throws RocksDBException
*/
public Options setLogFileTimeToRoll(long logFileTimeToRoll) {
public Options setLogFileTimeToRoll(long logFileTimeToRoll)
throws RocksDBException{
assert(isInitialized());
setLogFileTimeToRoll(nativeHandle_, logFileTimeToRoll);
return this;
}
private native void setLogFileTimeToRoll(
long handle, long logFileTimeToRoll);
long handle, long logFileTimeToRoll) throws RocksDBException;
/**
* Returns the maximum number of info log files to be kept.
@ -618,13 +625,16 @@ public class Options extends RocksObject {
*
* @param keepLogFileNum the maximum number of info log files to be kept.
* @return the reference to the current option.
* @throws RocksDBException
*/
public Options setKeepLogFileNum(long keepLogFileNum) {
public Options setKeepLogFileNum(long keepLogFileNum)
throws RocksDBException{
assert(isInitialized());
setKeepLogFileNum(nativeHandle_, keepLogFileNum);
return this;
}
private native void setKeepLogFileNum(long handle, long keepLogFileNum);
private native void setKeepLogFileNum(long handle, long keepLogFileNum)
throws RocksDBException;
/**
* Manifest file is rolled over on reaching this limit.
@ -844,14 +854,16 @@ public class Options extends RocksObject {
*
* @param size the size in byte
* @return the reference to the current option.
* @throws RocksDBException
*/
public Options setManifestPreallocationSize(long size) {
public Options setManifestPreallocationSize(long size)
throws RocksDBException {
assert(isInitialized());
setManifestPreallocationSize(nativeHandle_, size);
return this;
}
private native void setManifestPreallocationSize(
long handle, long size);
long handle, long size) throws RocksDBException;
/**
* Data being read from file storage may be buffered in the OS
@ -1110,8 +1122,10 @@ public class Options extends RocksObject {
*
* @param config the mem-table config.
* @return the instance of the current Options.
* @throws RocksDBException
*/
public Options setMemTableConfig(MemTableConfig config) {
public Options setMemTableConfig(MemTableConfig config)
throws RocksDBException {
setMemTableFactory(nativeHandle_, config.newMemTableFactoryHandle());
return this;
}
@ -1123,6 +1137,7 @@ public class Options extends RocksObject {
*
* @param config rate limiter config.
* @return the instance of the current Options.
* @throws RocksDBException
*/
public Options setRateLimiterConfig(RateLimiterConfig config) {
setRateLimiter(nativeHandle_, config.newRateLimiterHandle());
@ -1768,13 +1783,15 @@ public class Options extends RocksObject {
*
* @param arenaBlockSize the size of an arena block
* @return the reference to the current option.
* @throws RocksDBException
*/
public Options setArenaBlockSize(long arenaBlockSize) {
public Options setArenaBlockSize(long arenaBlockSize)
throws RocksDBException {
setArenaBlockSize(nativeHandle_, arenaBlockSize);
return this;
}
private native void setArenaBlockSize(
long handle, long arenaBlockSize);
long handle, long arenaBlockSize) throws RocksDBException;
/**
* Disable automatic compactions. Manual compactions can still
@ -1977,13 +1994,15 @@ public class Options extends RocksObject {
* @param inplaceUpdateNumLocks the number of locks used for
* inplace updates.
* @return the reference to the current option.
* @throws RocksDBException
*/
public Options setInplaceUpdateNumLocks(long inplaceUpdateNumLocks) {
public Options setInplaceUpdateNumLocks(long inplaceUpdateNumLocks)
throws RocksDBException {
setInplaceUpdateNumLocks(nativeHandle_, inplaceUpdateNumLocks);
return this;
}
private native void setInplaceUpdateNumLocks(
long handle, long inplaceUpdateNumLocks);
long handle, long inplaceUpdateNumLocks) throws RocksDBException;
/**
* Returns the number of bits used in the prefix bloom filter.
@ -2108,13 +2127,15 @@ public class Options extends RocksObject {
*
* @param maxSuccessiveMerges the maximum number of successive merges.
* @return the reference to the current option.
* @throws RocksDBException
*/
public Options setMaxSuccessiveMerges(long maxSuccessiveMerges) {
public Options setMaxSuccessiveMerges(long maxSuccessiveMerges)
throws RocksDBException {
setMaxSuccessiveMerges(nativeHandle_, maxSuccessiveMerges);
return this;
}
private native void setMaxSuccessiveMerges(
long handle, long maxSuccessiveMerges);
long handle, long maxSuccessiveMerges) throws RocksDBException;
/**
* The minimum number of write buffers that will be merged together
@ -2204,7 +2225,8 @@ public class Options extends RocksObject {
private native void disposeInternal(long handle);
private native void setCreateIfMissing(long handle, boolean flag);
private native boolean createIfMissing(long handle);
private native void setWriteBufferSize(long handle, long writeBufferSize);
private native void setWriteBufferSize(long handle, long writeBufferSize)
throws RocksDBException;
private native long writeBufferSize(long handle);
private native void setMaxWriteBufferNumber(
long handle, int maxWriteBufferNumber);

View File

@ -489,7 +489,7 @@ public class DbBenchmark {
options.setDisableWAL((Boolean)flags_.get(Flag.disable_wal));
}
private void prepareOptions(Options options) {
private void prepareOptions(Options options) throws RocksDBException {
if (!useExisting_) {
options.setCreateIfMissing(true);
} else {

View File

@ -7,15 +7,19 @@ package org.rocksdb.test;
import java.util.Random;
import org.rocksdb.RocksDB;
import org.rocksdb.RocksDBException;
import org.rocksdb.Options;
import org.rocksdb.test.PlatformRandomHelper;
public class OptionsTest {
static {
RocksDB.loadLibrary();
}
public static void main(String[] args) {
Options opt = new Options();
Random rand = new Random();
Random rand = PlatformRandomHelper.
getPlatformSpecificRandomFactory();
{ // CreateIfMissing test
boolean boolValue = rand.nextBoolean();
opt.setCreateIfMissing(boolValue);
@ -83,21 +87,34 @@ public class OptionsTest {
}
{ // MaxLogFileSize test
long longValue = rand.nextLong();
opt.setMaxLogFileSize(longValue);
assert(opt.maxLogFileSize() == longValue);
try {
long longValue = rand.nextLong();
opt.setMaxLogFileSize(longValue);
assert(opt.maxLogFileSize() == longValue);
} catch (RocksDBException e) {
System.out.println(e.getMessage());
assert(false);
}
}
{ // LogFileTimeToRoll test
long longValue = rand.nextLong();
opt.setLogFileTimeToRoll(longValue);
assert(opt.logFileTimeToRoll() == longValue);
try {
long longValue = rand.nextLong();
opt.setLogFileTimeToRoll(longValue);
assert(opt.logFileTimeToRoll() == longValue);
} catch (RocksDBException e) {
assert(false);
}
}
{ // KeepLogFileNum test
long longValue = rand.nextLong();
opt.setKeepLogFileNum(longValue);
assert(opt.keepLogFileNum() == longValue);
try {
long longValue = rand.nextLong();
opt.setKeepLogFileNum(longValue);
assert(opt.keepLogFileNum() == longValue);
} catch (RocksDBException e) {
assert(false);
}
}
{ // MaxManifestFileSize test
@ -125,9 +142,13 @@ public class OptionsTest {
}
{ // ManifestPreallocationSize test
long longValue = rand.nextLong();
opt.setManifestPreallocationSize(longValue);
assert(opt.manifestPreallocationSize() == longValue);
try {
long longValue = rand.nextLong();
opt.setManifestPreallocationSize(longValue);
assert(opt.manifestPreallocationSize() == longValue);
} catch (RocksDBException e) {
assert(false);
}
}
{ // AllowOsBuffer test
@ -185,9 +206,13 @@ public class OptionsTest {
}
{ // WriteBufferSize test
long longValue = rand.nextLong();
opt.setWriteBufferSize(longValue);
assert(opt.writeBufferSize() == longValue);
try {
long longValue = rand.nextLong();
opt.setWriteBufferSize(longValue);
assert(opt.writeBufferSize() == longValue);
} catch (RocksDBException e) {
assert(false);
}
}
{ // MaxWriteBufferNumber test
@ -293,9 +318,13 @@ public class OptionsTest {
}
{ // ArenaBlockSize test
long longValue = rand.nextLong();
opt.setArenaBlockSize(longValue);
assert(opt.arenaBlockSize() == longValue);
try {
long longValue = rand.nextLong();
opt.setArenaBlockSize(longValue);
assert(opt.arenaBlockSize() == longValue);
} catch (RocksDBException e) {
assert(false);
}
}
{ // DisableAutoCompactions test
@ -335,9 +364,13 @@ public class OptionsTest {
}
{ // InplaceUpdateNumLocks test
long longValue = rand.nextLong();
opt.setInplaceUpdateNumLocks(longValue);
assert(opt.inplaceUpdateNumLocks() == longValue);
try {
long longValue = rand.nextLong();
opt.setInplaceUpdateNumLocks(longValue);
assert(opt.inplaceUpdateNumLocks() == longValue);
} catch (RocksDBException e) {
assert(false);
}
}
{ // MemtablePrefixBloomBits test
@ -359,9 +392,13 @@ public class OptionsTest {
}
{ // MaxSuccessiveMerges test
long longValue = rand.nextLong();
opt.setMaxSuccessiveMerges(longValue);
assert(opt.maxSuccessiveMerges() == longValue);
try {
long longValue = rand.nextLong();
opt.setMaxSuccessiveMerges(longValue);
assert(opt.maxSuccessiveMerges() == longValue);
} catch (RocksDBException e){
assert(false);
}
}
{ // MinPartialMergeOperands test

View File

@ -0,0 +1,54 @@
// 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.test;
import java.util.Random;
/**
* Helper class to get the appropriate Random class instance dependent
* on the current platform architecture (32bit vs 64bit)
*/
public class PlatformRandomHelper {
/**
* Determine if OS is 32-Bit/64-Bit
*/
public static boolean isOs64Bit(){
boolean is64Bit = false;
if (System.getProperty("os.name").contains("Windows")) {
is64Bit = (System.getenv("ProgramFiles(x86)") != null);
} else {
is64Bit = (System.getProperty("os.arch").indexOf("64") != -1);
}
return is64Bit;
}
/**
* Factory to get a platform specific Random instance
*/
public static Random getPlatformSpecificRandomFactory(){
if (isOs64Bit()) {
return new Random();
}
return new Random32Bit();
}
/**
* Random32Bit is a class which overrides {@code nextLong} to
* provide random numbers which fit in size_t. This workaround
* is necessary because there is no unsigned_int < Java 8
*/
private static class Random32Bit extends Random {
@Override
public long nextLong(){
return this.nextInt(Integer.MAX_VALUE);
}
}
/**
* Utility class constructor
*/
private PlatformRandomHelper() { }
}

View File

@ -20,10 +20,15 @@
jlong Java_org_rocksdb_HashSkipListMemTableConfig_newMemTableFactoryHandle(
JNIEnv* env, jobject jobj, jlong jbucket_count,
jint jheight, jint jbranching_factor) {
return reinterpret_cast<jlong>(rocksdb::NewHashSkipListRepFactory(
rocksdb::jlong_to_size_t(jbucket_count),
static_cast<int32_t>(jheight),
static_cast<int32_t>(jbranching_factor)));
rocksdb::Status s = rocksdb::check_if_jlong_fits_size_t(jbucket_count);
if (s.ok()) {
return reinterpret_cast<jlong>(rocksdb::NewHashSkipListRepFactory(
static_cast<size_t>(jbucket_count),
static_cast<int32_t>(jheight),
static_cast<int32_t>(jbranching_factor)));
}
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
return 0;
}
/*
@ -33,8 +38,13 @@ jlong Java_org_rocksdb_HashSkipListMemTableConfig_newMemTableFactoryHandle(
*/
jlong Java_org_rocksdb_HashLinkedListMemTableConfig_newMemTableFactoryHandle(
JNIEnv* env, jobject jobj, jlong jbucket_count) {
return reinterpret_cast<jlong>(rocksdb::NewHashLinkListRepFactory(
rocksdb::jlong_to_size_t(jbucket_count)));
rocksdb::Status s = rocksdb::check_if_jlong_fits_size_t(jbucket_count);
if (s.ok()) {
return reinterpret_cast<jlong>(rocksdb::NewHashLinkListRepFactory(
static_cast<size_t>(jbucket_count)));
}
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
return 0;
}
/*
@ -44,8 +54,13 @@ jlong Java_org_rocksdb_HashLinkedListMemTableConfig_newMemTableFactoryHandle(
*/
jlong Java_org_rocksdb_VectorMemTableConfig_newMemTableFactoryHandle(
JNIEnv* env, jobject jobj, jlong jreserved_size) {
return reinterpret_cast<jlong>(new rocksdb::VectorRepFactory(
rocksdb::jlong_to_size_t(jreserved_size)));
rocksdb::Status s = rocksdb::check_if_jlong_fits_size_t(jreserved_size);
if (s.ok()) {
return reinterpret_cast<jlong>(new rocksdb::VectorRepFactory(
static_cast<size_t>(jreserved_size)));
}
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
return 0;
}
/*

View File

@ -71,7 +71,7 @@ jboolean Java_org_rocksdb_Options_createIfMissing(
*/
void Java_org_rocksdb_Options_setBuiltinComparator(
JNIEnv* env, jobject jobj, jlong jhandle, jint builtinComparator) {
switch (builtinComparator){
switch (builtinComparator) {
case 1:
reinterpret_cast<rocksdb::Options*>(jhandle)->comparator =
rocksdb::ReverseBytewiseComparator();
@ -90,11 +90,15 @@ void Java_org_rocksdb_Options_setBuiltinComparator(
*/
void Java_org_rocksdb_Options_setWriteBufferSize(
JNIEnv* env, jobject jobj, jlong jhandle, jlong jwrite_buffer_size) {
reinterpret_cast<rocksdb::Options*>(jhandle)->write_buffer_size =
rocksdb::jlong_to_size_t(jwrite_buffer_size);
rocksdb::Status s = rocksdb::check_if_jlong_fits_size_t(jwrite_buffer_size);
if (s.ok()) {
reinterpret_cast<rocksdb::Options*>(jhandle)->write_buffer_size =
jwrite_buffer_size;
} else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
}
/*
* Class: org_rocksdb_Options
* Method: writeBufferSize
@ -382,8 +386,13 @@ jlong Java_org_rocksdb_Options_maxLogFileSize(
*/
void Java_org_rocksdb_Options_setMaxLogFileSize(
JNIEnv* env, jobject jobj, jlong jhandle, jlong max_log_file_size) {
reinterpret_cast<rocksdb::Options*>(jhandle)->max_log_file_size =
rocksdb::jlong_to_size_t(max_log_file_size);
rocksdb::Status s = rocksdb::check_if_jlong_fits_size_t(max_log_file_size);
if (s.ok()) {
reinterpret_cast<rocksdb::Options*>(jhandle)->max_log_file_size =
max_log_file_size;
} else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
}
/*
@ -403,8 +412,14 @@ jlong Java_org_rocksdb_Options_logFileTimeToRoll(
*/
void Java_org_rocksdb_Options_setLogFileTimeToRoll(
JNIEnv* env, jobject jobj, jlong jhandle, jlong log_file_time_to_roll) {
reinterpret_cast<rocksdb::Options*>(jhandle)->log_file_time_to_roll =
rocksdb::jlong_to_size_t(log_file_time_to_roll);
rocksdb::Status s = rocksdb::check_if_jlong_fits_size_t(
log_file_time_to_roll);
if (s.ok()) {
reinterpret_cast<rocksdb::Options*>(jhandle)->log_file_time_to_roll =
log_file_time_to_roll;
} else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
}
/*
@ -424,8 +439,13 @@ jlong Java_org_rocksdb_Options_keepLogFileNum(
*/
void Java_org_rocksdb_Options_setKeepLogFileNum(
JNIEnv* env, jobject jobj, jlong jhandle, jlong keep_log_file_num) {
reinterpret_cast<rocksdb::Options*>(jhandle)->keep_log_file_num =
rocksdb::jlong_to_size_t(keep_log_file_num);
rocksdb::Status s = rocksdb::check_if_jlong_fits_size_t(keep_log_file_num);
if (s.ok()) {
reinterpret_cast<rocksdb::Options*>(jhandle)->keep_log_file_num =
keep_log_file_num;
} else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
}
/*
@ -542,7 +562,7 @@ void Java_org_rocksdb_Options_useFixedLengthPrefixExtractor(
JNIEnv* env, jobject jobj, jlong jhandle, jint jprefix_length) {
reinterpret_cast<rocksdb::Options*>(jhandle)->prefix_extractor.reset(
rocksdb::NewFixedPrefixTransform(
rocksdb::jlong_to_size_t(jprefix_length)));
static_cast<int>(jprefix_length)));
}
/*
@ -605,8 +625,13 @@ jlong Java_org_rocksdb_Options_manifestPreallocationSize(
*/
void Java_org_rocksdb_Options_setManifestPreallocationSize(
JNIEnv* env, jobject jobj, jlong jhandle, jlong preallocation_size) {
reinterpret_cast<rocksdb::Options*>(jhandle)->manifest_preallocation_size =
rocksdb::jlong_to_size_t(preallocation_size);
rocksdb::Status s = rocksdb::check_if_jlong_fits_size_t(preallocation_size);
if (s.ok()) {
reinterpret_cast<rocksdb::Options*>(jhandle)->manifest_preallocation_size =
preallocation_size;
} else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
}
/*
@ -1256,8 +1281,13 @@ jlong Java_org_rocksdb_Options_arenaBlockSize(
*/
void Java_org_rocksdb_Options_setArenaBlockSize(
JNIEnv* env, jobject jobj, jlong jhandle, jlong jarena_block_size) {
reinterpret_cast<rocksdb::Options*>(jhandle)->arena_block_size =
rocksdb::jlong_to_size_t(jarena_block_size);
rocksdb::Status s = rocksdb::check_if_jlong_fits_size_t(jarena_block_size);
if (s.ok()) {
reinterpret_cast<rocksdb::Options*>(jhandle)->arena_block_size =
jarena_block_size;
} else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
}
/*
@ -1420,9 +1450,14 @@ jlong Java_org_rocksdb_Options_inplaceUpdateNumLocks(
void Java_org_rocksdb_Options_setInplaceUpdateNumLocks(
JNIEnv* env, jobject jobj, jlong jhandle,
jlong jinplace_update_num_locks) {
reinterpret_cast<rocksdb::Options*>(
jhandle)->inplace_update_num_locks =
rocksdb::jlong_to_size_t(jinplace_update_num_locks);
rocksdb::Status s = rocksdb::check_if_jlong_fits_size_t(
jinplace_update_num_locks);
if (s.ok()) {
reinterpret_cast<rocksdb::Options*>(jhandle)->inplace_update_num_locks =
jinplace_update_num_locks;
} else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
}
/*
@ -1512,8 +1547,14 @@ jlong Java_org_rocksdb_Options_maxSuccessiveMerges(
void Java_org_rocksdb_Options_setMaxSuccessiveMerges(
JNIEnv* env, jobject jobj, jlong jhandle,
jlong jmax_successive_merges) {
reinterpret_cast<rocksdb::Options*>(jhandle)->max_successive_merges =
rocksdb::jlong_to_size_t(jmax_successive_merges);
rocksdb::Status s = rocksdb::check_if_jlong_fits_size_t(
jmax_successive_merges);
if (s.ok()) {
reinterpret_cast<rocksdb::Options*>(jhandle)->max_successive_merges =
jmax_successive_merges;
} else {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
}
/*

View File

@ -14,14 +14,18 @@
#include <limits>
#include "rocksdb/db.h"
#include "rocksdb/filter_policy.h"
#include "rocksdb/status.h"
#include "rocksdb/utilities/backupable_db.h"
namespace rocksdb {
inline size_t jlong_to_size_t(const jlong& jvalue) {
return static_cast<uint64_t>(jvalue) <=
static_cast<uint64_t>(std::numeric_limits<size_t>::max()) ?
static_cast<size_t>(jvalue) : std::numeric_limits<size_t>::max();
// detect if jlong overflows size_t
inline Status check_if_jlong_fits_size_t(const jlong& jvalue) {
Status s = Status::OK();
if (static_cast<uint64_t>(jvalue) > std::numeric_limits<size_t>::max()) {
s = Status::InvalidArgument(Slice("jlong overflows 32 bit value."));
}
return s;
}
// The portal class for org.rocksdb.RocksDB

View File

@ -18,7 +18,7 @@ jlong Java_org_rocksdb_GenericRateLimiterConfig_newRateLimiterHandle(
JNIEnv* env, jobject jobj, jlong jrate_bytes_per_second,
jlong jrefill_period_micros, jint jfairness) {
return reinterpret_cast<jlong>(rocksdb::NewGenericRateLimiter(
rocksdb::jlong_to_size_t(jrate_bytes_per_second),
rocksdb::jlong_to_size_t(jrefill_period_micros),
static_cast<int64_t>(jrate_bytes_per_second),
static_cast<int64_t>(jrefill_period_micros),
static_cast<int32_t>(jfairness)));
}

View File

@ -10,7 +10,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include <iostream>
#include <string>
#include "include/org_rocksdb_RestoreOptions.h"
@ -72,7 +71,7 @@ void Java_org_rocksdb_RestoreBackupableDB_restoreDBFromBackup0(JNIEnv* env,
env->ReleaseStringUTFChars(jdb_dir, cdb_dir);
env->ReleaseStringUTFChars(jwal_dir, cwal_dir);
if(!s.ok()) {
if (!s.ok()) {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
}
@ -97,7 +96,7 @@ void Java_org_rocksdb_RestoreBackupableDB_restoreDBFromLatestBackup0(
env->ReleaseStringUTFChars(jdb_dir, cdb_dir);
env->ReleaseStringUTFChars(jwal_dir, cwal_dir);
if(!s.ok()) {
if (!s.ok()) {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
}
@ -112,7 +111,7 @@ void Java_org_rocksdb_RestoreBackupableDB_purgeOldBackups0(JNIEnv* env,
auto rdb = reinterpret_cast<rocksdb::RestoreBackupableDB*>(jhandle);
rocksdb::Status s = rdb->PurgeOldBackups(jnum_backups_to_keep);
if(!s.ok()) {
if (!s.ok()) {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
}
@ -127,7 +126,7 @@ void Java_org_rocksdb_RestoreBackupableDB_deleteBackup0(JNIEnv* env,
auto rdb = reinterpret_cast<rocksdb::RestoreBackupableDB*>(jhandle);
rocksdb::Status s = rdb->DeleteBackup(jbackup_id);
if(!s.ok()) {
if (!s.ok()) {
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
}
}

View File

@ -246,7 +246,7 @@ jobject multi_get_helper(JNIEnv* env, jobject jdb, rocksdb::DB* db,
jkey_list, rocksdb::ListJni::getIteratorMethod(env));
// iterate over keys and convert java byte array to slice
while(env->CallBooleanMethod(
while (env->CallBooleanMethod(
iteratorObj, rocksdb::ListJni::getHasNextMethod(env)) == JNI_TRUE) {
jbyteArray jkey = (jbyteArray) env->CallObjectMethod(
iteratorObj, rocksdb::ListJni::getNextMethod(env));
@ -272,23 +272,22 @@ jobject multi_get_helper(JNIEnv* env, jobject jdb, rocksdb::DB* db,
jobject jvalue_list = env->NewObject(jclazz, mid, jkeys_count);
// insert in java list
for(std::vector<rocksdb::Status>::size_type i = 0; i != s.size(); i++) {
if(s[i].ok()) {
for (std::vector<rocksdb::Status>::size_type i = 0; i != s.size(); i++) {
if (s[i].ok()) {
jbyteArray jvalue = env->NewByteArray(values[i].size());
env->SetByteArrayRegion(
jvalue, 0, values[i].size(),
reinterpret_cast<const jbyte*>(values[i].c_str()));
env->CallBooleanMethod(
jvalue_list, rocksdb::ListJni::getListAddMethodId(env), jvalue);
}
else {
} else {
env->CallBooleanMethod(
jvalue_list, rocksdb::ListJni::getListAddMethodId(env), nullptr);
}
}
// free up allocated byte arrays
for(std::vector<jbyte*>::size_type i = 0; i != keys_to_free.size(); i++) {
for (std::vector<jbyte*>::size_type i = 0; i != keys_to_free.size(); i++) {
delete[] keys_to_free[i];
}
keys_to_free.clear();

View File

@ -30,7 +30,7 @@
void Java_org_rocksdb_WriteBatch_newWriteBatch(
JNIEnv* env, jobject jobj, jint jreserved_bytes) {
rocksdb::WriteBatch* wb = new rocksdb::WriteBatch(
rocksdb::jlong_to_size_t(jreserved_bytes));
static_cast<size_t>(jreserved_bytes));
rocksdb::WriteBatchJni::setHandle(env, jobj, wb);
}