From 62afa968c2763d7b5bc45bd705100b535e215095 Mon Sep 17 00:00:00 2001 From: Adam Retter Date: Fri, 18 Dec 2020 16:11:17 -0800 Subject: [PATCH] Fix various small build issues, Java API naming (#7776) Summary: * Compatibility with older GCC. * Compatibility with older jemalloc libraries. * Remove Docker warning when building i686 binaries. * Fix case inconsistency in Java API naming (potential update to HISTORY.md deferred) Pull Request resolved: https://github.com/facebook/rocksdb/pull/7776 Reviewed By: akankshamahajan15 Differential Revision: D25607235 Pulled By: pdillinger fbshipit-source-id: 7ab0fb7fa7a34e97ed0bec991f5081acb095777d --- Makefile | 4 +- java/rocksjni/portal.h | 20 +- java/rocksjni/testable_event_listener.cc | 79 +-- .../org/rocksdb/AbstractEventListener.java | 10 +- .../main/java/org/rocksdb/EventListener.java | 10 +- .../java/org/rocksdb/EventListenerTest.java | 555 ++++++++++++------ .../rocksdb/test/TestableEventListener.java | 4 + port/jemalloc_helper.h | 18 + 8 files changed, 452 insertions(+), 248 deletions(-) diff --git a/Makefile b/Makefile index 6aae4aa5f..0398ccf67 100644 --- a/Makefile +++ b/Makefile @@ -2253,7 +2253,7 @@ rocksdbjavastaticreleasedocker: rocksdbjavastatic rocksdbjavastaticdockerx86 roc rocksdbjavastaticdockerx86: mkdir -p java/target - docker run --rm --name rocksdb_linux_x86-be --attach stdin --attach stdout --attach stderr --volume $(HOME)/.m2:/root/.m2:ro --volume `pwd`:/rocksdb-host:ro --volume /rocksdb-local-build --volume `pwd`/java/target:/rocksdb-java-target --env DEBUG_LEVEL=$(DEBUG_LEVEL) evolvedbinary/rocksjava:centos6_x86-be /rocksdb-host/java/crossbuild/docker-build-linux-centos.sh + docker run --rm --name rocksdb_linux_x86-be --platform linux/386 --attach stdin --attach stdout --attach stderr --volume $(HOME)/.m2:/root/.m2:ro --volume `pwd`:/rocksdb-host:ro --volume /rocksdb-local-build --volume `pwd`/java/target:/rocksdb-java-target --env DEBUG_LEVEL=$(DEBUG_LEVEL) evolvedbinary/rocksjava:centos6_x86-be /rocksdb-host/java/crossbuild/docker-build-linux-centos.sh rocksdbjavastaticdockerx86_64: mkdir -p java/target @@ -2269,7 +2269,7 @@ rocksdbjavastaticdockerarm64v8: rocksdbjavastaticdockerx86musl: mkdir -p java/target - docker run --rm --name rocksdb_linux_x86-musl-be --attach stdin --attach stdout --attach stderr --volume $(HOME)/.m2:/root/.m2:ro --volume `pwd`:/rocksdb-host:ro --volume /rocksdb-local-build --volume `pwd`/java/target:/rocksdb-java-target --env DEBUG_LEVEL=$(DEBUG_LEVEL) evolvedbinary/rocksjava:alpine3_x86-be /rocksdb-host/java/crossbuild/docker-build-linux-centos.sh + docker run --rm --name rocksdb_linux_x86-musl-be --platform linux/386 --attach stdin --attach stdout --attach stderr --volume $(HOME)/.m2:/root/.m2:ro --volume `pwd`:/rocksdb-host:ro --volume /rocksdb-local-build --volume `pwd`/java/target:/rocksdb-java-target --env DEBUG_LEVEL=$(DEBUG_LEVEL) evolvedbinary/rocksjava:alpine3_x86-be /rocksdb-host/java/crossbuild/docker-build-linux-centos.sh rocksdbjavastaticdockerx86_64musl: mkdir -p java/target diff --git a/java/rocksjni/portal.h b/java/rocksjni/portal.h index 1176beba4..df955564f 100644 --- a/java/rocksjni/portal.h +++ b/java/rocksjni/portal.h @@ -7955,7 +7955,7 @@ class AbstractEventListenerJni } /** - * Get the Java Method: AbstractEventListener#OnFileFlushFinish + * Get the Java Method: AbstractEventListener#onFileFlushFinish * * @param env A pointer to the Java environment * @@ -7965,13 +7965,13 @@ class AbstractEventListenerJni jclass jclazz = getJClass(env); assert(jclazz != nullptr); static jmethodID mid = env->GetMethodID( - jclazz, "OnFileFlushFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); + jclazz, "onFileFlushFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); assert(mid != nullptr); return mid; } /** - * Get the Java Method: AbstractEventListener#OnFileSyncFinish + * Get the Java Method: AbstractEventListener#onFileSyncFinish * * @param env A pointer to the Java environment * @@ -7981,13 +7981,13 @@ class AbstractEventListenerJni jclass jclazz = getJClass(env); assert(jclazz != nullptr); static jmethodID mid = env->GetMethodID( - jclazz, "OnFileSyncFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); + jclazz, "onFileSyncFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); assert(mid != nullptr); return mid; } /** - * Get the Java Method: AbstractEventListener#OnFileRangeSyncFinish + * Get the Java Method: AbstractEventListener#onFileRangeSyncFinish * * @param env A pointer to the Java environment * @@ -7997,13 +7997,13 @@ class AbstractEventListenerJni jclass jclazz = getJClass(env); assert(jclazz != nullptr); static jmethodID mid = env->GetMethodID( - jclazz, "OnFileRangeSyncFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); + jclazz, "onFileRangeSyncFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); assert(mid != nullptr); return mid; } /** - * Get the Java Method: AbstractEventListener#OnFileTruncateFinish + * Get the Java Method: AbstractEventListener#onFileTruncateFinish * * @param env A pointer to the Java environment * @@ -8013,13 +8013,13 @@ class AbstractEventListenerJni jclass jclazz = getJClass(env); assert(jclazz != nullptr); static jmethodID mid = env->GetMethodID( - jclazz, "OnFileTruncateFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); + jclazz, "onFileTruncateFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); assert(mid != nullptr); return mid; } /** - * Get the Java Method: AbstractEventListener#OnFileCloseFinish + * Get the Java Method: AbstractEventListener#onFileCloseFinish * * @param env A pointer to the Java environment * @@ -8029,7 +8029,7 @@ class AbstractEventListenerJni jclass jclazz = getJClass(env); assert(jclazz != nullptr); static jmethodID mid = env->GetMethodID( - jclazz, "OnFileCloseFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); + jclazz, "onFileCloseFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); assert(mid != nullptr); return mid; } diff --git a/java/rocksjni/testable_event_listener.cc b/java/rocksjni/testable_event_listener.cc index 849cad7aa..759e61766 100644 --- a/java/rocksjni/testable_event_listener.cc +++ b/java/rocksjni/testable_event_listener.cc @@ -1,33 +1,40 @@ +// 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). #include +#include #include #include "include/org_rocksdb_test_TestableEventListener.h" #include "rocksdb/listener.h" +#include "rocksdb/status.h" +#include "rocksdb/table_properties.h" using namespace ROCKSDB_NAMESPACE; static TableProperties newTablePropertiesForTest() { TableProperties table_properties; - table_properties.data_size = LLONG_MAX; - table_properties.index_size = LLONG_MAX; - table_properties.index_partitions = LLONG_MAX; - table_properties.top_level_index_size = LLONG_MAX; - table_properties.index_key_is_user_key = LLONG_MAX; - table_properties.index_value_is_delta_encoded = LLONG_MAX; - table_properties.filter_size = LLONG_MAX; - table_properties.raw_key_size = LLONG_MAX; - table_properties.raw_value_size = LLONG_MAX; - table_properties.num_data_blocks = LLONG_MAX; - table_properties.num_entries = LLONG_MAX; - table_properties.num_deletions = LLONG_MAX; - table_properties.num_merge_operands = LLONG_MAX; - table_properties.num_range_deletions = LLONG_MAX; - table_properties.format_version = LLONG_MAX; - table_properties.fixed_key_len = LLONG_MAX; - table_properties.column_family_id = LLONG_MAX; - table_properties.creation_time = LLONG_MAX; - table_properties.oldest_key_time = LLONG_MAX; - table_properties.file_creation_time = LLONG_MAX; + table_properties.data_size = UINT64_MAX; + table_properties.index_size = UINT64_MAX; + table_properties.index_partitions = UINT64_MAX; + table_properties.top_level_index_size = UINT64_MAX; + table_properties.index_key_is_user_key = UINT64_MAX; + table_properties.index_value_is_delta_encoded = UINT64_MAX; + table_properties.filter_size = UINT64_MAX; + table_properties.raw_key_size = UINT64_MAX; + table_properties.raw_value_size = UINT64_MAX; + table_properties.num_data_blocks = UINT64_MAX; + table_properties.num_entries = UINT64_MAX; + table_properties.num_deletions = UINT64_MAX; + table_properties.num_merge_operands = UINT64_MAX; + table_properties.num_range_deletions = UINT64_MAX; + table_properties.format_version = UINT64_MAX; + table_properties.fixed_key_len = UINT64_MAX; + table_properties.column_family_id = UINT64_MAX; + table_properties.creation_time = UINT64_MAX; + table_properties.oldest_key_time = UINT64_MAX; + table_properties.file_creation_time = UINT64_MAX; table_properties.db_id = "dbId"; table_properties.db_session_id = "sessionId"; table_properties.column_family_name = "columnFamilyName"; @@ -40,7 +47,7 @@ static TableProperties newTablePropertiesForTest() { table_properties.compression_options = "compressionOptions"; table_properties.user_collected_properties = {{"key", "value"}}; table_properties.readable_properties = {{"key", "value"}}; - table_properties.properties_offsets = {{"key", LLONG_MAX}}; + table_properties.properties_offsets = {{"key", UINT64_MAX}}; return table_properties; } @@ -61,14 +68,14 @@ void Java_org_rocksdb_test_TestableEventListener_invokeAllCallbacks( flush_job_info.cf_id = INT_MAX; flush_job_info.cf_name = "testColumnFamily"; flush_job_info.file_path = "/file/path"; - flush_job_info.file_number = LLONG_MAX; - flush_job_info.oldest_blob_file_number = LLONG_MAX; - flush_job_info.thread_id = LLONG_MAX; + flush_job_info.file_number = UINT64_MAX; + flush_job_info.oldest_blob_file_number = UINT64_MAX; + flush_job_info.thread_id = UINT64_MAX; flush_job_info.job_id = INT_MAX; flush_job_info.triggered_writes_slowdown = true; flush_job_info.triggered_writes_stop = true; - flush_job_info.smallest_seqno = LLONG_MAX; - flush_job_info.largest_seqno = LLONG_MAX; + flush_job_info.smallest_seqno = UINT64_MAX; + flush_job_info.largest_seqno = UINT64_MAX; flush_job_info.table_properties = table_properties; flush_job_info.flush_reason = FlushReason::kManualFlush; @@ -86,10 +93,10 @@ void Java_org_rocksdb_test_TestableEventListener_invokeAllCallbacks( el->OnTableFileDeleted(file_deletion_info); CompactionJobInfo compaction_job_info; - compaction_job_info.cf_id = INT_MAX; + compaction_job_info.cf_id = UINT32_MAX; compaction_job_info.cf_name = "compactionColumnFamily"; compaction_job_info.status = status; - compaction_job_info.thread_id = LLONG_MAX; + compaction_job_info.thread_id = UINT64_MAX; compaction_job_info.job_id = INT_MAX; compaction_job_info.base_input_level = INT_MAX; compaction_job_info.output_level = INT_MAX; @@ -109,7 +116,7 @@ void Java_org_rocksdb_test_TestableEventListener_invokeAllCallbacks( el->OnCompactionCompleted(nullptr, compaction_job_info); TableFileCreationInfo file_creation_info; - file_creation_info.file_size = LLONG_MAX; + file_creation_info.file_size = UINT64_MAX; file_creation_info.table_properties = table_properties; file_creation_info.status = status; file_creation_info.file_checksum = "fileChecksum"; @@ -133,10 +140,10 @@ void Java_org_rocksdb_test_TestableEventListener_invokeAllCallbacks( MemTableInfo mem_table_info; mem_table_info.cf_name = "columnFamilyName"; - mem_table_info.first_seqno = LLONG_MAX; - mem_table_info.earliest_seqno = LLONG_MAX; - mem_table_info.num_entries = LLONG_MAX; - mem_table_info.num_deletes = LLONG_MAX; + mem_table_info.first_seqno = UINT64_MAX; + mem_table_info.earliest_seqno = UINT64_MAX; + mem_table_info.num_entries = UINT64_MAX; + mem_table_info.num_deletes = UINT64_MAX; el->OnMemTableSealed(mem_table_info); el->OnColumnFamilyHandleDeletionStarted(nullptr); @@ -145,7 +152,7 @@ void Java_org_rocksdb_test_TestableEventListener_invokeAllCallbacks( file_ingestion_info.cf_name = "columnFamilyName"; file_ingestion_info.external_file_path = "/external/file/path"; file_ingestion_info.internal_file_path = "/internal/file/path"; - file_ingestion_info.global_seqno = LLONG_MAX; + file_ingestion_info.global_seqno = UINT64_MAX; file_ingestion_info.table_properties = table_properties; el->OnExternalFileIngested(nullptr, file_ingestion_info); @@ -169,8 +176,8 @@ void Java_org_rocksdb_test_TestableEventListener_invokeAllCallbacks( std::chrono::nanoseconds>( std::chrono::nanoseconds(1600699425000000000ll)), status); - op_info.offset = LLONG_MAX; - op_info.length = LLONG_MAX; + op_info.offset = UINT64_MAX; + op_info.length = SIZE_MAX; op_info.status = status; el->OnFileReadFinish(op_info); diff --git a/java/src/main/java/org/rocksdb/AbstractEventListener.java b/java/src/main/java/org/rocksdb/AbstractEventListener.java index b3c8a7097..6698acf88 100644 --- a/java/src/main/java/org/rocksdb/AbstractEventListener.java +++ b/java/src/main/java/org/rocksdb/AbstractEventListener.java @@ -265,27 +265,27 @@ public abstract class AbstractEventListener extends RocksCallbackObject implemen } @Override - public void OnFileFlushFinish(final FileOperationInfo fileOperationInfo) { + public void onFileFlushFinish(final FileOperationInfo fileOperationInfo) { // no-op } @Override - public void OnFileSyncFinish(final FileOperationInfo fileOperationInfo) { + public void onFileSyncFinish(final FileOperationInfo fileOperationInfo) { // no-op } @Override - public void OnFileRangeSyncFinish(final FileOperationInfo fileOperationInfo) { + public void onFileRangeSyncFinish(final FileOperationInfo fileOperationInfo) { // no-op } @Override - public void OnFileTruncateFinish(final FileOperationInfo fileOperationInfo) { + public void onFileTruncateFinish(final FileOperationInfo fileOperationInfo) { // no-op } @Override - public void OnFileCloseFinish(final FileOperationInfo fileOperationInfo) { + public void onFileCloseFinish(final FileOperationInfo fileOperationInfo) { // no-op } diff --git a/java/src/main/java/org/rocksdb/EventListener.java b/java/src/main/java/org/rocksdb/EventListener.java index 7bc2ad0db..808278d02 100644 --- a/java/src/main/java/org/rocksdb/EventListener.java +++ b/java/src/main/java/org/rocksdb/EventListener.java @@ -259,7 +259,7 @@ public interface EventListener { * @param fileOperationInfo file operation info, * contains data copied from respective native structure. */ - void OnFileFlushFinish(final FileOperationInfo fileOperationInfo); + void onFileFlushFinish(final FileOperationInfo fileOperationInfo); /** * A callback function for RocksDB which will be called whenever a file sync @@ -268,7 +268,7 @@ public interface EventListener { * @param fileOperationInfo file operation info, * contains data copied from respective native structure. */ - void OnFileSyncFinish(final FileOperationInfo fileOperationInfo); + void onFileSyncFinish(final FileOperationInfo fileOperationInfo); /** * A callback function for RocksDB which will be called whenever a file @@ -277,7 +277,7 @@ public interface EventListener { * @param fileOperationInfo file operation info, * contains data copied from respective native structure. */ - void OnFileRangeSyncFinish(final FileOperationInfo fileOperationInfo); + void onFileRangeSyncFinish(final FileOperationInfo fileOperationInfo); /** * A callback function for RocksDB which will be called whenever a file @@ -286,7 +286,7 @@ public interface EventListener { * @param fileOperationInfo file operation info, * contains data copied from respective native structure. */ - void OnFileTruncateFinish(final FileOperationInfo fileOperationInfo); + void onFileTruncateFinish(final FileOperationInfo fileOperationInfo); /** * A callback function for RocksDB which will be called whenever a file close @@ -295,7 +295,7 @@ public interface EventListener { * @param fileOperationInfo file operation info, * contains data copied from respective native structure. */ - void OnFileCloseFinish(final FileOperationInfo fileOperationInfo); + void onFileCloseFinish(final FileOperationInfo fileOperationInfo); /** * If true, the {@link #onFileReadFinish(FileOperationInfo)} diff --git a/java/src/test/java/org/rocksdb/EventListenerTest.java b/java/src/test/java/org/rocksdb/EventListenerTest.java index eda52ca6f..f7e907cae 100644 --- a/java/src/test/java/org/rocksdb/EventListenerTest.java +++ b/java/src/test/java/org/rocksdb/EventListenerTest.java @@ -1,3 +1,7 @@ +// 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). package org.rocksdb; import static org.assertj.core.api.Assertions.assertThat; @@ -5,15 +9,13 @@ import static org.junit.Assert.*; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Collections; -import java.util.Map; -import java.util.Random; -import java.util.UUID; +import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.rocksdb.AbstractEventListener.EnabledEventCallback; import org.rocksdb.test.TestableEventListener; public class EventListenerTest { @@ -41,10 +43,8 @@ public class EventListenerTest { @Test public void onFlushCompleted() throws RocksDBException { - // Callback is synchronous, but we need mutable container to update boolean value in other - // method final AtomicBoolean wasCbCalled = new AtomicBoolean(); - AbstractEventListener onFlushCompletedListener = new AbstractEventListener() { + final AbstractEventListener onFlushCompletedListener = new AbstractEventListener() { @Override public void onFlushCompleted(final RocksDB rocksDb, final FlushJobInfo flushJobInfo) { assertNotNull(flushJobInfo.getColumnFamilyName()); @@ -57,10 +57,8 @@ public class EventListenerTest { @Test public void onFlushBegin() throws RocksDBException { - // Callback is synchronous, but we need mutable container to update boolean value in other - // method final AtomicBoolean wasCbCalled = new AtomicBoolean(); - AbstractEventListener onFlushBeginListener = new AbstractEventListener() { + final AbstractEventListener onFlushBeginListener = new AbstractEventListener() { @Override public void onFlushBegin(final RocksDB rocksDb, final FlushJobInfo flushJobInfo) { assertNotNull(flushJobInfo.getColumnFamilyName()); @@ -72,7 +70,7 @@ public class EventListenerTest { } void deleteTableFile(final AbstractEventListener el, final AtomicBoolean wasCbCalled) - throws RocksDBException, InterruptedException { + throws RocksDBException { try (final Options opt = new Options().setCreateIfMissing(true).setListeners(Collections.singletonList(el)); final RocksDB db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) { @@ -80,7 +78,7 @@ public class EventListenerTest { final byte[] value = new byte[24]; rand.nextBytes(value); db.put("testKey".getBytes(), value); - RocksDB.LiveFiles liveFiles = db.getLiveFiles(); + final RocksDB.LiveFiles liveFiles = db.getLiveFiles(); assertNotNull(liveFiles); assertNotNull(liveFiles.files); assertFalse(liveFiles.files.isEmpty()); @@ -91,10 +89,8 @@ public class EventListenerTest { @Test public void onTableFileDeleted() throws RocksDBException, InterruptedException { - // Callback is synchronous, but we need mutable container to update boolean value in other - // method final AtomicBoolean wasCbCalled = new AtomicBoolean(); - AbstractEventListener onTableFileDeletedListener = new AbstractEventListener() { + final AbstractEventListener onTableFileDeletedListener = new AbstractEventListener() { @Override public void onTableFileDeleted(final TableFileDeletionInfo tableFileDeletionInfo) { assertNotNull(tableFileDeletionInfo.getDbName()); @@ -120,10 +116,8 @@ public class EventListenerTest { @Test public void onCompactionBegin() throws RocksDBException { - // Callback is synchronous, but we need mutable container to update boolean value in other - // method final AtomicBoolean wasCbCalled = new AtomicBoolean(); - AbstractEventListener onCompactionBeginListener = new AbstractEventListener() { + final AbstractEventListener onCompactionBeginListener = new AbstractEventListener() { @Override public void onCompactionBegin(final RocksDB db, final CompactionJobInfo compactionJobInfo) { assertEquals(CompactionReason.kManualCompaction, compactionJobInfo.compactionReason()); @@ -135,10 +129,8 @@ public class EventListenerTest { @Test public void onCompactionCompleted() throws RocksDBException { - // Callback is synchronous, but we need mutable container to update boolean value in other - // method final AtomicBoolean wasCbCalled = new AtomicBoolean(); - AbstractEventListener onCompactionCompletedListener = new AbstractEventListener() { + final AbstractEventListener onCompactionCompletedListener = new AbstractEventListener() { @Override public void onCompactionCompleted( final RocksDB db, final CompactionJobInfo compactionJobInfo) { @@ -151,10 +143,8 @@ public class EventListenerTest { @Test public void onTableFileCreated() throws RocksDBException { - // Callback is synchronous, but we need mutable container to update boolean value in other - // method final AtomicBoolean wasCbCalled = new AtomicBoolean(); - AbstractEventListener onTableFileCreatedListener = new AbstractEventListener() { + final AbstractEventListener onTableFileCreatedListener = new AbstractEventListener() { @Override public void onTableFileCreated(final TableFileCreationInfo tableFileCreationInfo) { assertEquals(TableFileCreationReason.FLUSH, tableFileCreationInfo.getReason()); @@ -166,10 +156,8 @@ public class EventListenerTest { @Test public void onTableFileCreationStarted() throws RocksDBException { - // Callback is synchronous, but we need mutable container to update boolean value in other - // method final AtomicBoolean wasCbCalled = new AtomicBoolean(); - AbstractEventListener onTableFileCreationStartedListener = new AbstractEventListener() { + final AbstractEventListener onTableFileCreationStartedListener = new AbstractEventListener() { @Override public void onTableFileCreationStarted( final TableFileCreationBriefInfo tableFileCreationBriefInfo) { @@ -197,10 +185,8 @@ public class EventListenerTest { @Test public void onColumnFamilyHandleDeletionStarted() throws RocksDBException { - // Callback is synchronous, but we need mutable container to update boolean value in other - // method final AtomicBoolean wasCbCalled = new AtomicBoolean(); - AbstractEventListener onColumnFamilyHandleDeletionStartedListener = + final AbstractEventListener onColumnFamilyHandleDeletionStartedListener = new AbstractEventListener() { @Override public void onColumnFamilyHandleDeletionStarted( @@ -218,9 +204,9 @@ public class EventListenerTest { new Options().setCreateIfMissing(true).setListeners(Collections.singletonList(el)); final RocksDB db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) { assertThat(db).isNotNull(); - String uuid = UUID.randomUUID().toString(); - SstFileWriter sstFileWriter = new SstFileWriter(new EnvOptions(), opt); - Path externalFilePath = Paths.get(db.getName(), uuid); + final String uuid = UUID.randomUUID().toString(); + final SstFileWriter sstFileWriter = new SstFileWriter(new EnvOptions(), opt); + final Path externalFilePath = Paths.get(db.getName(), uuid); sstFileWriter.open(externalFilePath.toString()); sstFileWriter.put("testKey".getBytes(), uuid.getBytes()); sstFileWriter.finish(); @@ -232,10 +218,8 @@ public class EventListenerTest { @Test public void onExternalFileIngested() throws RocksDBException { - // Callback is synchronous, but we need mutable container to update boolean value in other - // method final AtomicBoolean wasCbCalled = new AtomicBoolean(); - AbstractEventListener onExternalFileIngestedListener = new AbstractEventListener() { + final AbstractEventListener onExternalFileIngestedListener = new AbstractEventListener() { @Override public void onExternalFileIngested( final RocksDB db, final ExternalFileIngestionInfo externalFileIngestionInfo) { @@ -248,8 +232,8 @@ public class EventListenerTest { @Test public void testAllCallbacksInvocation() { - final int TEST_INT_VAL = Integer.MAX_VALUE; - final long TEST_LONG_VAL = Long.MAX_VALUE; + final int TEST_INT_VAL = -1; + final long TEST_LONG_VAL = -1; // Expected test data objects final Map userCollectedPropertiesTestData = Collections.singletonMap("key", "value"); @@ -263,18 +247,18 @@ public class EventListenerTest { "columnFamilyName".getBytes(), "filterPolicyName", "comparatorName", "mergeOperatorName", "prefixExtractorName", "propertyCollectorsNames", "compressionName", userCollectedPropertiesTestData, readablePropertiesTestData, propertiesOffsetsTestData); - final FlushJobInfo flushJobInfoTestData = new FlushJobInfo(TEST_INT_VAL, "testColumnFamily", - "/file/path", TEST_LONG_VAL, TEST_INT_VAL, true, true, TEST_LONG_VAL, TEST_LONG_VAL, - tablePropertiesTestData, (byte) 0x0a); + final FlushJobInfo flushJobInfoTestData = new FlushJobInfo(Integer.MAX_VALUE, + "testColumnFamily", "/file/path", TEST_LONG_VAL, Integer.MAX_VALUE, true, true, + TEST_LONG_VAL, TEST_LONG_VAL, tablePropertiesTestData, (byte) 0x0a); final Status statusTestData = new Status(Status.Code.Incomplete, Status.SubCode.NoSpace, null); final TableFileDeletionInfo tableFileDeletionInfoTestData = - new TableFileDeletionInfo("dbName", "/file/path", TEST_INT_VAL, statusTestData); + new TableFileDeletionInfo("dbName", "/file/path", Integer.MAX_VALUE, statusTestData); final TableFileCreationInfo tableFileCreationInfoTestData = new TableFileCreationInfo(TEST_LONG_VAL, tablePropertiesTestData, statusTestData, "dbName", - "columnFamilyName", "/file/path", TEST_INT_VAL, (byte) 0x03); + "columnFamilyName", "/file/path", Integer.MAX_VALUE, (byte) 0x03); final TableFileCreationBriefInfo tableFileCreationBriefInfoTestData = new TableFileCreationBriefInfo( - "dbName", "columnFamilyName", "/file/path", TEST_INT_VAL, (byte) 0x03); + "dbName", "columnFamilyName", "/file/path", Integer.MAX_VALUE, (byte) 0x03); final MemTableInfo memTableInfoTestData = new MemTableInfo( "columnFamilyName", TEST_LONG_VAL, TEST_LONG_VAL, TEST_LONG_VAL, TEST_LONG_VAL); final FileOperationInfo fileOperationInfoTestData = new FileOperationInfo("/file/path", @@ -285,305 +269,496 @@ public class EventListenerTest { new ExternalFileIngestionInfo("columnFamilyName", "/external/file/path", "/internal/file/path", TEST_LONG_VAL, tablePropertiesTestData); - final int CALLBACKS_COUNT = 22; - final AtomicBoolean[] wasCalled = new AtomicBoolean[CALLBACKS_COUNT]; - for (int i = 0; i < CALLBACKS_COUNT; ++i) { - wasCalled[i] = new AtomicBoolean(); - } - TestableEventListener listener = new TestableEventListener() { + final CapturingTestableEventListener listener = new CapturingTestableEventListener() { @Override public void onFlushCompleted(final RocksDB db, final FlushJobInfo flushJobInfo) { + super.onFlushCompleted(db, flushJobInfo); assertEquals(flushJobInfoTestData, flushJobInfo); - wasCalled[0].set(true); } @Override public void onFlushBegin(final RocksDB db, final FlushJobInfo flushJobInfo) { + super.onFlushBegin(db, flushJobInfo); assertEquals(flushJobInfoTestData, flushJobInfo); - wasCalled[1].set(true); } @Override public void onTableFileDeleted(final TableFileDeletionInfo tableFileDeletionInfo) { + super.onTableFileDeleted(tableFileDeletionInfo); assertEquals(tableFileDeletionInfoTestData, tableFileDeletionInfo); - wasCalled[2].set(true); } @Override public void onCompactionBegin(final RocksDB db, final CompactionJobInfo compactionJobInfo) { + super.onCompactionBegin(db, compactionJobInfo); assertArrayEquals( "compactionColumnFamily".getBytes(), compactionJobInfo.columnFamilyName()); assertEquals(statusTestData, compactionJobInfo.status()); assertEquals(TEST_LONG_VAL, compactionJobInfo.threadId()); - assertEquals(TEST_INT_VAL, compactionJobInfo.jobId()); - assertEquals(TEST_INT_VAL, compactionJobInfo.baseInputLevel()); - assertEquals(TEST_INT_VAL, compactionJobInfo.outputLevel()); + assertEquals(Integer.MAX_VALUE, compactionJobInfo.jobId()); + assertEquals(Integer.MAX_VALUE, compactionJobInfo.baseInputLevel()); + assertEquals(Integer.MAX_VALUE, compactionJobInfo.outputLevel()); assertEquals(Collections.singletonList("inputFile.sst"), compactionJobInfo.inputFiles()); assertEquals(Collections.singletonList("outputFile.sst"), compactionJobInfo.outputFiles()); assertEquals(Collections.singletonMap("tableProperties", tablePropertiesTestData), compactionJobInfo.tableProperties()); assertEquals(CompactionReason.kFlush, compactionJobInfo.compactionReason()); assertEquals(CompressionType.SNAPPY_COMPRESSION, compactionJobInfo.compression()); - wasCalled[3].set(true); } @Override public void onCompactionCompleted( final RocksDB db, final CompactionJobInfo compactionJobInfo) { + super.onCompactionCompleted(db, compactionJobInfo); assertArrayEquals( "compactionColumnFamily".getBytes(), compactionJobInfo.columnFamilyName()); assertEquals(statusTestData, compactionJobInfo.status()); assertEquals(TEST_LONG_VAL, compactionJobInfo.threadId()); - assertEquals(TEST_INT_VAL, compactionJobInfo.jobId()); - assertEquals(TEST_INT_VAL, compactionJobInfo.baseInputLevel()); - assertEquals(TEST_INT_VAL, compactionJobInfo.outputLevel()); + assertEquals(Integer.MAX_VALUE, compactionJobInfo.jobId()); + assertEquals(Integer.MAX_VALUE, compactionJobInfo.baseInputLevel()); + assertEquals(Integer.MAX_VALUE, compactionJobInfo.outputLevel()); assertEquals(Collections.singletonList("inputFile.sst"), compactionJobInfo.inputFiles()); assertEquals(Collections.singletonList("outputFile.sst"), compactionJobInfo.outputFiles()); assertEquals(Collections.singletonMap("tableProperties", tablePropertiesTestData), compactionJobInfo.tableProperties()); assertEquals(CompactionReason.kFlush, compactionJobInfo.compactionReason()); assertEquals(CompressionType.SNAPPY_COMPRESSION, compactionJobInfo.compression()); - wasCalled[4].set(true); } @Override public void onTableFileCreated(final TableFileCreationInfo tableFileCreationInfo) { + super.onTableFileCreated(tableFileCreationInfo); assertEquals(tableFileCreationInfoTestData, tableFileCreationInfo); - wasCalled[5].set(true); } @Override public void onTableFileCreationStarted( final TableFileCreationBriefInfo tableFileCreationBriefInfo) { + super.onTableFileCreationStarted(tableFileCreationBriefInfo); assertEquals(tableFileCreationBriefInfoTestData, tableFileCreationBriefInfo); - wasCalled[6].set(true); } @Override public void onMemTableSealed(final MemTableInfo memTableInfo) { + super.onMemTableSealed(memTableInfo); assertEquals(memTableInfoTestData, memTableInfo); - wasCalled[7].set(true); } @Override public void onColumnFamilyHandleDeletionStarted(final ColumnFamilyHandle columnFamilyHandle) { - wasCalled[8].set(true); + super.onColumnFamilyHandleDeletionStarted(columnFamilyHandle); } @Override public void onExternalFileIngested( final RocksDB db, final ExternalFileIngestionInfo externalFileIngestionInfo) { + super.onExternalFileIngested(db, externalFileIngestionInfo); assertEquals(externalFileIngestionInfoTestData, externalFileIngestionInfo); - wasCalled[9].set(true); } @Override public void onBackgroundError( final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) { - wasCalled[10].set(true); + super.onBackgroundError(backgroundErrorReason, backgroundError); } @Override public void onStallConditionsChanged(final WriteStallInfo writeStallInfo) { + super.onStallConditionsChanged(writeStallInfo); assertEquals(writeStallInfoTestData, writeStallInfo); - wasCalled[11].set(true); } @Override public void onFileReadFinish(final FileOperationInfo fileOperationInfo) { + super.onFileReadFinish(fileOperationInfo); assertEquals(fileOperationInfoTestData, fileOperationInfo); - wasCalled[12].set(true); } @Override public void onFileWriteFinish(final FileOperationInfo fileOperationInfo) { + super.onFileWriteFinish(fileOperationInfo); assertEquals(fileOperationInfoTestData, fileOperationInfo); - wasCalled[13].set(true); } @Override - public void OnFileFlushFinish(final FileOperationInfo fileOperationInfo) { + public void onFileFlushFinish(final FileOperationInfo fileOperationInfo) { + super.onFileFlushFinish(fileOperationInfo); assertEquals(fileOperationInfoTestData, fileOperationInfo); - wasCalled[14].set(true); } @Override - public void OnFileSyncFinish(final FileOperationInfo fileOperationInfo) { + public void onFileSyncFinish(final FileOperationInfo fileOperationInfo) { + super.onFileSyncFinish(fileOperationInfo); assertEquals(fileOperationInfoTestData, fileOperationInfo); - wasCalled[15].set(true); } @Override - public void OnFileRangeSyncFinish(final FileOperationInfo fileOperationInfo) { + public void onFileRangeSyncFinish(final FileOperationInfo fileOperationInfo) { + super.onFileRangeSyncFinish(fileOperationInfo); assertEquals(fileOperationInfoTestData, fileOperationInfo); - wasCalled[16].set(true); } @Override - public void OnFileTruncateFinish(final FileOperationInfo fileOperationInfo) { + public void onFileTruncateFinish(final FileOperationInfo fileOperationInfo) { assertEquals(fileOperationInfoTestData, fileOperationInfo); - wasCalled[17].set(true); + super.onFileTruncateFinish(fileOperationInfo); } @Override - public void OnFileCloseFinish(final FileOperationInfo fileOperationInfo) { + public void onFileCloseFinish(final FileOperationInfo fileOperationInfo) { + super.onFileCloseFinish(fileOperationInfo); assertEquals(fileOperationInfoTestData, fileOperationInfo); - wasCalled[18].set(true); } @Override public boolean shouldBeNotifiedOnFileIO() { - wasCalled[19].set(true); + super.shouldBeNotifiedOnFileIO(); return false; } @Override public boolean onErrorRecoveryBegin( final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) { + super.onErrorRecoveryBegin(backgroundErrorReason, backgroundError); assertEquals(BackgroundErrorReason.FLUSH, backgroundErrorReason); assertEquals(statusTestData, backgroundError); - wasCalled[20].set(true); return true; } @Override public void onErrorRecoveryCompleted(final Status oldBackgroundError) { + super.onErrorRecoveryCompleted(oldBackgroundError); assertEquals(statusTestData, oldBackgroundError); - wasCalled[21].set(true); } }; + + // test action listener.invokeAllCallbacks(); - for (int i = 0; i < CALLBACKS_COUNT; ++i) { - assertTrue("Callback method " + i + " was not called", wasCalled[i].get()); - } + + // assert + assertAllEventsCalled(listener); } @Test public void testEnabledCallbacks() { - final AtomicBoolean wasOnMemTableSealedCalled = new AtomicBoolean(); - final AtomicBoolean wasOnErrorRecoveryCompletedCalled = new AtomicBoolean(); - final TestableEventListener listener = new TestableEventListener( - AbstractEventListener.EnabledEventCallback.ON_MEMTABLE_SEALED, - AbstractEventListener.EnabledEventCallback.ON_ERROR_RECOVERY_COMPLETED) { - @Override - public void onFlushCompleted(final RocksDB db, final FlushJobInfo flushJobInfo) { - fail("onFlushCompleted was not enabled"); - } + final EnabledEventCallback enabledEvents[] = { + EnabledEventCallback.ON_MEMTABLE_SEALED, EnabledEventCallback.ON_ERROR_RECOVERY_COMPLETED}; - @Override - public void onFlushBegin(final RocksDB db, final FlushJobInfo flushJobInfo) { - fail("onFlushBegin was not enabled"); - } + final CapturingTestableEventListener listener = + new CapturingTestableEventListener(enabledEvents); - @Override - public void onTableFileDeleted(final TableFileDeletionInfo tableFileDeletionInfo) { - fail("onTableFileDeleted was not enabled"); - } + // test action + listener.invokeAllCallbacks(); - @Override - public void onCompactionBegin(final RocksDB db, final CompactionJobInfo compactionJobInfo) { - fail("onCompactionBegin was not enabled"); - } + // assert + assertEventsCalled(listener, enabledEvents); + } - @Override - public void onCompactionCompleted( - final RocksDB db, final CompactionJobInfo compactionJobInfo) { - fail("onCompactionCompleted was not enabled"); - } + private static void assertAllEventsCalled( + final CapturingTestableEventListener capturingTestableEventListener) { + assertEventsCalled(capturingTestableEventListener, EnumSet.allOf(EnabledEventCallback.class)); + } - @Override - public void onTableFileCreated(final TableFileCreationInfo tableFileCreationInfo) { - fail("onTableFileCreated was not enabled"); - } + private static void assertEventsCalled( + final CapturingTestableEventListener capturingTestableEventListener, + final EnabledEventCallback[] expected) { + assertEventsCalled(capturingTestableEventListener, EnumSet.copyOf(Arrays.asList(expected))); + } - @Override - public void onTableFileCreationStarted( - final TableFileCreationBriefInfo tableFileCreationBriefInfo) { - fail("onTableFileCreationStarted was not enabled"); - } + private static void assertEventsCalled( + final CapturingTestableEventListener capturingTestableEventListener, + final EnumSet expected) { + final ListenerEvents capturedEvents = capturingTestableEventListener.capturedListenerEvents; - @Override - public void onMemTableSealed(final MemTableInfo memTableInfo) { - wasOnMemTableSealedCalled.set(true); - } + if (expected.contains(EnabledEventCallback.ON_FLUSH_COMPLETED)) { + assertTrue("onFlushCompleted was not called", capturedEvents.flushCompleted); + } else { + assertFalse("onFlushCompleted was not called", capturedEvents.flushCompleted); + } - @Override - public void onColumnFamilyHandleDeletionStarted(final ColumnFamilyHandle columnFamilyHandle) { - fail("onColumnFamilyHandleDeletionStarted was not enabled"); - } + if (expected.contains(EnabledEventCallback.ON_FLUSH_BEGIN)) { + assertTrue("onFlushBegin was not called", capturedEvents.flushBegin); + } else { + assertFalse("onFlushBegin was called", capturedEvents.flushBegin); + } - @Override - public void onExternalFileIngested( - final RocksDB db, final ExternalFileIngestionInfo externalFileIngestionInfo) { - fail("onExternalFileIngested was not enabled"); - } + if (expected.contains(EnabledEventCallback.ON_TABLE_FILE_DELETED)) { + assertTrue("onTableFileDeleted was not called", capturedEvents.tableFileDeleted); + } else { + assertFalse("onTableFileDeleted was called", capturedEvents.tableFileDeleted); + } - @Override - public void onBackgroundError( - final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) { - fail("onBackgroundError was not enabled"); - } + if (expected.contains(EnabledEventCallback.ON_COMPACTION_BEGIN)) { + assertTrue("onCompactionBegin was not called", capturedEvents.compactionBegin); + } else { + assertFalse("onCompactionBegin was called", capturedEvents.compactionBegin); + } - @Override - public void onStallConditionsChanged(final WriteStallInfo writeStallInfo) { - fail("onStallConditionsChanged was not enabled"); - } + if (expected.contains(EnabledEventCallback.ON_COMPACTION_COMPLETED)) { + assertTrue("onCompactionCompleted was not called", capturedEvents.compactionCompleted); + } else { + assertFalse("onCompactionCompleted was called", capturedEvents.compactionCompleted); + } - @Override - public void onFileReadFinish(final FileOperationInfo fileOperationInfo) { - fail("onFileReadFinish was not enabled"); - } + if (expected.contains(EnabledEventCallback.ON_TABLE_FILE_CREATED)) { + assertTrue("onTableFileCreated was not called", capturedEvents.tableFileCreated); + } else { + assertFalse("onTableFileCreated was called", capturedEvents.tableFileCreated); + } - @Override - public void onFileWriteFinish(final FileOperationInfo fileOperationInfo) { - fail("onFileWriteFinish was not enabled"); - } + if (expected.contains(EnabledEventCallback.ON_TABLE_FILE_CREATION_STARTED)) { + assertTrue( + "onTableFileCreationStarted was not called", capturedEvents.tableFileCreationStarted); + } else { + assertFalse("onTableFileCreationStarted was called", capturedEvents.tableFileCreationStarted); + } - @Override - public void OnFileFlushFinish(final FileOperationInfo fileOperationInfo) { - fail("OnFileFlushFinish was not enabled"); - } + if (expected.contains(EnabledEventCallback.ON_MEMTABLE_SEALED)) { + assertTrue("onMemTableSealed was not called", capturedEvents.memTableSealed); + } else { + assertFalse("onMemTableSealed was called", capturedEvents.memTableSealed); + } - @Override - public void OnFileSyncFinish(final FileOperationInfo fileOperationInfo) { - fail("OnFileSyncFinish was not enabled"); - } + if (expected.contains(EnabledEventCallback.ON_COLUMN_FAMILY_HANDLE_DELETION_STARTED)) { + assertTrue("onColumnFamilyHandleDeletionStarted was not called", + capturedEvents.columnFamilyHandleDeletionStarted); + } else { + assertFalse("onColumnFamilyHandleDeletionStarted was called", + capturedEvents.columnFamilyHandleDeletionStarted); + } - @Override - public void OnFileRangeSyncFinish(final FileOperationInfo fileOperationInfo) { - fail("OnFileRangeSyncFinish was not enabled"); - } + if (expected.contains(EnabledEventCallback.ON_EXTERNAL_FILE_INGESTED)) { + assertTrue("onExternalFileIngested was not called", capturedEvents.externalFileIngested); + } else { + assertFalse("onExternalFileIngested was called", capturedEvents.externalFileIngested); + } - @Override - public void OnFileTruncateFinish(final FileOperationInfo fileOperationInfo) { - fail("OnFileTruncateFinish was not enabled"); - } + if (expected.contains(EnabledEventCallback.ON_BACKGROUND_ERROR)) { + assertTrue("onBackgroundError was not called", capturedEvents.backgroundError); + } else { + assertFalse("onBackgroundError was called", capturedEvents.backgroundError); + } - @Override - public void OnFileCloseFinish(final FileOperationInfo fileOperationInfo) { - fail("OnFileCloseFinish was not enabled"); - } + if (expected.contains(EnabledEventCallback.ON_STALL_CONDITIONS_CHANGED)) { + assertTrue("onStallConditionsChanged was not called", capturedEvents.stallConditionsChanged); + } else { + assertFalse("onStallConditionsChanged was called", capturedEvents.stallConditionsChanged); + } - @Override - public boolean shouldBeNotifiedOnFileIO() { - fail("shouldBeNotifiedOnFileIO was not enabled"); - return false; - } + if (expected.contains(EnabledEventCallback.ON_FILE_READ_FINISH)) { + assertTrue("onFileReadFinish was not called", capturedEvents.fileReadFinish); + } else { + assertFalse("onFileReadFinish was called", capturedEvents.fileReadFinish); + } - @Override - public boolean onErrorRecoveryBegin( - final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) { - fail("onErrorRecoveryBegin was not enabled"); - return true; - } + if (expected.contains(EnabledEventCallback.ON_FILE_WRITE_FINISH)) { + assertTrue("onFileWriteFinish was not called", capturedEvents.fileWriteFinish); + } else { + assertFalse("onFileWriteFinish was called", capturedEvents.fileWriteFinish); + } - @Override - public void onErrorRecoveryCompleted(final Status oldBackgroundError) { - wasOnErrorRecoveryCompletedCalled.set(true); - } - }; - listener.invokeAllCallbacks(); - assertTrue(wasOnMemTableSealedCalled.get()); - assertTrue(wasOnErrorRecoveryCompletedCalled.get()); + if (expected.contains(EnabledEventCallback.ON_FILE_FLUSH_FINISH)) { + assertTrue("onFileFlushFinish was not called", capturedEvents.fileFlushFinish); + } else { + assertFalse("onFileFlushFinish was called", capturedEvents.fileFlushFinish); + } + + if (expected.contains(EnabledEventCallback.ON_FILE_SYNC_FINISH)) { + assertTrue("onFileSyncFinish was not called", capturedEvents.fileSyncFinish); + } else { + assertFalse("onFileSyncFinish was called", capturedEvents.fileSyncFinish); + } + + if (expected.contains(EnabledEventCallback.ON_FILE_RANGE_SYNC_FINISH)) { + assertTrue("onFileRangeSyncFinish was not called", capturedEvents.fileRangeSyncFinish); + } else { + assertFalse("onFileRangeSyncFinish was called", capturedEvents.fileRangeSyncFinish); + } + + if (expected.contains(EnabledEventCallback.ON_FILE_TRUNCATE_FINISH)) { + assertTrue("onFileTruncateFinish was not called", capturedEvents.fileTruncateFinish); + } else { + assertFalse("onFileTruncateFinish was called", capturedEvents.fileTruncateFinish); + } + + if (expected.contains(EnabledEventCallback.ON_FILE_CLOSE_FINISH)) { + assertTrue("onFileCloseFinish was not called", capturedEvents.fileCloseFinish); + } else { + assertFalse("onFileCloseFinish was called", capturedEvents.fileCloseFinish); + } + + if (expected.contains(EnabledEventCallback.SHOULD_BE_NOTIFIED_ON_FILE_IO)) { + assertTrue( + "shouldBeNotifiedOnFileIO was not called", capturedEvents.shouldBeNotifiedOnFileIO); + } else { + assertFalse("shouldBeNotifiedOnFileIO was called", capturedEvents.shouldBeNotifiedOnFileIO); + } + + if (expected.contains(EnabledEventCallback.ON_ERROR_RECOVERY_BEGIN)) { + assertTrue("onErrorRecoveryBegin was not called", capturedEvents.errorRecoveryBegin); + } else { + assertFalse("onErrorRecoveryBegin was called", capturedEvents.errorRecoveryBegin); + } + + if (expected.contains(EnabledEventCallback.ON_ERROR_RECOVERY_COMPLETED)) { + assertTrue("onErrorRecoveryCompleted was not called", capturedEvents.errorRecoveryCompleted); + } else { + assertFalse("onErrorRecoveryCompleted was called", capturedEvents.errorRecoveryCompleted); + } + } + + /** + * Members are volatile as they may be written + * and read by different threads. + */ + private static class ListenerEvents { + volatile boolean flushCompleted; + volatile boolean flushBegin; + volatile boolean tableFileDeleted; + volatile boolean compactionBegin; + volatile boolean compactionCompleted; + volatile boolean tableFileCreated; + volatile boolean tableFileCreationStarted; + volatile boolean memTableSealed; + volatile boolean columnFamilyHandleDeletionStarted; + volatile boolean externalFileIngested; + volatile boolean backgroundError; + volatile boolean stallConditionsChanged; + volatile boolean fileReadFinish; + volatile boolean fileWriteFinish; + volatile boolean fileFlushFinish; + volatile boolean fileSyncFinish; + volatile boolean fileRangeSyncFinish; + volatile boolean fileTruncateFinish; + volatile boolean fileCloseFinish; + volatile boolean shouldBeNotifiedOnFileIO; + volatile boolean errorRecoveryBegin; + volatile boolean errorRecoveryCompleted; + } + + private static class CapturingTestableEventListener extends TestableEventListener { + final ListenerEvents capturedListenerEvents = new ListenerEvents(); + + public CapturingTestableEventListener() {} + + public CapturingTestableEventListener(final EnabledEventCallback... enabledEventCallbacks) { + super(enabledEventCallbacks); + } + + @Override + public void onFlushCompleted(final RocksDB db, final FlushJobInfo flushJobInfo) { + capturedListenerEvents.flushCompleted = true; + } + + @Override + public void onFlushBegin(final RocksDB db, final FlushJobInfo flushJobInfo) { + capturedListenerEvents.flushBegin = true; + } + + @Override + public void onTableFileDeleted(final TableFileDeletionInfo tableFileDeletionInfo) { + capturedListenerEvents.tableFileDeleted = true; + } + + @Override + public void onCompactionBegin(final RocksDB db, final CompactionJobInfo compactionJobInfo) { + capturedListenerEvents.compactionBegin = true; + } + + @Override + public void onCompactionCompleted(final RocksDB db, final CompactionJobInfo compactionJobInfo) { + capturedListenerEvents.compactionCompleted = true; + } + + @Override + public void onTableFileCreated(final TableFileCreationInfo tableFileCreationInfo) { + capturedListenerEvents.tableFileCreated = true; + } + + @Override + public void onTableFileCreationStarted( + final TableFileCreationBriefInfo tableFileCreationBriefInfo) { + capturedListenerEvents.tableFileCreationStarted = true; + } + + @Override + public void onMemTableSealed(final MemTableInfo memTableInfo) { + capturedListenerEvents.memTableSealed = true; + } + + @Override + public void onColumnFamilyHandleDeletionStarted(final ColumnFamilyHandle columnFamilyHandle) { + capturedListenerEvents.columnFamilyHandleDeletionStarted = true; + } + + @Override + public void onExternalFileIngested( + final RocksDB db, final ExternalFileIngestionInfo externalFileIngestionInfo) { + capturedListenerEvents.externalFileIngested = true; + } + + @Override + public void onBackgroundError( + final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) { + capturedListenerEvents.backgroundError = true; + } + + @Override + public void onStallConditionsChanged(final WriteStallInfo writeStallInfo) { + capturedListenerEvents.stallConditionsChanged = true; + } + + @Override + public void onFileReadFinish(final FileOperationInfo fileOperationInfo) { + capturedListenerEvents.fileReadFinish = true; + } + + @Override + public void onFileWriteFinish(final FileOperationInfo fileOperationInfo) { + capturedListenerEvents.fileWriteFinish = true; + } + + @Override + public void onFileFlushFinish(final FileOperationInfo fileOperationInfo) { + capturedListenerEvents.fileFlushFinish = true; + } + + @Override + public void onFileSyncFinish(final FileOperationInfo fileOperationInfo) { + capturedListenerEvents.fileSyncFinish = true; + } + + @Override + public void onFileRangeSyncFinish(final FileOperationInfo fileOperationInfo) { + capturedListenerEvents.fileRangeSyncFinish = true; + } + + @Override + public void onFileTruncateFinish(final FileOperationInfo fileOperationInfo) { + capturedListenerEvents.fileTruncateFinish = true; + } + + @Override + public void onFileCloseFinish(final FileOperationInfo fileOperationInfo) { + capturedListenerEvents.fileCloseFinish = true; + } + + @Override + public boolean shouldBeNotifiedOnFileIO() { + capturedListenerEvents.shouldBeNotifiedOnFileIO = true; + return false; + } + + @Override + public boolean onErrorRecoveryBegin( + final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) { + capturedListenerEvents.errorRecoveryBegin = true; + return true; + } + + @Override + public void onErrorRecoveryCompleted(final Status oldBackgroundError) { + capturedListenerEvents.errorRecoveryCompleted = true; + } } } diff --git a/java/src/test/java/org/rocksdb/test/TestableEventListener.java b/java/src/test/java/org/rocksdb/test/TestableEventListener.java index a15d3cb23..865ad5cf7 100644 --- a/java/src/test/java/org/rocksdb/test/TestableEventListener.java +++ b/java/src/test/java/org/rocksdb/test/TestableEventListener.java @@ -1,3 +1,7 @@ +// 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). package org.rocksdb.test; import org.rocksdb.AbstractEventListener; diff --git a/port/jemalloc_helper.h b/port/jemalloc_helper.h index dd31262d3..c0ef19a40 100644 --- a/port/jemalloc_helper.h +++ b/port/jemalloc_helper.h @@ -38,6 +38,24 @@ static inline bool HasJemalloc() { return true; } #else +// definitions for compatibility with older versions of jemalloc +#if !defined(JEMALLOC_ALLOCATOR) +#define JEMALLOC_ALLOCATOR +#endif +#if !defined(JEMALLOC_RESTRICT_RETURN) +#define JEMALLOC_RESTRICT_RETURN +#endif +#if !defined(JEMALLOC_NOTHROW) +#define JEMALLOC_NOTHROW JEMALLOC_ATTR(nothrow) +#endif +#if !defined(JEMALLOC_ALLOC_SIZE) +#ifdef JEMALLOC_HAVE_ATTR_ALLOC_SIZE +#define JEMALLOC_ALLOC_SIZE(s) JEMALLOC_ATTR(alloc_size(s)) +#else +#define JEMALLOC_ALLOC_SIZE(s) +#endif +#endif + // Declare non-standard jemalloc APIs as weak symbols. We can null-check these // symbols to detect whether jemalloc is linked with the binary. extern "C" JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN void JEMALLOC_NOTHROW *