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:
Radek Hubner 2023-11-16 15:46:31 -08:00 committed by Facebook GitHub Bot
parent a9bd525b52
commit 2f9ea8193f
6 changed files with 143 additions and 1 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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. -&gt; 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);
}

View File

@ -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
View File

@ -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 \