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
This commit is contained in:
Adam Retter 2020-12-18 16:11:17 -08:00 committed by Facebook GitHub Bot
parent 75e4af14e0
commit 62afa968c2
8 changed files with 470 additions and 266 deletions

View File

@ -2253,7 +2253,7 @@ rocksdbjavastaticreleasedocker: rocksdbjavastatic rocksdbjavastaticdockerx86 roc
rocksdbjavastaticdockerx86: rocksdbjavastaticdockerx86:
mkdir -p java/target 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: rocksdbjavastaticdockerx86_64:
mkdir -p java/target mkdir -p java/target
@ -2269,7 +2269,7 @@ rocksdbjavastaticdockerarm64v8:
rocksdbjavastaticdockerx86musl: rocksdbjavastaticdockerx86musl:
mkdir -p java/target 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: rocksdbjavastaticdockerx86_64musl:
mkdir -p java/target mkdir -p java/target

View File

@ -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 * @param env A pointer to the Java environment
* *
@ -7965,13 +7965,13 @@ class AbstractEventListenerJni
jclass jclazz = getJClass(env); jclass jclazz = getJClass(env);
assert(jclazz != nullptr); assert(jclazz != nullptr);
static jmethodID mid = env->GetMethodID( static jmethodID mid = env->GetMethodID(
jclazz, "OnFileFlushFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); jclazz, "onFileFlushFinish", "(Lorg/rocksdb/FileOperationInfo;)V");
assert(mid != nullptr); assert(mid != nullptr);
return mid; return mid;
} }
/** /**
* Get the Java Method: AbstractEventListener#OnFileSyncFinish * Get the Java Method: AbstractEventListener#onFileSyncFinish
* *
* @param env A pointer to the Java environment * @param env A pointer to the Java environment
* *
@ -7981,13 +7981,13 @@ class AbstractEventListenerJni
jclass jclazz = getJClass(env); jclass jclazz = getJClass(env);
assert(jclazz != nullptr); assert(jclazz != nullptr);
static jmethodID mid = env->GetMethodID( static jmethodID mid = env->GetMethodID(
jclazz, "OnFileSyncFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); jclazz, "onFileSyncFinish", "(Lorg/rocksdb/FileOperationInfo;)V");
assert(mid != nullptr); assert(mid != nullptr);
return mid; return mid;
} }
/** /**
* Get the Java Method: AbstractEventListener#OnFileRangeSyncFinish * Get the Java Method: AbstractEventListener#onFileRangeSyncFinish
* *
* @param env A pointer to the Java environment * @param env A pointer to the Java environment
* *
@ -7997,13 +7997,13 @@ class AbstractEventListenerJni
jclass jclazz = getJClass(env); jclass jclazz = getJClass(env);
assert(jclazz != nullptr); assert(jclazz != nullptr);
static jmethodID mid = env->GetMethodID( static jmethodID mid = env->GetMethodID(
jclazz, "OnFileRangeSyncFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); jclazz, "onFileRangeSyncFinish", "(Lorg/rocksdb/FileOperationInfo;)V");
assert(mid != nullptr); assert(mid != nullptr);
return mid; return mid;
} }
/** /**
* Get the Java Method: AbstractEventListener#OnFileTruncateFinish * Get the Java Method: AbstractEventListener#onFileTruncateFinish
* *
* @param env A pointer to the Java environment * @param env A pointer to the Java environment
* *
@ -8013,13 +8013,13 @@ class AbstractEventListenerJni
jclass jclazz = getJClass(env); jclass jclazz = getJClass(env);
assert(jclazz != nullptr); assert(jclazz != nullptr);
static jmethodID mid = env->GetMethodID( static jmethodID mid = env->GetMethodID(
jclazz, "OnFileTruncateFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); jclazz, "onFileTruncateFinish", "(Lorg/rocksdb/FileOperationInfo;)V");
assert(mid != nullptr); assert(mid != nullptr);
return mid; return mid;
} }
/** /**
* Get the Java Method: AbstractEventListener#OnFileCloseFinish * Get the Java Method: AbstractEventListener#onFileCloseFinish
* *
* @param env A pointer to the Java environment * @param env A pointer to the Java environment
* *
@ -8029,7 +8029,7 @@ class AbstractEventListenerJni
jclass jclazz = getJClass(env); jclass jclazz = getJClass(env);
assert(jclazz != nullptr); assert(jclazz != nullptr);
static jmethodID mid = env->GetMethodID( static jmethodID mid = env->GetMethodID(
jclazz, "OnFileCloseFinish", "(Lorg/rocksdb/FileOperationInfo;)V"); jclazz, "onFileCloseFinish", "(Lorg/rocksdb/FileOperationInfo;)V");
assert(mid != nullptr); assert(mid != nullptr);
return mid; return mid;
} }

View File

@ -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 <climits> #include <climits>
#include <cstdint>
#include <utility> #include <utility>
#include "include/org_rocksdb_test_TestableEventListener.h" #include "include/org_rocksdb_test_TestableEventListener.h"
#include "rocksdb/listener.h" #include "rocksdb/listener.h"
#include "rocksdb/status.h"
#include "rocksdb/table_properties.h"
using namespace ROCKSDB_NAMESPACE; using namespace ROCKSDB_NAMESPACE;
static TableProperties newTablePropertiesForTest() { static TableProperties newTablePropertiesForTest() {
TableProperties table_properties; TableProperties table_properties;
table_properties.data_size = LLONG_MAX; table_properties.data_size = UINT64_MAX;
table_properties.index_size = LLONG_MAX; table_properties.index_size = UINT64_MAX;
table_properties.index_partitions = LLONG_MAX; table_properties.index_partitions = UINT64_MAX;
table_properties.top_level_index_size = LLONG_MAX; table_properties.top_level_index_size = UINT64_MAX;
table_properties.index_key_is_user_key = LLONG_MAX; table_properties.index_key_is_user_key = UINT64_MAX;
table_properties.index_value_is_delta_encoded = LLONG_MAX; table_properties.index_value_is_delta_encoded = UINT64_MAX;
table_properties.filter_size = LLONG_MAX; table_properties.filter_size = UINT64_MAX;
table_properties.raw_key_size = LLONG_MAX; table_properties.raw_key_size = UINT64_MAX;
table_properties.raw_value_size = LLONG_MAX; table_properties.raw_value_size = UINT64_MAX;
table_properties.num_data_blocks = LLONG_MAX; table_properties.num_data_blocks = UINT64_MAX;
table_properties.num_entries = LLONG_MAX; table_properties.num_entries = UINT64_MAX;
table_properties.num_deletions = LLONG_MAX; table_properties.num_deletions = UINT64_MAX;
table_properties.num_merge_operands = LLONG_MAX; table_properties.num_merge_operands = UINT64_MAX;
table_properties.num_range_deletions = LLONG_MAX; table_properties.num_range_deletions = UINT64_MAX;
table_properties.format_version = LLONG_MAX; table_properties.format_version = UINT64_MAX;
table_properties.fixed_key_len = LLONG_MAX; table_properties.fixed_key_len = UINT64_MAX;
table_properties.column_family_id = LLONG_MAX; table_properties.column_family_id = UINT64_MAX;
table_properties.creation_time = LLONG_MAX; table_properties.creation_time = UINT64_MAX;
table_properties.oldest_key_time = LLONG_MAX; table_properties.oldest_key_time = UINT64_MAX;
table_properties.file_creation_time = LLONG_MAX; table_properties.file_creation_time = UINT64_MAX;
table_properties.db_id = "dbId"; table_properties.db_id = "dbId";
table_properties.db_session_id = "sessionId"; table_properties.db_session_id = "sessionId";
table_properties.column_family_name = "columnFamilyName"; table_properties.column_family_name = "columnFamilyName";
@ -40,7 +47,7 @@ static TableProperties newTablePropertiesForTest() {
table_properties.compression_options = "compressionOptions"; table_properties.compression_options = "compressionOptions";
table_properties.user_collected_properties = {{"key", "value"}}; table_properties.user_collected_properties = {{"key", "value"}};
table_properties.readable_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; 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_id = INT_MAX;
flush_job_info.cf_name = "testColumnFamily"; flush_job_info.cf_name = "testColumnFamily";
flush_job_info.file_path = "/file/path"; flush_job_info.file_path = "/file/path";
flush_job_info.file_number = LLONG_MAX; flush_job_info.file_number = UINT64_MAX;
flush_job_info.oldest_blob_file_number = LLONG_MAX; flush_job_info.oldest_blob_file_number = UINT64_MAX;
flush_job_info.thread_id = LLONG_MAX; flush_job_info.thread_id = UINT64_MAX;
flush_job_info.job_id = INT_MAX; flush_job_info.job_id = INT_MAX;
flush_job_info.triggered_writes_slowdown = true; flush_job_info.triggered_writes_slowdown = true;
flush_job_info.triggered_writes_stop = true; flush_job_info.triggered_writes_stop = true;
flush_job_info.smallest_seqno = LLONG_MAX; flush_job_info.smallest_seqno = UINT64_MAX;
flush_job_info.largest_seqno = LLONG_MAX; flush_job_info.largest_seqno = UINT64_MAX;
flush_job_info.table_properties = table_properties; flush_job_info.table_properties = table_properties;
flush_job_info.flush_reason = FlushReason::kManualFlush; flush_job_info.flush_reason = FlushReason::kManualFlush;
@ -86,10 +93,10 @@ void Java_org_rocksdb_test_TestableEventListener_invokeAllCallbacks(
el->OnTableFileDeleted(file_deletion_info); el->OnTableFileDeleted(file_deletion_info);
CompactionJobInfo compaction_job_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.cf_name = "compactionColumnFamily";
compaction_job_info.status = status; 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.job_id = INT_MAX;
compaction_job_info.base_input_level = INT_MAX; compaction_job_info.base_input_level = INT_MAX;
compaction_job_info.output_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); el->OnCompactionCompleted(nullptr, compaction_job_info);
TableFileCreationInfo file_creation_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.table_properties = table_properties;
file_creation_info.status = status; file_creation_info.status = status;
file_creation_info.file_checksum = "fileChecksum"; file_creation_info.file_checksum = "fileChecksum";
@ -133,10 +140,10 @@ void Java_org_rocksdb_test_TestableEventListener_invokeAllCallbacks(
MemTableInfo mem_table_info; MemTableInfo mem_table_info;
mem_table_info.cf_name = "columnFamilyName"; mem_table_info.cf_name = "columnFamilyName";
mem_table_info.first_seqno = LLONG_MAX; mem_table_info.first_seqno = UINT64_MAX;
mem_table_info.earliest_seqno = LLONG_MAX; mem_table_info.earliest_seqno = UINT64_MAX;
mem_table_info.num_entries = LLONG_MAX; mem_table_info.num_entries = UINT64_MAX;
mem_table_info.num_deletes = LLONG_MAX; mem_table_info.num_deletes = UINT64_MAX;
el->OnMemTableSealed(mem_table_info); el->OnMemTableSealed(mem_table_info);
el->OnColumnFamilyHandleDeletionStarted(nullptr); el->OnColumnFamilyHandleDeletionStarted(nullptr);
@ -145,7 +152,7 @@ void Java_org_rocksdb_test_TestableEventListener_invokeAllCallbacks(
file_ingestion_info.cf_name = "columnFamilyName"; file_ingestion_info.cf_name = "columnFamilyName";
file_ingestion_info.external_file_path = "/external/file/path"; file_ingestion_info.external_file_path = "/external/file/path";
file_ingestion_info.internal_file_path = "/internal/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; file_ingestion_info.table_properties = table_properties;
el->OnExternalFileIngested(nullptr, file_ingestion_info); el->OnExternalFileIngested(nullptr, file_ingestion_info);
@ -169,8 +176,8 @@ void Java_org_rocksdb_test_TestableEventListener_invokeAllCallbacks(
std::chrono::nanoseconds>( std::chrono::nanoseconds>(
std::chrono::nanoseconds(1600699425000000000ll)), std::chrono::nanoseconds(1600699425000000000ll)),
status); status);
op_info.offset = LLONG_MAX; op_info.offset = UINT64_MAX;
op_info.length = LLONG_MAX; op_info.length = SIZE_MAX;
op_info.status = status; op_info.status = status;
el->OnFileReadFinish(op_info); el->OnFileReadFinish(op_info);

View File

@ -265,27 +265,27 @@ public abstract class AbstractEventListener extends RocksCallbackObject implemen
} }
@Override @Override
public void OnFileFlushFinish(final FileOperationInfo fileOperationInfo) { public void onFileFlushFinish(final FileOperationInfo fileOperationInfo) {
// no-op // no-op
} }
@Override @Override
public void OnFileSyncFinish(final FileOperationInfo fileOperationInfo) { public void onFileSyncFinish(final FileOperationInfo fileOperationInfo) {
// no-op // no-op
} }
@Override @Override
public void OnFileRangeSyncFinish(final FileOperationInfo fileOperationInfo) { public void onFileRangeSyncFinish(final FileOperationInfo fileOperationInfo) {
// no-op // no-op
} }
@Override @Override
public void OnFileTruncateFinish(final FileOperationInfo fileOperationInfo) { public void onFileTruncateFinish(final FileOperationInfo fileOperationInfo) {
// no-op // no-op
} }
@Override @Override
public void OnFileCloseFinish(final FileOperationInfo fileOperationInfo) { public void onFileCloseFinish(final FileOperationInfo fileOperationInfo) {
// no-op // no-op
} }

View File

@ -259,7 +259,7 @@ public interface EventListener {
* @param fileOperationInfo file operation info, * @param fileOperationInfo file operation info,
* contains data copied from respective native structure. * 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 * 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, * @param fileOperationInfo file operation info,
* contains data copied from respective native structure. * 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 * A callback function for RocksDB which will be called whenever a file
@ -277,7 +277,7 @@ public interface EventListener {
* @param fileOperationInfo file operation info, * @param fileOperationInfo file operation info,
* contains data copied from respective native structure. * 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 * A callback function for RocksDB which will be called whenever a file
@ -286,7 +286,7 @@ public interface EventListener {
* @param fileOperationInfo file operation info, * @param fileOperationInfo file operation info,
* contains data copied from respective native structure. * 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 * 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, * @param fileOperationInfo file operation info,
* contains data copied from respective native structure. * contains data copied from respective native structure.
*/ */
void OnFileCloseFinish(final FileOperationInfo fileOperationInfo); void onFileCloseFinish(final FileOperationInfo fileOperationInfo);
/** /**
* If true, the {@link #onFileReadFinish(FileOperationInfo)} * If true, the {@link #onFileReadFinish(FileOperationInfo)}

View File

@ -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; package org.rocksdb;
import static org.assertj.core.api.Assertions.assertThat; 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.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Collections; import java.util.*;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.ClassRule; import org.junit.ClassRule;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.rocksdb.AbstractEventListener.EnabledEventCallback;
import org.rocksdb.test.TestableEventListener; import org.rocksdb.test.TestableEventListener;
public class EventListenerTest { public class EventListenerTest {
@ -41,10 +43,8 @@ public class EventListenerTest {
@Test @Test
public void onFlushCompleted() throws RocksDBException { 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(); final AtomicBoolean wasCbCalled = new AtomicBoolean();
AbstractEventListener onFlushCompletedListener = new AbstractEventListener() { final AbstractEventListener onFlushCompletedListener = new AbstractEventListener() {
@Override @Override
public void onFlushCompleted(final RocksDB rocksDb, final FlushJobInfo flushJobInfo) { public void onFlushCompleted(final RocksDB rocksDb, final FlushJobInfo flushJobInfo) {
assertNotNull(flushJobInfo.getColumnFamilyName()); assertNotNull(flushJobInfo.getColumnFamilyName());
@ -57,10 +57,8 @@ public class EventListenerTest {
@Test @Test
public void onFlushBegin() throws RocksDBException { 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(); final AtomicBoolean wasCbCalled = new AtomicBoolean();
AbstractEventListener onFlushBeginListener = new AbstractEventListener() { final AbstractEventListener onFlushBeginListener = new AbstractEventListener() {
@Override @Override
public void onFlushBegin(final RocksDB rocksDb, final FlushJobInfo flushJobInfo) { public void onFlushBegin(final RocksDB rocksDb, final FlushJobInfo flushJobInfo) {
assertNotNull(flushJobInfo.getColumnFamilyName()); assertNotNull(flushJobInfo.getColumnFamilyName());
@ -72,7 +70,7 @@ public class EventListenerTest {
} }
void deleteTableFile(final AbstractEventListener el, final AtomicBoolean wasCbCalled) void deleteTableFile(final AbstractEventListener el, final AtomicBoolean wasCbCalled)
throws RocksDBException, InterruptedException { throws RocksDBException {
try (final Options opt = try (final Options opt =
new Options().setCreateIfMissing(true).setListeners(Collections.singletonList(el)); new Options().setCreateIfMissing(true).setListeners(Collections.singletonList(el));
final RocksDB db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) { final RocksDB db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) {
@ -80,7 +78,7 @@ public class EventListenerTest {
final byte[] value = new byte[24]; final byte[] value = new byte[24];
rand.nextBytes(value); rand.nextBytes(value);
db.put("testKey".getBytes(), value); db.put("testKey".getBytes(), value);
RocksDB.LiveFiles liveFiles = db.getLiveFiles(); final RocksDB.LiveFiles liveFiles = db.getLiveFiles();
assertNotNull(liveFiles); assertNotNull(liveFiles);
assertNotNull(liveFiles.files); assertNotNull(liveFiles.files);
assertFalse(liveFiles.files.isEmpty()); assertFalse(liveFiles.files.isEmpty());
@ -91,10 +89,8 @@ public class EventListenerTest {
@Test @Test
public void onTableFileDeleted() throws RocksDBException, InterruptedException { 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(); final AtomicBoolean wasCbCalled = new AtomicBoolean();
AbstractEventListener onTableFileDeletedListener = new AbstractEventListener() { final AbstractEventListener onTableFileDeletedListener = new AbstractEventListener() {
@Override @Override
public void onTableFileDeleted(final TableFileDeletionInfo tableFileDeletionInfo) { public void onTableFileDeleted(final TableFileDeletionInfo tableFileDeletionInfo) {
assertNotNull(tableFileDeletionInfo.getDbName()); assertNotNull(tableFileDeletionInfo.getDbName());
@ -120,10 +116,8 @@ public class EventListenerTest {
@Test @Test
public void onCompactionBegin() throws RocksDBException { 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(); final AtomicBoolean wasCbCalled = new AtomicBoolean();
AbstractEventListener onCompactionBeginListener = new AbstractEventListener() { final AbstractEventListener onCompactionBeginListener = new AbstractEventListener() {
@Override @Override
public void onCompactionBegin(final RocksDB db, final CompactionJobInfo compactionJobInfo) { public void onCompactionBegin(final RocksDB db, final CompactionJobInfo compactionJobInfo) {
assertEquals(CompactionReason.kManualCompaction, compactionJobInfo.compactionReason()); assertEquals(CompactionReason.kManualCompaction, compactionJobInfo.compactionReason());
@ -135,10 +129,8 @@ public class EventListenerTest {
@Test @Test
public void onCompactionCompleted() throws RocksDBException { 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(); final AtomicBoolean wasCbCalled = new AtomicBoolean();
AbstractEventListener onCompactionCompletedListener = new AbstractEventListener() { final AbstractEventListener onCompactionCompletedListener = new AbstractEventListener() {
@Override @Override
public void onCompactionCompleted( public void onCompactionCompleted(
final RocksDB db, final CompactionJobInfo compactionJobInfo) { final RocksDB db, final CompactionJobInfo compactionJobInfo) {
@ -151,10 +143,8 @@ public class EventListenerTest {
@Test @Test
public void onTableFileCreated() throws RocksDBException { 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(); final AtomicBoolean wasCbCalled = new AtomicBoolean();
AbstractEventListener onTableFileCreatedListener = new AbstractEventListener() { final AbstractEventListener onTableFileCreatedListener = new AbstractEventListener() {
@Override @Override
public void onTableFileCreated(final TableFileCreationInfo tableFileCreationInfo) { public void onTableFileCreated(final TableFileCreationInfo tableFileCreationInfo) {
assertEquals(TableFileCreationReason.FLUSH, tableFileCreationInfo.getReason()); assertEquals(TableFileCreationReason.FLUSH, tableFileCreationInfo.getReason());
@ -166,10 +156,8 @@ public class EventListenerTest {
@Test @Test
public void onTableFileCreationStarted() throws RocksDBException { 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(); final AtomicBoolean wasCbCalled = new AtomicBoolean();
AbstractEventListener onTableFileCreationStartedListener = new AbstractEventListener() { final AbstractEventListener onTableFileCreationStartedListener = new AbstractEventListener() {
@Override @Override
public void onTableFileCreationStarted( public void onTableFileCreationStarted(
final TableFileCreationBriefInfo tableFileCreationBriefInfo) { final TableFileCreationBriefInfo tableFileCreationBriefInfo) {
@ -197,10 +185,8 @@ public class EventListenerTest {
@Test @Test
public void onColumnFamilyHandleDeletionStarted() throws RocksDBException { 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(); final AtomicBoolean wasCbCalled = new AtomicBoolean();
AbstractEventListener onColumnFamilyHandleDeletionStartedListener = final AbstractEventListener onColumnFamilyHandleDeletionStartedListener =
new AbstractEventListener() { new AbstractEventListener() {
@Override @Override
public void onColumnFamilyHandleDeletionStarted( public void onColumnFamilyHandleDeletionStarted(
@ -218,9 +204,9 @@ public class EventListenerTest {
new Options().setCreateIfMissing(true).setListeners(Collections.singletonList(el)); new Options().setCreateIfMissing(true).setListeners(Collections.singletonList(el));
final RocksDB db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) { final RocksDB db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) {
assertThat(db).isNotNull(); assertThat(db).isNotNull();
String uuid = UUID.randomUUID().toString(); final String uuid = UUID.randomUUID().toString();
SstFileWriter sstFileWriter = new SstFileWriter(new EnvOptions(), opt); final SstFileWriter sstFileWriter = new SstFileWriter(new EnvOptions(), opt);
Path externalFilePath = Paths.get(db.getName(), uuid); final Path externalFilePath = Paths.get(db.getName(), uuid);
sstFileWriter.open(externalFilePath.toString()); sstFileWriter.open(externalFilePath.toString());
sstFileWriter.put("testKey".getBytes(), uuid.getBytes()); sstFileWriter.put("testKey".getBytes(), uuid.getBytes());
sstFileWriter.finish(); sstFileWriter.finish();
@ -232,10 +218,8 @@ public class EventListenerTest {
@Test @Test
public void onExternalFileIngested() throws RocksDBException { 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(); final AtomicBoolean wasCbCalled = new AtomicBoolean();
AbstractEventListener onExternalFileIngestedListener = new AbstractEventListener() { final AbstractEventListener onExternalFileIngestedListener = new AbstractEventListener() {
@Override @Override
public void onExternalFileIngested( public void onExternalFileIngested(
final RocksDB db, final ExternalFileIngestionInfo externalFileIngestionInfo) { final RocksDB db, final ExternalFileIngestionInfo externalFileIngestionInfo) {
@ -248,8 +232,8 @@ public class EventListenerTest {
@Test @Test
public void testAllCallbacksInvocation() { public void testAllCallbacksInvocation() {
final int TEST_INT_VAL = Integer.MAX_VALUE; final int TEST_INT_VAL = -1;
final long TEST_LONG_VAL = Long.MAX_VALUE; final long TEST_LONG_VAL = -1;
// Expected test data objects // Expected test data objects
final Map<String, String> userCollectedPropertiesTestData = final Map<String, String> userCollectedPropertiesTestData =
Collections.singletonMap("key", "value"); Collections.singletonMap("key", "value");
@ -263,18 +247,18 @@ public class EventListenerTest {
"columnFamilyName".getBytes(), "filterPolicyName", "comparatorName", "mergeOperatorName", "columnFamilyName".getBytes(), "filterPolicyName", "comparatorName", "mergeOperatorName",
"prefixExtractorName", "propertyCollectorsNames", "compressionName", "prefixExtractorName", "propertyCollectorsNames", "compressionName",
userCollectedPropertiesTestData, readablePropertiesTestData, propertiesOffsetsTestData); userCollectedPropertiesTestData, readablePropertiesTestData, propertiesOffsetsTestData);
final FlushJobInfo flushJobInfoTestData = new FlushJobInfo(TEST_INT_VAL, "testColumnFamily", final FlushJobInfo flushJobInfoTestData = new FlushJobInfo(Integer.MAX_VALUE,
"/file/path", TEST_LONG_VAL, TEST_INT_VAL, true, true, TEST_LONG_VAL, TEST_LONG_VAL, "testColumnFamily", "/file/path", TEST_LONG_VAL, Integer.MAX_VALUE, true, true,
tablePropertiesTestData, (byte) 0x0a); TEST_LONG_VAL, TEST_LONG_VAL, tablePropertiesTestData, (byte) 0x0a);
final Status statusTestData = new Status(Status.Code.Incomplete, Status.SubCode.NoSpace, null); final Status statusTestData = new Status(Status.Code.Incomplete, Status.SubCode.NoSpace, null);
final TableFileDeletionInfo tableFileDeletionInfoTestData = final TableFileDeletionInfo tableFileDeletionInfoTestData =
new TableFileDeletionInfo("dbName", "/file/path", TEST_INT_VAL, statusTestData); new TableFileDeletionInfo("dbName", "/file/path", Integer.MAX_VALUE, statusTestData);
final TableFileCreationInfo tableFileCreationInfoTestData = final TableFileCreationInfo tableFileCreationInfoTestData =
new TableFileCreationInfo(TEST_LONG_VAL, tablePropertiesTestData, statusTestData, "dbName", 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 = final TableFileCreationBriefInfo tableFileCreationBriefInfoTestData =
new TableFileCreationBriefInfo( 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( final MemTableInfo memTableInfoTestData = new MemTableInfo(
"columnFamilyName", TEST_LONG_VAL, TEST_LONG_VAL, TEST_LONG_VAL, TEST_LONG_VAL); "columnFamilyName", TEST_LONG_VAL, TEST_LONG_VAL, TEST_LONG_VAL, TEST_LONG_VAL);
final FileOperationInfo fileOperationInfoTestData = new FileOperationInfo("/file/path", final FileOperationInfo fileOperationInfoTestData = new FileOperationInfo("/file/path",
@ -285,305 +269,496 @@ public class EventListenerTest {
new ExternalFileIngestionInfo("columnFamilyName", "/external/file/path", new ExternalFileIngestionInfo("columnFamilyName", "/external/file/path",
"/internal/file/path", TEST_LONG_VAL, tablePropertiesTestData); "/internal/file/path", TEST_LONG_VAL, tablePropertiesTestData);
final int CALLBACKS_COUNT = 22; final CapturingTestableEventListener listener = new CapturingTestableEventListener() {
final AtomicBoolean[] wasCalled = new AtomicBoolean[CALLBACKS_COUNT];
for (int i = 0; i < CALLBACKS_COUNT; ++i) {
wasCalled[i] = new AtomicBoolean();
}
TestableEventListener listener = new TestableEventListener() {
@Override @Override
public void onFlushCompleted(final RocksDB db, final FlushJobInfo flushJobInfo) { public void onFlushCompleted(final RocksDB db, final FlushJobInfo flushJobInfo) {
super.onFlushCompleted(db, flushJobInfo);
assertEquals(flushJobInfoTestData, flushJobInfo); assertEquals(flushJobInfoTestData, flushJobInfo);
wasCalled[0].set(true);
} }
@Override @Override
public void onFlushBegin(final RocksDB db, final FlushJobInfo flushJobInfo) { public void onFlushBegin(final RocksDB db, final FlushJobInfo flushJobInfo) {
super.onFlushBegin(db, flushJobInfo);
assertEquals(flushJobInfoTestData, flushJobInfo); assertEquals(flushJobInfoTestData, flushJobInfo);
wasCalled[1].set(true);
} }
@Override @Override
public void onTableFileDeleted(final TableFileDeletionInfo tableFileDeletionInfo) { public void onTableFileDeleted(final TableFileDeletionInfo tableFileDeletionInfo) {
super.onTableFileDeleted(tableFileDeletionInfo);
assertEquals(tableFileDeletionInfoTestData, tableFileDeletionInfo); assertEquals(tableFileDeletionInfoTestData, tableFileDeletionInfo);
wasCalled[2].set(true);
} }
@Override @Override
public void onCompactionBegin(final RocksDB db, final CompactionJobInfo compactionJobInfo) { public void onCompactionBegin(final RocksDB db, final CompactionJobInfo compactionJobInfo) {
super.onCompactionBegin(db, compactionJobInfo);
assertArrayEquals( assertArrayEquals(
"compactionColumnFamily".getBytes(), compactionJobInfo.columnFamilyName()); "compactionColumnFamily".getBytes(), compactionJobInfo.columnFamilyName());
assertEquals(statusTestData, compactionJobInfo.status()); assertEquals(statusTestData, compactionJobInfo.status());
assertEquals(TEST_LONG_VAL, compactionJobInfo.threadId()); assertEquals(TEST_LONG_VAL, compactionJobInfo.threadId());
assertEquals(TEST_INT_VAL, compactionJobInfo.jobId()); assertEquals(Integer.MAX_VALUE, compactionJobInfo.jobId());
assertEquals(TEST_INT_VAL, compactionJobInfo.baseInputLevel()); assertEquals(Integer.MAX_VALUE, compactionJobInfo.baseInputLevel());
assertEquals(TEST_INT_VAL, compactionJobInfo.outputLevel()); assertEquals(Integer.MAX_VALUE, compactionJobInfo.outputLevel());
assertEquals(Collections.singletonList("inputFile.sst"), compactionJobInfo.inputFiles()); assertEquals(Collections.singletonList("inputFile.sst"), compactionJobInfo.inputFiles());
assertEquals(Collections.singletonList("outputFile.sst"), compactionJobInfo.outputFiles()); assertEquals(Collections.singletonList("outputFile.sst"), compactionJobInfo.outputFiles());
assertEquals(Collections.singletonMap("tableProperties", tablePropertiesTestData), assertEquals(Collections.singletonMap("tableProperties", tablePropertiesTestData),
compactionJobInfo.tableProperties()); compactionJobInfo.tableProperties());
assertEquals(CompactionReason.kFlush, compactionJobInfo.compactionReason()); assertEquals(CompactionReason.kFlush, compactionJobInfo.compactionReason());
assertEquals(CompressionType.SNAPPY_COMPRESSION, compactionJobInfo.compression()); assertEquals(CompressionType.SNAPPY_COMPRESSION, compactionJobInfo.compression());
wasCalled[3].set(true);
} }
@Override @Override
public void onCompactionCompleted( public void onCompactionCompleted(
final RocksDB db, final CompactionJobInfo compactionJobInfo) { final RocksDB db, final CompactionJobInfo compactionJobInfo) {
super.onCompactionCompleted(db, compactionJobInfo);
assertArrayEquals( assertArrayEquals(
"compactionColumnFamily".getBytes(), compactionJobInfo.columnFamilyName()); "compactionColumnFamily".getBytes(), compactionJobInfo.columnFamilyName());
assertEquals(statusTestData, compactionJobInfo.status()); assertEquals(statusTestData, compactionJobInfo.status());
assertEquals(TEST_LONG_VAL, compactionJobInfo.threadId()); assertEquals(TEST_LONG_VAL, compactionJobInfo.threadId());
assertEquals(TEST_INT_VAL, compactionJobInfo.jobId()); assertEquals(Integer.MAX_VALUE, compactionJobInfo.jobId());
assertEquals(TEST_INT_VAL, compactionJobInfo.baseInputLevel()); assertEquals(Integer.MAX_VALUE, compactionJobInfo.baseInputLevel());
assertEquals(TEST_INT_VAL, compactionJobInfo.outputLevel()); assertEquals(Integer.MAX_VALUE, compactionJobInfo.outputLevel());
assertEquals(Collections.singletonList("inputFile.sst"), compactionJobInfo.inputFiles()); assertEquals(Collections.singletonList("inputFile.sst"), compactionJobInfo.inputFiles());
assertEquals(Collections.singletonList("outputFile.sst"), compactionJobInfo.outputFiles()); assertEquals(Collections.singletonList("outputFile.sst"), compactionJobInfo.outputFiles());
assertEquals(Collections.singletonMap("tableProperties", tablePropertiesTestData), assertEquals(Collections.singletonMap("tableProperties", tablePropertiesTestData),
compactionJobInfo.tableProperties()); compactionJobInfo.tableProperties());
assertEquals(CompactionReason.kFlush, compactionJobInfo.compactionReason()); assertEquals(CompactionReason.kFlush, compactionJobInfo.compactionReason());
assertEquals(CompressionType.SNAPPY_COMPRESSION, compactionJobInfo.compression()); assertEquals(CompressionType.SNAPPY_COMPRESSION, compactionJobInfo.compression());
wasCalled[4].set(true);
} }
@Override @Override
public void onTableFileCreated(final TableFileCreationInfo tableFileCreationInfo) { public void onTableFileCreated(final TableFileCreationInfo tableFileCreationInfo) {
super.onTableFileCreated(tableFileCreationInfo);
assertEquals(tableFileCreationInfoTestData, tableFileCreationInfo); assertEquals(tableFileCreationInfoTestData, tableFileCreationInfo);
wasCalled[5].set(true);
} }
@Override @Override
public void onTableFileCreationStarted( public void onTableFileCreationStarted(
final TableFileCreationBriefInfo tableFileCreationBriefInfo) { final TableFileCreationBriefInfo tableFileCreationBriefInfo) {
super.onTableFileCreationStarted(tableFileCreationBriefInfo);
assertEquals(tableFileCreationBriefInfoTestData, tableFileCreationBriefInfo); assertEquals(tableFileCreationBriefInfoTestData, tableFileCreationBriefInfo);
wasCalled[6].set(true);
} }
@Override @Override
public void onMemTableSealed(final MemTableInfo memTableInfo) { public void onMemTableSealed(final MemTableInfo memTableInfo) {
super.onMemTableSealed(memTableInfo);
assertEquals(memTableInfoTestData, memTableInfo); assertEquals(memTableInfoTestData, memTableInfo);
wasCalled[7].set(true);
} }
@Override @Override
public void onColumnFamilyHandleDeletionStarted(final ColumnFamilyHandle columnFamilyHandle) { public void onColumnFamilyHandleDeletionStarted(final ColumnFamilyHandle columnFamilyHandle) {
wasCalled[8].set(true); super.onColumnFamilyHandleDeletionStarted(columnFamilyHandle);
} }
@Override @Override
public void onExternalFileIngested( public void onExternalFileIngested(
final RocksDB db, final ExternalFileIngestionInfo externalFileIngestionInfo) { final RocksDB db, final ExternalFileIngestionInfo externalFileIngestionInfo) {
super.onExternalFileIngested(db, externalFileIngestionInfo);
assertEquals(externalFileIngestionInfoTestData, externalFileIngestionInfo); assertEquals(externalFileIngestionInfoTestData, externalFileIngestionInfo);
wasCalled[9].set(true);
} }
@Override @Override
public void onBackgroundError( public void onBackgroundError(
final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) { final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) {
wasCalled[10].set(true); super.onBackgroundError(backgroundErrorReason, backgroundError);
} }
@Override @Override
public void onStallConditionsChanged(final WriteStallInfo writeStallInfo) { public void onStallConditionsChanged(final WriteStallInfo writeStallInfo) {
super.onStallConditionsChanged(writeStallInfo);
assertEquals(writeStallInfoTestData, writeStallInfo); assertEquals(writeStallInfoTestData, writeStallInfo);
wasCalled[11].set(true);
} }
@Override @Override
public void onFileReadFinish(final FileOperationInfo fileOperationInfo) { public void onFileReadFinish(final FileOperationInfo fileOperationInfo) {
super.onFileReadFinish(fileOperationInfo);
assertEquals(fileOperationInfoTestData, fileOperationInfo); assertEquals(fileOperationInfoTestData, fileOperationInfo);
wasCalled[12].set(true);
} }
@Override @Override
public void onFileWriteFinish(final FileOperationInfo fileOperationInfo) { public void onFileWriteFinish(final FileOperationInfo fileOperationInfo) {
super.onFileWriteFinish(fileOperationInfo);
assertEquals(fileOperationInfoTestData, fileOperationInfo); assertEquals(fileOperationInfoTestData, fileOperationInfo);
wasCalled[13].set(true);
} }
@Override @Override
public void OnFileFlushFinish(final FileOperationInfo fileOperationInfo) { public void onFileFlushFinish(final FileOperationInfo fileOperationInfo) {
super.onFileFlushFinish(fileOperationInfo);
assertEquals(fileOperationInfoTestData, fileOperationInfo); assertEquals(fileOperationInfoTestData, fileOperationInfo);
wasCalled[14].set(true);
} }
@Override @Override
public void OnFileSyncFinish(final FileOperationInfo fileOperationInfo) { public void onFileSyncFinish(final FileOperationInfo fileOperationInfo) {
super.onFileSyncFinish(fileOperationInfo);
assertEquals(fileOperationInfoTestData, fileOperationInfo); assertEquals(fileOperationInfoTestData, fileOperationInfo);
wasCalled[15].set(true);
} }
@Override @Override
public void OnFileRangeSyncFinish(final FileOperationInfo fileOperationInfo) { public void onFileRangeSyncFinish(final FileOperationInfo fileOperationInfo) {
super.onFileRangeSyncFinish(fileOperationInfo);
assertEquals(fileOperationInfoTestData, fileOperationInfo); assertEquals(fileOperationInfoTestData, fileOperationInfo);
wasCalled[16].set(true);
} }
@Override @Override
public void OnFileTruncateFinish(final FileOperationInfo fileOperationInfo) { public void onFileTruncateFinish(final FileOperationInfo fileOperationInfo) {
assertEquals(fileOperationInfoTestData, fileOperationInfo); assertEquals(fileOperationInfoTestData, fileOperationInfo);
wasCalled[17].set(true); super.onFileTruncateFinish(fileOperationInfo);
} }
@Override @Override
public void OnFileCloseFinish(final FileOperationInfo fileOperationInfo) { public void onFileCloseFinish(final FileOperationInfo fileOperationInfo) {
super.onFileCloseFinish(fileOperationInfo);
assertEquals(fileOperationInfoTestData, fileOperationInfo); assertEquals(fileOperationInfoTestData, fileOperationInfo);
wasCalled[18].set(true);
} }
@Override @Override
public boolean shouldBeNotifiedOnFileIO() { public boolean shouldBeNotifiedOnFileIO() {
wasCalled[19].set(true); super.shouldBeNotifiedOnFileIO();
return false; return false;
} }
@Override @Override
public boolean onErrorRecoveryBegin( public boolean onErrorRecoveryBegin(
final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) { final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) {
super.onErrorRecoveryBegin(backgroundErrorReason, backgroundError);
assertEquals(BackgroundErrorReason.FLUSH, backgroundErrorReason); assertEquals(BackgroundErrorReason.FLUSH, backgroundErrorReason);
assertEquals(statusTestData, backgroundError); assertEquals(statusTestData, backgroundError);
wasCalled[20].set(true);
return true; return true;
} }
@Override @Override
public void onErrorRecoveryCompleted(final Status oldBackgroundError) { public void onErrorRecoveryCompleted(final Status oldBackgroundError) {
super.onErrorRecoveryCompleted(oldBackgroundError);
assertEquals(statusTestData, oldBackgroundError); assertEquals(statusTestData, oldBackgroundError);
wasCalled[21].set(true);
} }
}; };
// test action
listener.invokeAllCallbacks(); listener.invokeAllCallbacks();
for (int i = 0; i < CALLBACKS_COUNT; ++i) {
assertTrue("Callback method " + i + " was not called", wasCalled[i].get()); // assert
} assertAllEventsCalled(listener);
} }
@Test @Test
public void testEnabledCallbacks() { public void testEnabledCallbacks() {
final AtomicBoolean wasOnMemTableSealedCalled = new AtomicBoolean(); final EnabledEventCallback enabledEvents[] = {
final AtomicBoolean wasOnErrorRecoveryCompletedCalled = new AtomicBoolean(); EnabledEventCallback.ON_MEMTABLE_SEALED, EnabledEventCallback.ON_ERROR_RECOVERY_COMPLETED};
final TestableEventListener listener = new TestableEventListener(
AbstractEventListener.EnabledEventCallback.ON_MEMTABLE_SEALED, final CapturingTestableEventListener listener =
AbstractEventListener.EnabledEventCallback.ON_ERROR_RECOVERY_COMPLETED) { new CapturingTestableEventListener(enabledEvents);
// test action
listener.invokeAllCallbacks();
// assert
assertEventsCalled(listener, enabledEvents);
}
private static void assertAllEventsCalled(
final CapturingTestableEventListener capturingTestableEventListener) {
assertEventsCalled(capturingTestableEventListener, EnumSet.allOf(EnabledEventCallback.class));
}
private static void assertEventsCalled(
final CapturingTestableEventListener capturingTestableEventListener,
final EnabledEventCallback[] expected) {
assertEventsCalled(capturingTestableEventListener, EnumSet.copyOf(Arrays.asList(expected)));
}
private static void assertEventsCalled(
final CapturingTestableEventListener capturingTestableEventListener,
final EnumSet<EnabledEventCallback> expected) {
final ListenerEvents capturedEvents = capturingTestableEventListener.capturedListenerEvents;
if (expected.contains(EnabledEventCallback.ON_FLUSH_COMPLETED)) {
assertTrue("onFlushCompleted was not called", capturedEvents.flushCompleted);
} else {
assertFalse("onFlushCompleted was not called", capturedEvents.flushCompleted);
}
if (expected.contains(EnabledEventCallback.ON_FLUSH_BEGIN)) {
assertTrue("onFlushBegin was not called", capturedEvents.flushBegin);
} else {
assertFalse("onFlushBegin was called", capturedEvents.flushBegin);
}
if (expected.contains(EnabledEventCallback.ON_TABLE_FILE_DELETED)) {
assertTrue("onTableFileDeleted was not called", capturedEvents.tableFileDeleted);
} else {
assertFalse("onTableFileDeleted was called", capturedEvents.tableFileDeleted);
}
if (expected.contains(EnabledEventCallback.ON_COMPACTION_BEGIN)) {
assertTrue("onCompactionBegin was not called", capturedEvents.compactionBegin);
} else {
assertFalse("onCompactionBegin was called", capturedEvents.compactionBegin);
}
if (expected.contains(EnabledEventCallback.ON_COMPACTION_COMPLETED)) {
assertTrue("onCompactionCompleted was not called", capturedEvents.compactionCompleted);
} else {
assertFalse("onCompactionCompleted was called", capturedEvents.compactionCompleted);
}
if (expected.contains(EnabledEventCallback.ON_TABLE_FILE_CREATED)) {
assertTrue("onTableFileCreated was not called", capturedEvents.tableFileCreated);
} else {
assertFalse("onTableFileCreated was called", capturedEvents.tableFileCreated);
}
if (expected.contains(EnabledEventCallback.ON_TABLE_FILE_CREATION_STARTED)) {
assertTrue(
"onTableFileCreationStarted was not called", capturedEvents.tableFileCreationStarted);
} else {
assertFalse("onTableFileCreationStarted was called", capturedEvents.tableFileCreationStarted);
}
if (expected.contains(EnabledEventCallback.ON_MEMTABLE_SEALED)) {
assertTrue("onMemTableSealed was not called", capturedEvents.memTableSealed);
} else {
assertFalse("onMemTableSealed was called", capturedEvents.memTableSealed);
}
if (expected.contains(EnabledEventCallback.ON_COLUMN_FAMILY_HANDLE_DELETION_STARTED)) {
assertTrue("onColumnFamilyHandleDeletionStarted was not called",
capturedEvents.columnFamilyHandleDeletionStarted);
} else {
assertFalse("onColumnFamilyHandleDeletionStarted was called",
capturedEvents.columnFamilyHandleDeletionStarted);
}
if (expected.contains(EnabledEventCallback.ON_EXTERNAL_FILE_INGESTED)) {
assertTrue("onExternalFileIngested was not called", capturedEvents.externalFileIngested);
} else {
assertFalse("onExternalFileIngested was called", capturedEvents.externalFileIngested);
}
if (expected.contains(EnabledEventCallback.ON_BACKGROUND_ERROR)) {
assertTrue("onBackgroundError was not called", capturedEvents.backgroundError);
} else {
assertFalse("onBackgroundError was called", capturedEvents.backgroundError);
}
if (expected.contains(EnabledEventCallback.ON_STALL_CONDITIONS_CHANGED)) {
assertTrue("onStallConditionsChanged was not called", capturedEvents.stallConditionsChanged);
} else {
assertFalse("onStallConditionsChanged was called", capturedEvents.stallConditionsChanged);
}
if (expected.contains(EnabledEventCallback.ON_FILE_READ_FINISH)) {
assertTrue("onFileReadFinish was not called", capturedEvents.fileReadFinish);
} else {
assertFalse("onFileReadFinish was called", capturedEvents.fileReadFinish);
}
if (expected.contains(EnabledEventCallback.ON_FILE_WRITE_FINISH)) {
assertTrue("onFileWriteFinish was not called", capturedEvents.fileWriteFinish);
} else {
assertFalse("onFileWriteFinish was called", capturedEvents.fileWriteFinish);
}
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 @Override
public void onFlushCompleted(final RocksDB db, final FlushJobInfo flushJobInfo) { public void onFlushCompleted(final RocksDB db, final FlushJobInfo flushJobInfo) {
fail("onFlushCompleted was not enabled"); capturedListenerEvents.flushCompleted = true;
} }
@Override @Override
public void onFlushBegin(final RocksDB db, final FlushJobInfo flushJobInfo) { public void onFlushBegin(final RocksDB db, final FlushJobInfo flushJobInfo) {
fail("onFlushBegin was not enabled"); capturedListenerEvents.flushBegin = true;
} }
@Override @Override
public void onTableFileDeleted(final TableFileDeletionInfo tableFileDeletionInfo) { public void onTableFileDeleted(final TableFileDeletionInfo tableFileDeletionInfo) {
fail("onTableFileDeleted was not enabled"); capturedListenerEvents.tableFileDeleted = true;
} }
@Override @Override
public void onCompactionBegin(final RocksDB db, final CompactionJobInfo compactionJobInfo) { public void onCompactionBegin(final RocksDB db, final CompactionJobInfo compactionJobInfo) {
fail("onCompactionBegin was not enabled"); capturedListenerEvents.compactionBegin = true;
} }
@Override @Override
public void onCompactionCompleted( public void onCompactionCompleted(final RocksDB db, final CompactionJobInfo compactionJobInfo) {
final RocksDB db, final CompactionJobInfo compactionJobInfo) { capturedListenerEvents.compactionCompleted = true;
fail("onCompactionCompleted was not enabled");
} }
@Override @Override
public void onTableFileCreated(final TableFileCreationInfo tableFileCreationInfo) { public void onTableFileCreated(final TableFileCreationInfo tableFileCreationInfo) {
fail("onTableFileCreated was not enabled"); capturedListenerEvents.tableFileCreated = true;
} }
@Override @Override
public void onTableFileCreationStarted( public void onTableFileCreationStarted(
final TableFileCreationBriefInfo tableFileCreationBriefInfo) { final TableFileCreationBriefInfo tableFileCreationBriefInfo) {
fail("onTableFileCreationStarted was not enabled"); capturedListenerEvents.tableFileCreationStarted = true;
} }
@Override @Override
public void onMemTableSealed(final MemTableInfo memTableInfo) { public void onMemTableSealed(final MemTableInfo memTableInfo) {
wasOnMemTableSealedCalled.set(true); capturedListenerEvents.memTableSealed = true;
} }
@Override @Override
public void onColumnFamilyHandleDeletionStarted(final ColumnFamilyHandle columnFamilyHandle) { public void onColumnFamilyHandleDeletionStarted(final ColumnFamilyHandle columnFamilyHandle) {
fail("onColumnFamilyHandleDeletionStarted was not enabled"); capturedListenerEvents.columnFamilyHandleDeletionStarted = true;
} }
@Override @Override
public void onExternalFileIngested( public void onExternalFileIngested(
final RocksDB db, final ExternalFileIngestionInfo externalFileIngestionInfo) { final RocksDB db, final ExternalFileIngestionInfo externalFileIngestionInfo) {
fail("onExternalFileIngested was not enabled"); capturedListenerEvents.externalFileIngested = true;
} }
@Override @Override
public void onBackgroundError( public void onBackgroundError(
final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) { final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) {
fail("onBackgroundError was not enabled"); capturedListenerEvents.backgroundError = true;
} }
@Override @Override
public void onStallConditionsChanged(final WriteStallInfo writeStallInfo) { public void onStallConditionsChanged(final WriteStallInfo writeStallInfo) {
fail("onStallConditionsChanged was not enabled"); capturedListenerEvents.stallConditionsChanged = true;
} }
@Override @Override
public void onFileReadFinish(final FileOperationInfo fileOperationInfo) { public void onFileReadFinish(final FileOperationInfo fileOperationInfo) {
fail("onFileReadFinish was not enabled"); capturedListenerEvents.fileReadFinish = true;
} }
@Override @Override
public void onFileWriteFinish(final FileOperationInfo fileOperationInfo) { public void onFileWriteFinish(final FileOperationInfo fileOperationInfo) {
fail("onFileWriteFinish was not enabled"); capturedListenerEvents.fileWriteFinish = true;
} }
@Override @Override
public void OnFileFlushFinish(final FileOperationInfo fileOperationInfo) { public void onFileFlushFinish(final FileOperationInfo fileOperationInfo) {
fail("OnFileFlushFinish was not enabled"); capturedListenerEvents.fileFlushFinish = true;
} }
@Override @Override
public void OnFileSyncFinish(final FileOperationInfo fileOperationInfo) { public void onFileSyncFinish(final FileOperationInfo fileOperationInfo) {
fail("OnFileSyncFinish was not enabled"); capturedListenerEvents.fileSyncFinish = true;
} }
@Override @Override
public void OnFileRangeSyncFinish(final FileOperationInfo fileOperationInfo) { public void onFileRangeSyncFinish(final FileOperationInfo fileOperationInfo) {
fail("OnFileRangeSyncFinish was not enabled"); capturedListenerEvents.fileRangeSyncFinish = true;
} }
@Override @Override
public void OnFileTruncateFinish(final FileOperationInfo fileOperationInfo) { public void onFileTruncateFinish(final FileOperationInfo fileOperationInfo) {
fail("OnFileTruncateFinish was not enabled"); capturedListenerEvents.fileTruncateFinish = true;
} }
@Override @Override
public void OnFileCloseFinish(final FileOperationInfo fileOperationInfo) { public void onFileCloseFinish(final FileOperationInfo fileOperationInfo) {
fail("OnFileCloseFinish was not enabled"); capturedListenerEvents.fileCloseFinish = true;
} }
@Override @Override
public boolean shouldBeNotifiedOnFileIO() { public boolean shouldBeNotifiedOnFileIO() {
fail("shouldBeNotifiedOnFileIO was not enabled"); capturedListenerEvents.shouldBeNotifiedOnFileIO = true;
return false; return false;
} }
@Override @Override
public boolean onErrorRecoveryBegin( public boolean onErrorRecoveryBegin(
final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) { final BackgroundErrorReason backgroundErrorReason, final Status backgroundError) {
fail("onErrorRecoveryBegin was not enabled"); capturedListenerEvents.errorRecoveryBegin = true;
return true; return true;
} }
@Override @Override
public void onErrorRecoveryCompleted(final Status oldBackgroundError) { public void onErrorRecoveryCompleted(final Status oldBackgroundError) {
wasOnErrorRecoveryCompletedCalled.set(true); capturedListenerEvents.errorRecoveryCompleted = true;
} }
};
listener.invokeAllCallbacks();
assertTrue(wasOnMemTableSealedCalled.get());
assertTrue(wasOnErrorRecoveryCompletedCalled.get());
} }
} }

View File

@ -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; package org.rocksdb.test;
import org.rocksdb.AbstractEventListener; import org.rocksdb.AbstractEventListener;

View File

@ -38,6 +38,24 @@ static inline bool HasJemalloc() { return true; }
#else #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 // Declare non-standard jemalloc APIs as weak symbols. We can null-check these
// symbols to detect whether jemalloc is linked with the binary. // symbols to detect whether jemalloc is linked with the binary.
extern "C" JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN void JEMALLOC_NOTHROW * extern "C" JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN void JEMALLOC_NOTHROW *