mirror of https://github.com/facebook/rocksdb.git
Add HyperClockCache Java API. (#12065)
Summary: Fix https://github.com/facebook/rocksdb/issues/11510 Pull Request resolved: https://github.com/facebook/rocksdb/pull/12065 Reviewed By: ajkr Differential Revision: D51406695 Pulled By: cbi42 fbshipit-source-id: b9e32da5f9bcafb5365e4349f7295be90d5aa7ba
This commit is contained in:
parent
a9bd525b52
commit
2f9ea8193f
|
@ -43,6 +43,7 @@ set(JNI_NATIVE_SOURCES
|
|||
rocksjni/export_import_files_metadatajni.cc
|
||||
rocksjni/filter.cc
|
||||
rocksjni/import_column_family_options.cc
|
||||
rocksjni/hyper_clock_cache.cc
|
||||
rocksjni/ingest_external_file_options.cc
|
||||
rocksjni/iterator.cc
|
||||
rocksjni/jnicallback.cc
|
||||
|
@ -173,6 +174,7 @@ set(JAVA_MAIN_CLASSES
|
|||
src/main/java/org/rocksdb/HistogramType.java
|
||||
src/main/java/org/rocksdb/Holder.java
|
||||
src/main/java/org/rocksdb/ImportColumnFamilyOptions.java
|
||||
src/main/java/org/rocksdb/HyperClockCache.java
|
||||
src/main/java/org/rocksdb/IndexShorteningMode.java
|
||||
src/main/java/org/rocksdb/IndexType.java
|
||||
src/main/java/org/rocksdb/InfoLogLevel.java
|
||||
|
@ -336,6 +338,7 @@ set(JAVA_TEST_CLASSES
|
|||
src/test/java/org/rocksdb/VerifyChecksumsTest.java
|
||||
src/test/java/org/rocksdb/MultiColumnRegressionTest.java
|
||||
src/test/java/org/rocksdb/FlushTest.java
|
||||
src/test/java/org/rocksdb/HyperClockCacheTest.java
|
||||
src/test/java/org/rocksdb/PutMultiplePartsTest.java
|
||||
src/test/java/org/rocksdb/StatisticsCollectorTest.java
|
||||
src/test/java/org/rocksdb/LRUCacheTest.java
|
||||
|
@ -445,6 +448,7 @@ set(JAVA_TEST_RUNNING_CLASSES
|
|||
org.rocksdb.VerifyChecksumsTest
|
||||
org.rocksdb.MultiColumnRegressionTest
|
||||
org.rocksdb.FlushTest
|
||||
org.rocksdb.HyperClockCacheTest
|
||||
org.rocksdb.PutMultiplePartsTest
|
||||
org.rocksdb.StatisticsCollectorTest
|
||||
org.rocksdb.LRUCacheTest
|
||||
|
@ -682,6 +686,7 @@ if(${CMAKE_VERSION} VERSION_LESS "3.11.4")
|
|||
org.rocksdb.FlushOptions
|
||||
org.rocksdb.HashLinkedListMemTableConfig
|
||||
org.rocksdb.HashSkipListMemTableConfig
|
||||
org.rocksdb.HyperClockCache
|
||||
org.rocksdb.IngestExternalFileOptions
|
||||
org.rocksdb.Logger
|
||||
org.rocksdb.LRUCache
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under both the GPLv2 (found in the
|
||||
// COPYING file in the root directory) and Apache 2.0 License
|
||||
// (found in the LICENSE.Apache file in the root directory).
|
||||
//
|
||||
// This file implements the "bridge" between Java and C++ for
|
||||
// ROCKSDB_NAMESPACE::HyperClockCache.
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "cache/clock_cache.h"
|
||||
#include "include/org_rocksdb_HyperClockCache.h"
|
||||
#include "rocksjni/cplusplus_to_java_convert.h"
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_HyperClockCache
|
||||
* Method: newHyperClockCache
|
||||
* Signature: (JJIZ)J
|
||||
*/
|
||||
jlong Java_org_rocksdb_HyperClockCache_newHyperClockCache(
|
||||
JNIEnv*, jclass, jlong capacity, jlong estimatedEntryCharge,
|
||||
jint numShardBits, jboolean strictCapacityLimit) {
|
||||
ROCKSDB_NAMESPACE::HyperClockCacheOptions cacheOptions =
|
||||
ROCKSDB_NAMESPACE::HyperClockCacheOptions(
|
||||
capacity, estimatedEntryCharge, numShardBits, strictCapacityLimit);
|
||||
|
||||
auto* cache = new std::shared_ptr<ROCKSDB_NAMESPACE::Cache>(
|
||||
cacheOptions.MakeSharedCache());
|
||||
return GET_CPLUSPLUS_POINTER(cache);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_rocksdb_HyperClockCache
|
||||
* Method: disposeInternalJni
|
||||
* Signature: (J)V
|
||||
*/
|
||||
void Java_org_rocksdb_HyperClockCache_disposeInternalJni(JNIEnv*, jclass,
|
||||
jlong jhandle) {
|
||||
auto* hyper_clock_cache =
|
||||
reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Cache>*>(jhandle);
|
||||
delete hyper_clock_cache; // delete std::shared_ptr
|
||||
}
|
|
@ -8,12 +8,18 @@ package org.rocksdb;
|
|||
/**
|
||||
* Similar to {@link LRUCache}, but based on the CLOCK algorithm with
|
||||
* better concurrent performance in some cases
|
||||
*
|
||||
* @deprecated The old Clock Cache implementation had an unresolved bug and
|
||||
* has been removed. The new HyperClockCache requires an additional
|
||||
* configuration parameter that is not provided by this API. This function
|
||||
* simply returns a new LRUCache for functional compatibility.
|
||||
*/
|
||||
public class ClockCache extends Cache {
|
||||
|
||||
/**
|
||||
* Create a new cache with a fixed size capacity.
|
||||
*
|
||||
* @deprecated The old Clock Cache implementation had an unresolved bug and has been removed.
|
||||
*
|
||||
* @param capacity The fixed size capacity of the cache
|
||||
*/
|
||||
public ClockCache(final long capacity) {
|
||||
|
@ -27,6 +33,8 @@ public class ClockCache extends Cache {
|
|||
* numShardBits = -1 means it is automatically determined: every shard
|
||||
* will be at least 512KB and number of shard bits will not exceed 6.
|
||||
*
|
||||
* @deprecated The old Clock Cache implementation had an unresolved bug and has been removed.
|
||||
*
|
||||
* @param capacity The fixed size capacity of the cache
|
||||
* @param numShardBits The cache is sharded to 2^numShardBits shards,
|
||||
* by hash of the key
|
||||
|
@ -43,6 +51,8 @@ public class ClockCache extends Cache {
|
|||
* numShardBits = -1 means it is automatically determined: every shard
|
||||
* will be at least 512KB and number of shard bits will not exceed 6.
|
||||
*
|
||||
* @deprecated The old Clock Cache implementation had an unresolved bug and has been removed.
|
||||
*
|
||||
* @param capacity The fixed size capacity of the cache
|
||||
* @param numShardBits The cache is sharded to 2^numShardBits shards,
|
||||
* by hash of the key
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package org.rocksdb;
|
||||
|
||||
/**
|
||||
* HyperClockCache - A lock-free Cache alternative for RocksDB block cache
|
||||
* that offers much improved CPU efficiency vs. LRUCache under high parallel
|
||||
* load or high contention, with some caveats:
|
||||
* <ul>
|
||||
* <li>
|
||||
* Not a general Cache implementation: can only be used for
|
||||
* BlockBasedTableOptions::block_cache, which RocksDB uses in a way that is
|
||||
* compatible with HyperClockCache.
|
||||
* </li>
|
||||
* <li>
|
||||
* Requires an extra tuning parameter: see estimated_entry_charge below.
|
||||
* Similarly, substantially changing the capacity with SetCapacity could
|
||||
* harm efficiency. -> EXPERIMENTAL: the tuning parameter can be set to 0
|
||||
* to find the appropriate balance automatically.
|
||||
* </li>
|
||||
* <li>
|
||||
* Cache priorities are less aggressively enforced, which could cause
|
||||
* cache dilution from long range scans (unless they use fill_cache=false).
|
||||
* </li>
|
||||
* <li>
|
||||
* Can be worse for small caches, because if almost all of a cache shard is
|
||||
* pinned (more likely with non-partitioned filters), then CLOCK eviction
|
||||
* becomes very CPU intensive.
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
@Experimental("HyperClockCache is still experimental and this API may change in future.")
|
||||
public class HyperClockCache extends Cache {
|
||||
/**
|
||||
*
|
||||
* @param capacity The fixed size capacity of the cache
|
||||
* @param estimatedEntryCharge EXPERIMENTAL: the field can be set to 0 to size the table
|
||||
* dynamically and automatically. See C++ Api for more info.
|
||||
* @param numShardBits The cache is sharded to 2^numShardBits shards, by hash of the key
|
||||
* @param strictCapacityLimit insert to the cache will fail when cache is full
|
||||
*/
|
||||
public HyperClockCache(final long capacity, final long estimatedEntryCharge, int numShardBits,
|
||||
boolean strictCapacityLimit) {
|
||||
super(newHyperClockCache(capacity, estimatedEntryCharge, numShardBits, strictCapacityLimit));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disposeInternal(long handle) {
|
||||
disposeInternalJni(handle);
|
||||
}
|
||||
|
||||
private static native void disposeInternalJni(long handle);
|
||||
|
||||
private static native long newHyperClockCache(final long capacity,
|
||||
final long estimatedEntryCharge, int numShardBits, boolean strictCapacityLimit);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package org.rocksdb;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class HyperClockCacheTest {
|
||||
@Rule public TemporaryFolder dbFolder = new TemporaryFolder();
|
||||
|
||||
@Test
|
||||
public void newHyperClockCache() throws RocksDBException {
|
||||
RocksDB.loadLibrary();
|
||||
try (Cache cache = new HyperClockCache(1024 * 1024, 0, 8, false)) {
|
||||
BlockBasedTableConfig tableConfing = new BlockBasedTableConfig();
|
||||
tableConfing.setBlockCache(cache);
|
||||
try (Options options = new Options()) {
|
||||
options.setTableFormatConfig(tableConfing);
|
||||
options.setCreateIfMissing(true);
|
||||
try (RocksDB db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath())) {
|
||||
db.put("testKey".getBytes(), "testData".getBytes());
|
||||
// no op
|
||||
assertThat(cache.getUsage()).isGreaterThanOrEqualTo(0);
|
||||
assertThat(cache.getPinnedUsage()).isGreaterThanOrEqualTo(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1
src.mk
1
src.mk
|
@ -670,6 +670,7 @@ JNI_NATIVE_SOURCES = \
|
|||
java/rocksjni/import_column_family_options.cc \
|
||||
java/rocksjni/ingest_external_file_options.cc \
|
||||
java/rocksjni/filter.cc \
|
||||
java/rocksjni/hyper_clock_cache.cc \
|
||||
java/rocksjni/iterator.cc \
|
||||
java/rocksjni/jni_perf_context.cc \
|
||||
java/rocksjni/jnicallback.cc \
|
||||
|
|
Loading…
Reference in New Issue