Filters getting disposed by System.gc before EOL

Previous to this commit Filters passed as parameters to the
BlockTableConfig are disposed before they should be disposed.

Further Smart pointer usage was corrected.

Java holds now the smart pointer to the FilterPolicy correctly
and cares about freeing underlying c++ structures.
This commit is contained in:
fyrz 2014-10-14 18:38:50 +02:00
parent 7658bcc1e5
commit bafbc23baa
5 changed files with 40 additions and 13 deletions

View File

@ -1154,6 +1154,7 @@ public class Options extends RocksObject {
*/
public Options setMemTableConfig(MemTableConfig config)
throws RocksDBException {
memTableConfig_ = config;
setMemTableFactory(nativeHandle_, config.newMemTableFactoryHandle());
return this;
}
@ -1168,6 +1169,7 @@ public class Options extends RocksObject {
* @throws RocksDBException
*/
public Options setRateLimiterConfig(RateLimiterConfig config) {
rateLimiterConfig_ = config;
setRateLimiter(nativeHandle_, config.newRateLimiterHandle());
return this;
}
@ -1191,6 +1193,7 @@ public class Options extends RocksObject {
* @return the reference of the current Options.
*/
public Options setTableFormatConfig(TableFormatConfig config) {
tableFormatConfig_ = config;
setTableFactory(nativeHandle_, config.newTableFactoryHandle());
return this;
}
@ -2280,4 +2283,7 @@ public class Options extends RocksObject {
long cacheSize_;
int numShardBits_;
RocksEnv env_;
MemTableConfig memTableConfig_;
TableFormatConfig tableFormatConfig_;
RateLimiterConfig rateLimiterConfig_;
}

View File

@ -13,19 +13,30 @@ public class FilterTest {
}
public static void main(String[] args) {
Options options = new Options();
// test table config without filter
// test table config
BlockBasedTableConfig blockConfig = new BlockBasedTableConfig();
options.setTableFormatConfig(blockConfig);
options.setTableFormatConfig(new BlockBasedTableConfig().
setFilter(new BloomFilter()));
options.dispose();
System.gc();
System.runFinalization();
// new Bloom filter
options = new Options();
blockConfig = new BlockBasedTableConfig();
blockConfig.setFilter(new BloomFilter());
options.setTableFormatConfig(blockConfig);
blockConfig.setFilter(new BloomFilter(10));
BloomFilter bloomFilter = new BloomFilter(10);
blockConfig.setFilter(bloomFilter);
options.setTableFormatConfig(blockConfig);
System.gc();
System.runFinalization();
blockConfig.setFilter(new BloomFilter(10, false));
options.setTableFormatConfig(blockConfig);
options.dispose();
options = null;
blockConfig = null;
System.gc();
System.runFinalization();
System.out.println("Filter test passed");
}
}

View File

@ -24,9 +24,12 @@
void Java_org_rocksdb_BloomFilter_createNewBloomFilter(
JNIEnv* env, jobject jobj, jint bits_per_key,
jboolean use_block_base_builder) {
const rocksdb::FilterPolicy* fp = rocksdb::NewBloomFilterPolicy(bits_per_key,
use_block_base_builder);
rocksdb::FilterJni::setHandle(env, jobj, fp);
rocksdb::FilterPolicy* fp = const_cast<rocksdb::FilterPolicy *>(
rocksdb::NewBloomFilterPolicy(bits_per_key, use_block_base_builder));
std::shared_ptr<rocksdb::FilterPolicy> *pFilterPolicy =
new std::shared_ptr<rocksdb::FilterPolicy>;
*pFilterPolicy = std::shared_ptr<rocksdb::FilterPolicy>(fp);
rocksdb::FilterJni::setHandle(env, jobj, pFilterPolicy);
}
/*
@ -35,6 +38,9 @@ void Java_org_rocksdb_BloomFilter_createNewBloomFilter(
* Signature: (J)V
*/
void Java_org_rocksdb_Filter_disposeInternal(
JNIEnv* env, jobject jobj, jlong handle) {
delete reinterpret_cast<rocksdb::FilterPolicy*>(handle);
JNIEnv* env, jobject jobj, jlong jhandle) {
std::shared_ptr<rocksdb::FilterPolicy> *handle =
reinterpret_cast<std::shared_ptr<rocksdb::FilterPolicy> *>(jhandle);
handle->reset();
}

View File

@ -313,14 +313,16 @@ class FilterJni {
}
// Get the pointer to rocksdb::FilterPolicy.
static rocksdb::FilterPolicy* getHandle(JNIEnv* env, jobject jobj) {
return reinterpret_cast<rocksdb::FilterPolicy*>(
static std::shared_ptr<rocksdb::FilterPolicy>* getHandle(
JNIEnv* env, jobject jobj) {
return reinterpret_cast
<std::shared_ptr<rocksdb::FilterPolicy> *>(
env->GetLongField(jobj, getHandleFieldID(env)));
}
// Pass the rocksdb::FilterPolicy pointer to the java side.
static void setHandle(
JNIEnv* env, jobject jobj, const rocksdb::FilterPolicy* op) {
JNIEnv* env, jobject jobj, std::shared_ptr<rocksdb::FilterPolicy>* op) {
env->SetLongField(
jobj, getHandleFieldID(env),
reinterpret_cast<jlong>(op));

View File

@ -56,8 +56,10 @@ jlong Java_org_rocksdb_BlockBasedTableConfig_newTableFactoryHandle(
options.block_restart_interval = block_restart_interval;
options.whole_key_filtering = whole_key_filtering;
if (jfilterPolicy > 0) {
options.filter_policy.reset(
reinterpret_cast<rocksdb::FilterPolicy*>(jfilterPolicy));
std::shared_ptr<rocksdb::FilterPolicy> *pFilterPolicy =
reinterpret_cast<std::shared_ptr<rocksdb::FilterPolicy> *>(
jfilterPolicy);
options.filter_policy = *pFilterPolicy;
}
options.cache_index_and_filter_blocks = cache_index_and_filter_blocks;
options.hash_index_allow_collision = hash_index_allow_collision;