Replace reinterpret_cast with static_cast_with_check (#7067)

Summary:
Replace `reinterpret_cast` with `static_cast_with_check` for `DBImpl` and `ColumnFamilyHandleImpl`.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/7067

Reviewed By: siying

Differential Revision: D22361587

Pulled By: jay-zhuang

fbshipit-source-id: dfe9e8f3af39c3d27cc372c55ab9ad905eb0a5a1
main
Jay Zhuang 5 years ago committed by Facebook GitHub Bot
parent 373d5ac485
commit 00de699096
  1. 2
      db/blob/db_blob_index_test.cc
  2. 3
      db/column_family.cc
  3. 10
      db/column_family_test.cc
  4. 9
      db/compact_files_test.cc
  5. 6
      db/compacted_db_impl.cc
  6. 9
      db/compaction/compaction_job_stats_test.cc
  7. 22
      db/corruption_test.cc
  8. 5
      db/cuckoo_table_db_test.cc
  9. 23
      db/db_basic_test.cc
  10. 6
      db/db_flush_test.cc
  11. 56
      db/db_impl/db_impl.cc
  12. 11
      db/db_impl/db_impl_compaction_flush.cc
  13. 12
      db/db_impl/db_impl_debug.cc
  14. 6
      db/db_impl/db_impl_experimental.cc
  15. 11
      db/db_impl/db_impl_readonly.cc
  16. 4
      db/db_impl/db_impl_secondary.cc
  17. 7
      db/db_impl/db_impl_write.cc
  18. 5
      db/db_iterator_test.cc
  19. 2
      db/db_range_del_test.cc
  20. 4
      db/db_test.cc
  21. 4
      db/db_test2.cc
  22. 10
      db/db_test_util.h
  23. 2
      db/listener_test.cc
  24. 5
      db/plain_table_db_test.cc
  25. 13
      db/prefix_test.cc
  26. 3
      db/write_batch.cc
  27. 2
      db_stress_tool/db_stress_test_base.cc
  28. 3
      monitoring/thread_status_updater_debug.cc
  29. 5
      tools/reduce_levels_test.cc
  30. 3
      util/cast_util.h
  31. 6
      utilities/backupable/backupable_db_test.cc
  32. 9
      utilities/blob_db/blob_db_impl.cc
  33. 7
      utilities/blob_db/blob_db_impl_filesnapshot.cc
  34. 4
      utilities/cassandra/cassandra_functional_test.cc
  35. 3
      utilities/checkpoint/checkpoint_impl.cc
  36. 56
      utilities/transactions/transaction_test.cc
  37. 4
      utilities/transactions/transaction_test.h
  38. 3
      utilities/transactions/transaction_util.cc
  39. 20
      utilities/transactions/write_prepared_transaction_test.cc
  40. 6
      utilities/transactions/write_prepared_txn_db.cc
  41. 3
      utilities/transactions/write_unprepared_txn_db.cc
  42. 4
      utilities/write_batch_with_index/write_batch_with_index.cc
  43. 4
      utilities/write_batch_with_index/write_batch_with_index_internal.cc

@ -46,7 +46,7 @@ class DBBlobIndexTest : public DBTestBase {
ColumnFamilyHandle* cfh() { return dbfull()->DefaultColumnFamily(); } ColumnFamilyHandle* cfh() { return dbfull()->DefaultColumnFamily(); }
ColumnFamilyData* cfd() { ColumnFamilyData* cfd() {
return reinterpret_cast<ColumnFamilyHandleImpl*>(cfh())->cfd(); return static_cast_with_check<ColumnFamilyHandleImpl>(cfh())->cfd();
} }
Status PutBlobIndex(WriteBatch* batch, const Slice& key, Status PutBlobIndex(WriteBatch* batch, const Slice& key,

@ -34,6 +34,7 @@
#include "table/block_based/block_based_table_factory.h" #include "table/block_based/block_based_table_factory.h"
#include "table/merging_iterator.h" #include "table/merging_iterator.h"
#include "util/autovector.h" #include "util/autovector.h"
#include "util/cast_util.h"
#include "util/compression.h" #include "util/compression.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
@ -1546,7 +1547,7 @@ ColumnFamilyHandle* ColumnFamilyMemTablesImpl::GetColumnFamilyHandle() {
uint32_t GetColumnFamilyID(ColumnFamilyHandle* column_family) { uint32_t GetColumnFamilyID(ColumnFamilyHandle* column_family) {
uint32_t column_family_id = 0; uint32_t column_family_id = 0;
if (column_family != nullptr) { if (column_family != nullptr) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
column_family_id = cfh->GetID(); column_family_id = cfh->GetID();
} }
return column_family_id; return column_family_id;

@ -122,7 +122,7 @@ class ColumnFamilyTestBase : public testing::Test {
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
if (flush_every != 0 && i != 0 && i % flush_every == 0) { if (flush_every != 0 && i != 0 && i % flush_every == 0) {
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
dbi->TEST_FlushMemTable(); dbi->TEST_FlushMemTable();
} }
@ -227,7 +227,7 @@ class ColumnFamilyTestBase : public testing::Test {
Open({"default"}); Open({"default"});
} }
DBImpl* dbfull() { return reinterpret_cast<DBImpl*>(db_); } DBImpl* dbfull() { return static_cast_with_check<DBImpl>(db_); }
int GetProperty(int cf, std::string property) { int GetProperty(int cf, std::string property) {
std::string value; std::string value;
@ -570,7 +570,7 @@ TEST_P(ColumnFamilyTest, DontReuseColumnFamilyID) {
Open(); Open();
CreateColumnFamilies({"one", "two", "three"}); CreateColumnFamilies({"one", "two", "three"});
for (size_t i = 0; i < handles_.size(); ++i) { for (size_t i = 0; i < handles_.size(); ++i) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(handles_[i]); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(handles_[i]);
ASSERT_EQ(i, cfh->GetID()); ASSERT_EQ(i, cfh->GetID());
} }
if (iter == 1) { if (iter == 1) {
@ -586,7 +586,7 @@ TEST_P(ColumnFamilyTest, DontReuseColumnFamilyID) {
CreateColumnFamilies({"three2"}); CreateColumnFamilies({"three2"});
// ID 3 that was used for dropped column family "three" should not be // ID 3 that was used for dropped column family "three" should not be
// reused // reused
auto cfh3 = reinterpret_cast<ColumnFamilyHandleImpl*>(handles_[3]); auto cfh3 = static_cast_with_check<ColumnFamilyHandleImpl>(handles_[3]);
ASSERT_EQ(4U, cfh3->GetID()); ASSERT_EQ(4U, cfh3->GetID());
Close(); Close();
Destroy(); Destroy();
@ -3354,7 +3354,7 @@ TEST_P(ColumnFamilyTest, MultipleCFPathsTest) {
// Re-open and verify the keys. // Re-open and verify the keys.
Reopen({ColumnFamilyOptions(), cf_opt1, cf_opt2}); Reopen({ColumnFamilyOptions(), cf_opt1, cf_opt2});
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
for (int cf = 1; cf != 3; ++cf) { for (int cf = 1; cf != 3; ++cf) {
ReadOptions read_options; ReadOptions read_options;
read_options.readahead_size = 0; read_options.readahead_size = 0;

@ -16,6 +16,7 @@
#include "rocksdb/env.h" #include "rocksdb/env.h"
#include "test_util/sync_point.h" #include "test_util/sync_point.h"
#include "test_util/testharness.h" #include "test_util/testharness.h"
#include "util/cast_util.h"
#include "util/string_util.h" #include "util/string_util.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
@ -148,7 +149,7 @@ TEST_F(CompactFilesTest, ObsoleteFiles) {
auto l0_files = collector->GetFlushedFiles(); auto l0_files = collector->GetFlushedFiles();
ASSERT_OK(db->CompactFiles(CompactionOptions(), l0_files, 1)); ASSERT_OK(db->CompactFiles(CompactionOptions(), l0_files, 1));
reinterpret_cast<DBImpl*>(db)->TEST_WaitForCompact(); static_cast_with_check<DBImpl>(db)->TEST_WaitForCompact();
// verify all compaction input files are deleted // verify all compaction input files are deleted
for (auto fname : l0_files) { for (auto fname : l0_files) {
@ -183,13 +184,13 @@ TEST_F(CompactFilesTest, NotCutOutputOnLevel0) {
for (int i = 0; i < 500; ++i) { for (int i = 0; i < 500; ++i) {
db->Put(WriteOptions(), ToString(i), std::string(1000, 'a' + (i % 26))); db->Put(WriteOptions(), ToString(i), std::string(1000, 'a' + (i % 26)));
} }
reinterpret_cast<DBImpl*>(db)->TEST_WaitForFlushMemTable(); static_cast_with_check<DBImpl>(db)->TEST_WaitForFlushMemTable();
auto l0_files_1 = collector->GetFlushedFiles(); auto l0_files_1 = collector->GetFlushedFiles();
collector->ClearFlushedFiles(); collector->ClearFlushedFiles();
for (int i = 0; i < 500; ++i) { for (int i = 0; i < 500; ++i) {
db->Put(WriteOptions(), ToString(i), std::string(1000, 'a' + (i % 26))); db->Put(WriteOptions(), ToString(i), std::string(1000, 'a' + (i % 26)));
} }
reinterpret_cast<DBImpl*>(db)->TEST_WaitForFlushMemTable(); static_cast_with_check<DBImpl>(db)->TEST_WaitForFlushMemTable();
auto l0_files_2 = collector->GetFlushedFiles(); auto l0_files_2 = collector->GetFlushedFiles();
ASSERT_OK(db->CompactFiles(CompactionOptions(), l0_files_1, 0)); ASSERT_OK(db->CompactFiles(CompactionOptions(), l0_files_1, 0));
ASSERT_OK(db->CompactFiles(CompactionOptions(), l0_files_2, 0)); ASSERT_OK(db->CompactFiles(CompactionOptions(), l0_files_2, 0));
@ -383,7 +384,7 @@ TEST_F(CompactFilesTest, GetCompactionJobInfo) {
for (int i = 0; i < 500; ++i) { for (int i = 0; i < 500; ++i) {
db->Put(WriteOptions(), ToString(i), std::string(1000, 'a' + (i % 26))); db->Put(WriteOptions(), ToString(i), std::string(1000, 'a' + (i % 26)));
} }
reinterpret_cast<DBImpl*>(db)->TEST_WaitForFlushMemTable(); static_cast_with_check<DBImpl>(db)->TEST_WaitForFlushMemTable();
auto l0_files_1 = collector->GetFlushedFiles(); auto l0_files_1 = collector->GetFlushedFiles();
CompactionOptions co; CompactionOptions co;
co.compression = CompressionType::kLZ4Compression; co.compression = CompressionType::kLZ4Compression;

@ -5,9 +5,11 @@
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
#include "db/compacted_db_impl.h" #include "db/compacted_db_impl.h"
#include "db/db_impl/db_impl.h" #include "db/db_impl/db_impl.h"
#include "db/version_set.h" #include "db/version_set.h"
#include "table/get_context.h" #include "table/get_context.h"
#include "util/cast_util.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
@ -90,8 +92,8 @@ Status CompactedDBImpl::Init(const Options& options) {
ColumnFamilyOptions(options)); ColumnFamilyOptions(options));
Status s = Recover({cf}, true /* read only */, false, true); Status s = Recover({cf}, true /* read only */, false, true);
if (s.ok()) { if (s.ok()) {
cfd_ = reinterpret_cast<ColumnFamilyHandleImpl*>( cfd_ = static_cast_with_check<ColumnFamilyHandleImpl>(DefaultColumnFamily())
DefaultColumnFamily())->cfd(); ->cfd();
cfd_->InstallSuperVersion(&sv_context, &mutex_); cfd_->InstallSuperVersion(&sv_context, &mutex_);
} }
mutex_.Unlock(); mutex_.Unlock();

@ -52,6 +52,7 @@
#include "test_util/sync_point.h" #include "test_util/sync_point.h"
#include "test_util/testharness.h" #include "test_util/testharness.h"
#include "test_util/testutil.h" #include "test_util/testutil.h"
#include "util/cast_util.h"
#include "util/compression.h" #include "util/compression.h"
#include "util/hash.h" #include "util/hash.h"
#include "util/mutexlock.h" #include "util/mutexlock.h"
@ -126,9 +127,7 @@ class CompactionJobStatsTest : public testing::Test,
static void SetUpTestCase() {} static void SetUpTestCase() {}
static void TearDownTestCase() {} static void TearDownTestCase() {}
DBImpl* dbfull() { DBImpl* dbfull() { return static_cast_with_check<DBImpl>(db_); }
return reinterpret_cast<DBImpl*>(db_);
}
void CreateColumnFamilies(const std::vector<std::string>& cfs, void CreateColumnFamilies(const std::vector<std::string>& cfs,
const Options& options) { const Options& options) {
@ -797,7 +796,7 @@ TEST_P(CompactionJobStatsTest, CompactionJobStatsTest) {
} }
ASSERT_OK(Flush(1)); ASSERT_OK(Flush(1));
reinterpret_cast<DBImpl*>(db_)->TEST_WaitForCompact(); static_cast_with_check<DBImpl>(db_)->TEST_WaitForCompact();
stats_checker->set_verify_next_comp_io_stats(true); stats_checker->set_verify_next_comp_io_stats(true);
std::atomic<bool> first_prepare_write(true); std::atomic<bool> first_prepare_write(true);
@ -1012,7 +1011,7 @@ TEST_P(CompactionJobStatsTest, UniversalCompactionTest) {
&rnd, start_key, start_key + key_base - 1, &rnd, start_key, start_key + key_base - 1,
kKeySize, kValueSize, key_interval, kKeySize, kValueSize, key_interval,
compression_ratio, 1); compression_ratio, 1);
reinterpret_cast<DBImpl*>(db_)->TEST_WaitForCompact(); static_cast_with_check<DBImpl>(db_)->TEST_WaitForCompact();
} }
ASSERT_EQ(stats_checker->NumberOfUnverifiedStats(), 0U); ASSERT_EQ(stats_checker->NumberOfUnverifiedStats(), 0U);
} }

@ -106,7 +106,7 @@ class CorruptionTest : public testing::Test {
WriteBatch batch; WriteBatch batch;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
if (flush_every != 0 && i != 0 && i % flush_every == 0) { if (flush_every != 0 && i != 0 && i % flush_every == 0) {
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
dbi->TEST_FlushMemTable(); dbi->TEST_FlushMemTable();
} }
//if ((i % 100) == 0) fprintf(stderr, "@ %d of %d\n", i, n); //if ((i % 100) == 0) fprintf(stderr, "@ %d of %d\n", i, n);
@ -281,7 +281,7 @@ TEST_F(CorruptionTest, NewFileErrorDuringWrite) {
TEST_F(CorruptionTest, TableFile) { TEST_F(CorruptionTest, TableFile) {
Build(100); Build(100);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
dbi->TEST_FlushMemTable(); dbi->TEST_FlushMemTable();
dbi->TEST_CompactRange(0, nullptr, nullptr); dbi->TEST_CompactRange(0, nullptr, nullptr);
dbi->TEST_CompactRange(1, nullptr, nullptr); dbi->TEST_CompactRange(1, nullptr, nullptr);
@ -304,7 +304,7 @@ TEST_F(CorruptionTest, VerifyChecksumReadahead) {
Reopen(&options); Reopen(&options);
Build(10000); Build(10000);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
dbi->TEST_FlushMemTable(); dbi->TEST_FlushMemTable();
dbi->TEST_CompactRange(0, nullptr, nullptr); dbi->TEST_CompactRange(0, nullptr, nullptr);
dbi->TEST_CompactRange(1, nullptr, nullptr); dbi->TEST_CompactRange(1, nullptr, nullptr);
@ -351,14 +351,14 @@ TEST_F(CorruptionTest, TableFileIndexData) {
Reopen(&options); Reopen(&options);
// build 2 tables, flush at 5000 // build 2 tables, flush at 5000
Build(10000, 5000); Build(10000, 5000);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
dbi->TEST_FlushMemTable(); dbi->TEST_FlushMemTable();
// corrupt an index block of an entire file // corrupt an index block of an entire file
Corrupt(kTableFile, -2000, 500); Corrupt(kTableFile, -2000, 500);
options.paranoid_checks = false; options.paranoid_checks = false;
Reopen(&options); Reopen(&options);
dbi = reinterpret_cast<DBImpl*>(db_); dbi = static_cast_with_check<DBImpl>(db_);
// one full file may be readable, since only one was corrupted // one full file may be readable, since only one was corrupted
// the other file should be fully non-readable, since index was corrupted // the other file should be fully non-readable, since index was corrupted
Check(0, 5000); Check(0, 5000);
@ -398,7 +398,7 @@ TEST_F(CorruptionTest, SequenceNumberRecovery) {
TEST_F(CorruptionTest, CorruptedDescriptor) { TEST_F(CorruptionTest, CorruptedDescriptor) {
ASSERT_OK(db_->Put(WriteOptions(), "foo", "hello")); ASSERT_OK(db_->Put(WriteOptions(), "foo", "hello"));
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
dbi->TEST_FlushMemTable(); dbi->TEST_FlushMemTable();
dbi->TEST_CompactRange(0, nullptr, nullptr); dbi->TEST_CompactRange(0, nullptr, nullptr);
@ -417,7 +417,7 @@ TEST_F(CorruptionTest, CompactionInputError) {
Options options; Options options;
Reopen(&options); Reopen(&options);
Build(10); Build(10);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
dbi->TEST_FlushMemTable(); dbi->TEST_FlushMemTable();
dbi->TEST_CompactRange(0, nullptr, nullptr); dbi->TEST_CompactRange(0, nullptr, nullptr);
dbi->TEST_CompactRange(1, nullptr, nullptr); dbi->TEST_CompactRange(1, nullptr, nullptr);
@ -439,7 +439,7 @@ TEST_F(CorruptionTest, CompactionInputErrorParanoid) {
options.write_buffer_size = 131072; options.write_buffer_size = 131072;
options.max_write_buffer_number = 2; options.max_write_buffer_number = 2;
Reopen(&options); Reopen(&options);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
// Fill levels >= 1 // Fill levels >= 1
for (int level = 1; level < dbi->NumberLevels(); level++) { for (int level = 1; level < dbi->NumberLevels(); level++) {
@ -454,7 +454,7 @@ TEST_F(CorruptionTest, CompactionInputErrorParanoid) {
Reopen(&options); Reopen(&options);
dbi = reinterpret_cast<DBImpl*>(db_); dbi = static_cast_with_check<DBImpl>(db_);
Build(10); Build(10);
dbi->TEST_FlushMemTable(); dbi->TEST_FlushMemTable();
dbi->TEST_WaitForCompact(); dbi->TEST_WaitForCompact();
@ -481,7 +481,7 @@ TEST_F(CorruptionTest, CompactionInputErrorParanoid) {
TEST_F(CorruptionTest, UnrelatedKeys) { TEST_F(CorruptionTest, UnrelatedKeys) {
Build(10); Build(10);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
dbi->TEST_FlushMemTable(); dbi->TEST_FlushMemTable();
Corrupt(kTableFile, 100, 1); Corrupt(kTableFile, 100, 1);
ASSERT_NOK(dbi->VerifyChecksum()); ASSERT_NOK(dbi->VerifyChecksum());
@ -532,7 +532,7 @@ TEST_F(CorruptionTest, FileSystemStateCorrupted) {
Reopen(&options); Reopen(&options);
Build(10); Build(10);
ASSERT_OK(db_->Flush(FlushOptions())); ASSERT_OK(db_->Flush(FlushOptions()));
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
std::vector<LiveFileMetaData> metadata; std::vector<LiveFileMetaData> metadata;
dbi->GetLiveFilesMetaData(&metadata); dbi->GetLiveFilesMetaData(&metadata);
ASSERT_GT(metadata.size(), size_t(0)); ASSERT_GT(metadata.size(), size_t(0));

@ -13,6 +13,7 @@
#include "table/meta_blocks.h" #include "table/meta_blocks.h"
#include "test_util/testharness.h" #include "test_util/testharness.h"
#include "test_util/testutil.h" #include "test_util/testutil.h"
#include "util/cast_util.h"
#include "util/string_util.h" #include "util/string_util.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
@ -46,9 +47,7 @@ class CuckooTableDBTest : public testing::Test {
return options; return options;
} }
DBImpl* dbfull() { DBImpl* dbfull() { return static_cast_with_check<DBImpl>(db_); }
return reinterpret_cast<DBImpl*>(db_);
}
// The following util methods are copied from plain_table_db_test. // The following util methods are copied from plain_table_db_test.
void Reopen(Options* options = nullptr) { void Reopen(Options* options = nullptr) {

@ -1109,7 +1109,7 @@ TEST_P(DBMultiGetTestWithParam, MultiGetMultiCF) {
} }
int get_sv_count = 0; int get_sv_count = 0;
ROCKSDB_NAMESPACE::DBImpl* db = reinterpret_cast<DBImpl*>(db_); ROCKSDB_NAMESPACE::DBImpl* db = static_cast_with_check<DBImpl>(db_);
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack( ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
"DBImpl::MultiGet::AfterRefSV", [&](void* /*arg*/) { "DBImpl::MultiGet::AfterRefSV", [&](void* /*arg*/) {
if (++get_sv_count == 2) { if (++get_sv_count == 2) {
@ -1127,7 +1127,7 @@ TEST_P(DBMultiGetTestWithParam, MultiGetMultiCF) {
} }
if (get_sv_count == 11) { if (get_sv_count == 11) {
for (int i = 0; i < 8; ++i) { for (int i = 0; i < 8; ++i) {
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>( auto* cfd = static_cast_with_check<ColumnFamilyHandleImpl>(
db->GetColumnFamilyHandle(i)) db->GetColumnFamilyHandle(i))
->cfd(); ->cfd();
ASSERT_EQ(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse); ASSERT_EQ(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse);
@ -1178,8 +1178,9 @@ TEST_P(DBMultiGetTestWithParam, MultiGetMultiCF) {
ASSERT_EQ(values[2], std::get<2>(cf_kv_vec[1]) + "_2"); ASSERT_EQ(values[2], std::get<2>(cf_kv_vec[1]) + "_2");
for (int cf = 0; cf < 8; ++cf) { for (int cf = 0; cf < 8; ++cf) {
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>( auto* cfd =
reinterpret_cast<DBImpl*>(db_)->GetColumnFamilyHandle(cf)) static_cast_with_check<ColumnFamilyHandleImpl>(
static_cast_with_check<DBImpl>(db_)->GetColumnFamilyHandle(cf))
->cfd(); ->cfd();
ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse); ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse);
ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVObsolete); ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVObsolete);
@ -1240,8 +1241,9 @@ TEST_P(DBMultiGetTestWithParam, MultiGetMultiCFMutex) {
"cf" + std::to_string(j) + "_val" + std::to_string(retries)); "cf" + std::to_string(j) + "_val" + std::to_string(retries));
} }
for (int i = 0; i < 8; ++i) { for (int i = 0; i < 8; ++i) {
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>( auto* cfd =
reinterpret_cast<DBImpl*>(db_)->GetColumnFamilyHandle(i)) static_cast_with_check<ColumnFamilyHandleImpl>(
static_cast_with_check<DBImpl>(db_)->GetColumnFamilyHandle(i))
->cfd(); ->cfd();
ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse); ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse);
} }
@ -1259,7 +1261,7 @@ TEST_P(DBMultiGetTestWithParam, MultiGetMultiCFSnapshot) {
} }
int get_sv_count = 0; int get_sv_count = 0;
ROCKSDB_NAMESPACE::DBImpl* db = reinterpret_cast<DBImpl*>(db_); ROCKSDB_NAMESPACE::DBImpl* db = static_cast_with_check<DBImpl>(db_);
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack( ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
"DBImpl::MultiGet::AfterRefSV", [&](void* /*arg*/) { "DBImpl::MultiGet::AfterRefSV", [&](void* /*arg*/) {
if (++get_sv_count == 2) { if (++get_sv_count == 2) {
@ -1271,7 +1273,7 @@ TEST_P(DBMultiGetTestWithParam, MultiGetMultiCFSnapshot) {
} }
if (get_sv_count == 8) { if (get_sv_count == 8) {
for (int i = 0; i < 8; ++i) { for (int i = 0; i < 8; ++i) {
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>( auto* cfd = static_cast_with_check<ColumnFamilyHandleImpl>(
db->GetColumnFamilyHandle(i)) db->GetColumnFamilyHandle(i))
->cfd(); ->cfd();
ASSERT_TRUE( ASSERT_TRUE(
@ -1299,8 +1301,9 @@ TEST_P(DBMultiGetTestWithParam, MultiGetMultiCFSnapshot) {
ASSERT_EQ(values[j], "cf" + std::to_string(j) + "_val"); ASSERT_EQ(values[j], "cf" + std::to_string(j) + "_val");
} }
for (int i = 0; i < 8; ++i) { for (int i = 0; i < 8; ++i) {
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>( auto* cfd =
reinterpret_cast<DBImpl*>(db_)->GetColumnFamilyHandle(i)) static_cast_with_check<ColumnFamilyHandleImpl>(
static_cast_with_check<DBImpl>(db_)->GetColumnFamilyHandle(i))
->cfd(); ->cfd();
ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse); ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse);
} }

@ -89,7 +89,7 @@ TEST_F(DBFlushTest, SyncFail) {
CreateAndReopenWithCF({"pikachu"}, options); CreateAndReopenWithCF({"pikachu"}, options);
Put("key", "value"); Put("key", "value");
auto* cfd = auto* cfd =
reinterpret_cast<ColumnFamilyHandleImpl*>(db_->DefaultColumnFamily()) static_cast_with_check<ColumnFamilyHandleImpl>(db_->DefaultColumnFamily())
->cfd(); ->cfd();
FlushOptions flush_options; FlushOptions flush_options;
flush_options.wait = false; flush_options.wait = false;
@ -379,8 +379,8 @@ TEST_F(DBFlushTest, FireOnFlushCompletedAfterCommittedResult) {
DBImpl* db_impl = static_cast_with_check<DBImpl>(db); DBImpl* db_impl = static_cast_with_check<DBImpl>(db);
InstrumentedMutex* mutex = db_impl->mutex(); InstrumentedMutex* mutex = db_impl->mutex();
mutex->Lock(); mutex->Lock();
auto* cfd = auto* cfd = static_cast_with_check<ColumnFamilyHandleImpl>(
reinterpret_cast<ColumnFamilyHandleImpl*>(db->DefaultColumnFamily()) db->DefaultColumnFamily())
->cfd(); ->cfd();
ASSERT_LT(seq, cfd->imm()->current()->GetEarliestSequenceNumber()); ASSERT_LT(seq, cfd->imm()->current()->GetEarliestSequenceNumber());
mutex->Unlock(); mutex->Unlock();

@ -329,7 +329,8 @@ Status DBImpl::ResumeImpl() {
// whether there are flush jobs with non-empty data to flush, triggering // whether there are flush jobs with non-empty data to flush, triggering
// appends to MANIFEST. // appends to MANIFEST.
VersionEdit edit; VersionEdit edit;
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(default_cf_handle_); auto cfh =
static_cast_with_check<ColumnFamilyHandleImpl>(default_cf_handle_);
assert(cfh); assert(cfh);
ColumnFamilyData* cfd = cfh->cfd(); ColumnFamilyData* cfd = cfh->cfd();
const MutableCFOptions& cf_opts = *cfd->GetLatestMutableCFOptions(); const MutableCFOptions& cf_opts = *cfd->GetLatestMutableCFOptions();
@ -945,7 +946,8 @@ Status DBImpl::SetOptions(
(void)options_map; (void)options_map;
return Status::NotSupported("Not supported in ROCKSDB LITE"); return Status::NotSupported("Not supported in ROCKSDB LITE");
#else #else
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd(); auto* cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
if (options_map.empty()) { if (options_map.empty()) {
ROCKS_LOG_WARN(immutable_db_options_.info_log, ROCKS_LOG_WARN(immutable_db_options_.info_log,
"SetOptions() on column family [%s], empty input", "SetOptions() on column family [%s], empty input",
@ -1352,7 +1354,7 @@ InternalIterator* DBImpl::NewInternalIterator(
if (column_family == nullptr) { if (column_family == nullptr) {
cfd = default_cf_handle_->cfd(); cfd = default_cf_handle_->cfd();
} else { } else {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
cfd = cfh->cfd(); cfd = cfh->cfd();
} }
@ -1581,8 +1583,8 @@ Status DBImpl::GetImpl(const ReadOptions& read_options, const Slice& key,
StopWatch sw(env_, stats_, DB_GET); StopWatch sw(env_, stats_, DB_GET);
PERF_TIMER_GUARD(get_snapshot_time); PERF_TIMER_GUARD(get_snapshot_time);
auto cfh = auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(
reinterpret_cast<ColumnFamilyHandleImpl*>(get_impl_options.column_family); get_impl_options.column_family);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
if (tracer_) { if (tracer_) {
@ -1783,7 +1785,7 @@ std::vector<Status> DBImpl::MultiGet(
std::unordered_map<uint32_t, MultiGetColumnFamilyData> multiget_cf_data( std::unordered_map<uint32_t, MultiGetColumnFamilyData> multiget_cf_data(
column_family.size()); column_family.size());
for (auto cf : column_family) { for (auto cf : column_family) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(cf); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(cf);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
if (multiget_cf_data.find(cfd->GetID()) == multiget_cf_data.end()) { if (multiget_cf_data.find(cfd->GetID()) == multiget_cf_data.end()) {
multiget_cf_data.emplace(cfd->GetID(), multiget_cf_data.emplace(cfd->GetID(),
@ -2185,10 +2187,11 @@ void DBImpl::PrepareMultiGetKeys(
KeyContext* lhs = (*sorted_keys)[index - 1]; KeyContext* lhs = (*sorted_keys)[index - 1];
KeyContext* rhs = (*sorted_keys)[index]; KeyContext* rhs = (*sorted_keys)[index];
ColumnFamilyHandleImpl* cfh = ColumnFamilyHandleImpl* cfh =
reinterpret_cast<ColumnFamilyHandleImpl*>(lhs->column_family); static_cast_with_check<ColumnFamilyHandleImpl>(lhs->column_family);
uint32_t cfd_id1 = cfh->cfd()->GetID(); uint32_t cfd_id1 = cfh->cfd()->GetID();
const Comparator* comparator = cfh->cfd()->user_comparator(); const Comparator* comparator = cfh->cfd()->user_comparator();
cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(lhs->column_family); cfh =
static_cast_with_check<ColumnFamilyHandleImpl>(lhs->column_family);
uint32_t cfd_id2 = cfh->cfd()->GetID(); uint32_t cfd_id2 = cfh->cfd()->GetID();
assert(cfd_id1 <= cfd_id2); assert(cfd_id1 <= cfd_id2);
@ -2552,7 +2555,7 @@ Status DBImpl::CreateColumnFamilyImpl(const ColumnFamilyOptions& cf_options,
// this is outside the mutex // this is outside the mutex
if (s.ok()) { if (s.ok()) {
NewThreadStatusCfInfo( NewThreadStatusCfInfo(
reinterpret_cast<ColumnFamilyHandleImpl*>(*handle)->cfd()); static_cast_with_check<ColumnFamilyHandleImpl>(*handle)->cfd());
} }
return s; return s;
} }
@ -2589,7 +2592,7 @@ Status DBImpl::DropColumnFamilies(
} }
Status DBImpl::DropColumnFamilyImpl(ColumnFamilyHandle* column_family) { Status DBImpl::DropColumnFamilyImpl(ColumnFamilyHandle* column_family) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
if (cfd->GetID() == 0) { if (cfd->GetID() == 0) {
return Status::InvalidArgument("Can't drop default column family"); return Status::InvalidArgument("Can't drop default column family");
@ -2703,7 +2706,7 @@ Iterator* DBImpl::NewIterator(const ReadOptions& read_options,
"Iterator requested internal keys which are too old and are not" "Iterator requested internal keys which are too old and are not"
" guaranteed to be preserved, try larger iter_start_seqnum opt.")); " guaranteed to be preserved, try larger iter_start_seqnum opt."));
} }
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
ColumnFamilyData* cfd = cfh->cfd(); ColumnFamilyData* cfd = cfh->cfd();
assert(cfd != nullptr); assert(cfd != nullptr);
ReadCallback* read_callback = nullptr; // No read callback provided. ReadCallback* read_callback = nullptr; // No read callback provided.
@ -2838,7 +2841,7 @@ Status DBImpl::NewIterators(
"Tailing iterator not supported in RocksDB lite"); "Tailing iterator not supported in RocksDB lite");
#else #else
for (auto cfh : column_families) { for (auto cfh : column_families) {
auto cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(cfh)->cfd(); auto cfd = static_cast_with_check<ColumnFamilyHandleImpl>(cfh)->cfd();
SuperVersion* sv = cfd->GetReferencedSuperVersion(this); SuperVersion* sv = cfd->GetReferencedSuperVersion(this);
auto iter = new ForwardIterator(this, read_options, cfd, sv, auto iter = new ForwardIterator(this, read_options, cfd, sv,
/* allow_unprepared_value */ true); /* allow_unprepared_value */ true);
@ -2858,7 +2861,8 @@ Status DBImpl::NewIterators(
: versions_->LastSequence(); : versions_->LastSequence();
for (size_t i = 0; i < column_families.size(); ++i) { for (size_t i = 0; i < column_families.size(); ++i) {
auto* cfd = auto* cfd =
reinterpret_cast<ColumnFamilyHandleImpl*>(column_families[i])->cfd(); static_cast_with_check<ColumnFamilyHandleImpl>(column_families[i])
->cfd();
iterators->push_back( iterators->push_back(
NewIteratorImpl(read_options, cfd, snapshot, read_callback)); NewIteratorImpl(read_options, cfd, snapshot, read_callback));
} }
@ -2965,7 +2969,7 @@ void DBImpl::ReleaseSnapshot(const Snapshot* s) {
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
Status DBImpl::GetPropertiesOfAllTables(ColumnFamilyHandle* column_family, Status DBImpl::GetPropertiesOfAllTables(ColumnFamilyHandle* column_family,
TablePropertiesCollection* props) { TablePropertiesCollection* props) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
// Increment the ref count // Increment the ref count
@ -2987,7 +2991,7 @@ Status DBImpl::GetPropertiesOfAllTables(ColumnFamilyHandle* column_family,
Status DBImpl::GetPropertiesOfTablesInRange(ColumnFamilyHandle* column_family, Status DBImpl::GetPropertiesOfTablesInRange(ColumnFamilyHandle* column_family,
const Range* range, std::size_t n, const Range* range, std::size_t n,
TablePropertiesCollection* props) { TablePropertiesCollection* props) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
// Increment the ref count // Increment the ref count
@ -3023,7 +3027,7 @@ FileSystem* DBImpl::GetFileSystem() const {
Options DBImpl::GetOptions(ColumnFamilyHandle* column_family) const { Options DBImpl::GetOptions(ColumnFamilyHandle* column_family) const {
InstrumentedMutexLock l(&mutex_); InstrumentedMutexLock l(&mutex_);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
return Options(BuildDBOptions(immutable_db_options_, mutable_db_options_), return Options(BuildDBOptions(immutable_db_options_, mutable_db_options_),
cfh->cfd()->GetLatestCFOptions()); cfh->cfd()->GetLatestCFOptions());
} }
@ -3037,7 +3041,8 @@ bool DBImpl::GetProperty(ColumnFamilyHandle* column_family,
const Slice& property, std::string* value) { const Slice& property, std::string* value) {
const DBPropertyInfo* property_info = GetPropertyInfo(property); const DBPropertyInfo* property_info = GetPropertyInfo(property);
value->clear(); value->clear();
auto cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd(); auto cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
if (property_info == nullptr) { if (property_info == nullptr) {
return false; return false;
} else if (property_info->handle_int) { } else if (property_info->handle_int) {
@ -3071,7 +3076,8 @@ bool DBImpl::GetMapProperty(ColumnFamilyHandle* column_family,
std::map<std::string, std::string>* value) { std::map<std::string, std::string>* value) {
const DBPropertyInfo* property_info = GetPropertyInfo(property); const DBPropertyInfo* property_info = GetPropertyInfo(property);
value->clear(); value->clear();
auto cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd(); auto cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
if (property_info == nullptr) { if (property_info == nullptr) {
return false; return false;
} else if (property_info->handle_map) { } else if (property_info->handle_map) {
@ -3090,7 +3096,8 @@ bool DBImpl::GetIntProperty(ColumnFamilyHandle* column_family,
if (property_info == nullptr || property_info->handle_int == nullptr) { if (property_info == nullptr || property_info->handle_int == nullptr) {
return false; return false;
} }
auto cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd(); auto cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
return GetIntPropertyInternal(cfd, *property_info, false, value); return GetIntPropertyInternal(cfd, *property_info, false, value);
} }
@ -3263,7 +3270,7 @@ void DBImpl::GetApproximateMemTableStats(ColumnFamilyHandle* column_family,
uint64_t* const count, uint64_t* const count,
uint64_t* const size) { uint64_t* const size) {
ColumnFamilyHandleImpl* cfh = ColumnFamilyHandleImpl* cfh =
reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
ColumnFamilyData* cfd = cfh->cfd(); ColumnFamilyData* cfd = cfh->cfd();
SuperVersion* sv = GetAndRefSuperVersion(cfd); SuperVersion* sv = GetAndRefSuperVersion(cfd);
@ -3288,7 +3295,7 @@ Status DBImpl::GetApproximateSizes(const SizeApproximationOptions& options,
} }
Version* v; Version* v;
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
SuperVersion* sv = GetAndRefSuperVersion(cfd); SuperVersion* sv = GetAndRefSuperVersion(cfd);
v = sv->current; v = sv->current;
@ -3446,7 +3453,7 @@ Status DBImpl::DeleteFilesInRanges(ColumnFamilyHandle* column_family,
const RangePtr* ranges, size_t n, const RangePtr* ranges, size_t n,
bool include_end) { bool include_end) {
Status status; Status status;
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
ColumnFamilyData* cfd = cfh->cfd(); ColumnFamilyData* cfd = cfh->cfd();
VersionEdit edit; VersionEdit edit;
std::set<FileMetaData*> deleted_files; std::set<FileMetaData*> deleted_files;
@ -3544,7 +3551,8 @@ Status DBImpl::GetLiveFilesChecksumInfo(FileChecksumList* checksum_list) {
void DBImpl::GetColumnFamilyMetaData(ColumnFamilyHandle* column_family, void DBImpl::GetColumnFamilyMetaData(ColumnFamilyHandle* column_family,
ColumnFamilyMetaData* cf_meta) { ColumnFamilyMetaData* cf_meta) {
assert(column_family); assert(column_family);
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd(); auto* cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
auto* sv = GetAndRefSuperVersion(cfd); auto* sv = GetAndRefSuperVersion(cfd);
{ {
// Without mutex, Version::GetColumnFamilyMetaData will have data race with // Without mutex, Version::GetColumnFamilyMetaData will have data race with
@ -4510,7 +4518,7 @@ Status DBImpl::CreateColumnFamilyWithImport(
} }
// Import sst files from metadata. // Import sst files from metadata.
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(*handle); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(*handle);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
ImportColumnFamilyJob import_job(env_, versions_.get(), cfd, ImportColumnFamilyJob import_job(env_, versions_.get(), cfd,
immutable_db_options_, file_options_, immutable_db_options_, file_options_,

@ -695,7 +695,7 @@ void DBImpl::NotifyOnFlushCompleted(
Status DBImpl::CompactRange(const CompactRangeOptions& options, Status DBImpl::CompactRange(const CompactRangeOptions& options,
ColumnFamilyHandle* column_family, ColumnFamilyHandle* column_family,
const Slice* begin, const Slice* end) { const Slice* begin, const Slice* end) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
if (options.target_path_id >= cfd->ioptions()->cf_paths.size()) { if (options.target_path_id >= cfd->ioptions()->cf_paths.size()) {
@ -885,7 +885,8 @@ Status DBImpl::CompactFiles(const CompactionOptions& compact_options,
return Status::InvalidArgument("ColumnFamilyHandle must be non-null."); return Status::InvalidArgument("ColumnFamilyHandle must be non-null.");
} }
auto cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd(); auto cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
assert(cfd); assert(cfd);
Status s; Status s;
@ -1359,7 +1360,7 @@ Status DBImpl::ReFitLevel(ColumnFamilyData* cfd, int level, int target_level) {
} }
int DBImpl::NumberLevels(ColumnFamilyHandle* column_family) { int DBImpl::NumberLevels(ColumnFamilyHandle* column_family) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
return cfh->cfd()->NumberLevels(); return cfh->cfd()->NumberLevels();
} }
@ -1368,7 +1369,7 @@ int DBImpl::MaxMemCompactionLevel(ColumnFamilyHandle* /*column_family*/) {
} }
int DBImpl::Level0StopWriteTrigger(ColumnFamilyHandle* column_family) { int DBImpl::Level0StopWriteTrigger(ColumnFamilyHandle* column_family) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
InstrumentedMutexLock l(&mutex_); InstrumentedMutexLock l(&mutex_);
return cfh->cfd() return cfh->cfd()
->GetSuperVersion() ->GetSuperVersion()
@ -1377,7 +1378,7 @@ int DBImpl::Level0StopWriteTrigger(ColumnFamilyHandle* column_family) {
Status DBImpl::Flush(const FlushOptions& flush_options, Status DBImpl::Flush(const FlushOptions& flush_options,
ColumnFamilyHandle* column_family) { ColumnFamilyHandle* column_family) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
ROCKS_LOG_INFO(immutable_db_options_.info_log, "[%s] Manual flush start.", ROCKS_LOG_INFO(immutable_db_options_.info_log, "[%s] Manual flush start.",
cfh->GetName().c_str()); cfh->GetName().c_str());
Status s; Status s;

@ -47,7 +47,7 @@ int64_t DBImpl::TEST_MaxNextLevelOverlappingBytes(
if (column_family == nullptr) { if (column_family == nullptr) {
cfd = default_cf_handle_->cfd(); cfd = default_cf_handle_->cfd();
} else { } else {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
cfd = cfh->cfd(); cfd = cfh->cfd();
} }
InstrumentedMutexLock l(&mutex_); InstrumentedMutexLock l(&mutex_);
@ -57,7 +57,7 @@ int64_t DBImpl::TEST_MaxNextLevelOverlappingBytes(
void DBImpl::TEST_GetFilesMetaData( void DBImpl::TEST_GetFilesMetaData(
ColumnFamilyHandle* column_family, ColumnFamilyHandle* column_family,
std::vector<std::vector<FileMetaData>>* metadata) { std::vector<std::vector<FileMetaData>>* metadata) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
InstrumentedMutexLock l(&mutex_); InstrumentedMutexLock l(&mutex_);
metadata->resize(NumberLevels()); metadata->resize(NumberLevels());
@ -88,7 +88,7 @@ Status DBImpl::TEST_CompactRange(int level, const Slice* begin,
if (column_family == nullptr) { if (column_family == nullptr) {
cfd = default_cf_handle_->cfd(); cfd = default_cf_handle_->cfd();
} else { } else {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
cfd = cfh->cfd(); cfd = cfh->cfd();
} }
int output_level = int output_level =
@ -131,7 +131,7 @@ Status DBImpl::TEST_FlushMemTable(bool wait, bool allow_write_stall,
if (cfh == nullptr) { if (cfh == nullptr) {
cfd = default_cf_handle_->cfd(); cfd = default_cf_handle_->cfd();
} else { } else {
auto cfhi = reinterpret_cast<ColumnFamilyHandleImpl*>(cfh); auto cfhi = static_cast_with_check<ColumnFamilyHandleImpl>(cfh);
cfd = cfhi->cfd(); cfd = cfhi->cfd();
} }
return FlushMemTable(cfd, fo, FlushReason::kTest); return FlushMemTable(cfd, fo, FlushReason::kTest);
@ -152,7 +152,7 @@ Status DBImpl::TEST_WaitForFlushMemTable(ColumnFamilyHandle* column_family) {
if (column_family == nullptr) { if (column_family == nullptr) {
cfd = default_cf_handle_->cfd(); cfd = default_cf_handle_->cfd();
} else { } else {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
cfd = cfh->cfd(); cfd = cfh->cfd();
} }
return WaitForFlushMemTable(cfd, nullptr, false); return WaitForFlushMemTable(cfd, nullptr, false);
@ -242,7 +242,7 @@ Status DBImpl::TEST_GetLatestMutableCFOptions(
ColumnFamilyHandle* column_family, MutableCFOptions* mutable_cf_options) { ColumnFamilyHandle* column_family, MutableCFOptions* mutable_cf_options) {
InstrumentedMutexLock l(&mutex_); InstrumentedMutexLock l(&mutex_);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
*mutable_cf_options = *cfh->cfd()->GetLatestMutableCFOptions(); *mutable_cf_options = *cfh->cfd()->GetLatestMutableCFOptions();
return Status::OK(); return Status::OK();
} }

@ -7,22 +7,22 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "db/db_impl/db_impl.h"
#include <cinttypes> #include <cinttypes>
#include <vector> #include <vector>
#include "db/column_family.h" #include "db/column_family.h"
#include "db/db_impl/db_impl.h"
#include "db/job_context.h" #include "db/job_context.h"
#include "db/version_set.h" #include "db/version_set.h"
#include "rocksdb/status.h" #include "rocksdb/status.h"
#include "util/cast_util.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
Status DBImpl::SuggestCompactRange(ColumnFamilyHandle* column_family, Status DBImpl::SuggestCompactRange(ColumnFamilyHandle* column_family,
const Slice* begin, const Slice* end) { const Slice* begin, const Slice* end) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
InternalKey start_key, end_key; InternalKey start_key, end_key;
if (begin != nullptr) { if (begin != nullptr) {

@ -4,13 +4,14 @@
// (found in the LICENSE.Apache file in the root directory). // (found in the LICENSE.Apache file in the root directory).
#include "db/db_impl/db_impl_readonly.h" #include "db/db_impl/db_impl_readonly.h"
#include "db/arena_wrapped_db_iter.h"
#include "db/arena_wrapped_db_iter.h"
#include "db/compacted_db_impl.h" #include "db/compacted_db_impl.h"
#include "db/db_impl/db_impl.h" #include "db/db_impl/db_impl.h"
#include "db/db_iter.h" #include "db/db_iter.h"
#include "db/merge_context.h" #include "db/merge_context.h"
#include "monitoring/perf_context_imp.h" #include "monitoring/perf_context_imp.h"
#include "util/cast_util.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
@ -35,7 +36,7 @@ Status DBImplReadOnly::Get(const ReadOptions& read_options,
PERF_TIMER_GUARD(get_snapshot_time); PERF_TIMER_GUARD(get_snapshot_time);
Status s; Status s;
SequenceNumber snapshot = versions_->LastSequence(); SequenceNumber snapshot = versions_->LastSequence();
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
if (tracer_) { if (tracer_) {
InstrumentedMutexLock lock(&trace_mutex_); InstrumentedMutexLock lock(&trace_mutex_);
@ -70,7 +71,7 @@ Status DBImplReadOnly::Get(const ReadOptions& read_options,
Iterator* DBImplReadOnly::NewIterator(const ReadOptions& read_options, Iterator* DBImplReadOnly::NewIterator(const ReadOptions& read_options,
ColumnFamilyHandle* column_family) { ColumnFamilyHandle* column_family) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
SuperVersion* super_version = cfd->GetSuperVersion()->Ref(); SuperVersion* super_version = cfd->GetSuperVersion()->Ref();
SequenceNumber latest_snapshot = versions_->LastSequence(); SequenceNumber latest_snapshot = versions_->LastSequence();
@ -111,7 +112,7 @@ Status DBImplReadOnly::NewIterators(
: latest_snapshot; : latest_snapshot;
for (auto cfh : column_families) { for (auto cfh : column_families) {
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(cfh)->cfd(); auto* cfd = static_cast_with_check<ColumnFamilyHandleImpl>(cfh)->cfd();
auto* sv = cfd->GetSuperVersion()->Ref(); auto* sv = cfd->GetSuperVersion()->Ref();
auto* db_iter = NewArenaWrappedDbIterator( auto* db_iter = NewArenaWrappedDbIterator(
env_, read_options, *cfd->ioptions(), sv->mutable_cf_options, read_seq, env_, read_options, *cfd->ioptions(), sv->mutable_cf_options, read_seq,
@ -236,7 +237,7 @@ Status DBImplReadOnly::OpenForReadOnlyWithoutCheck(
*dbptr = impl; *dbptr = impl;
for (auto* h : *handles) { for (auto* h : *handles) {
impl->NewThreadStatusCfInfo( impl->NewThreadStatusCfInfo(
reinterpret_cast<ColumnFamilyHandleImpl*>(h)->cfd()); static_cast_with_check<ColumnFamilyHandleImpl>(h)->cfd());
} }
} else { } else {
for (auto h : *handles) { for (auto h : *handles) {

@ -388,7 +388,7 @@ Iterator* DBImplSecondary::NewIterator(const ReadOptions& read_options,
"ReadTier::kPersistedData is not yet supported in iterators.")); "ReadTier::kPersistedData is not yet supported in iterators."));
} }
Iterator* result = nullptr; Iterator* result = nullptr;
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
ReadCallback* read_callback = nullptr; // No read callback provided. ReadCallback* read_callback = nullptr; // No read callback provided.
if (read_options.tailing) { if (read_options.tailing) {
@ -642,7 +642,7 @@ Status DB::OpenAsSecondary(
*dbptr = impl; *dbptr = impl;
for (auto h : *handles) { for (auto h : *handles) {
impl->NewThreadStatusCfInfo( impl->NewThreadStatusCfInfo(
reinterpret_cast<ColumnFamilyHandleImpl*>(h)->cfd()); static_cast_with_check<ColumnFamilyHandleImpl>(h)->cfd());
} }
} else { } else {
for (auto h : *handles) { for (auto h : *handles) {

@ -6,14 +6,15 @@
// Copyright (c) 2011 The LevelDB Authors. All rights reserved. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "db/db_impl/db_impl.h"
#include <cinttypes> #include <cinttypes>
#include "db/db_impl/db_impl.h"
#include "db/error_handler.h" #include "db/error_handler.h"
#include "db/event_helpers.h" #include "db/event_helpers.h"
#include "monitoring/perf_context_imp.h" #include "monitoring/perf_context_imp.h"
#include "options/options_helper.h" #include "options/options_helper.h"
#include "test_util/sync_point.h" #include "test_util/sync_point.h"
#include "util/cast_util.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
// Convenience methods // Convenience methods
@ -24,7 +25,7 @@ Status DBImpl::Put(const WriteOptions& o, ColumnFamilyHandle* column_family,
Status DBImpl::Merge(const WriteOptions& o, ColumnFamilyHandle* column_family, Status DBImpl::Merge(const WriteOptions& o, ColumnFamilyHandle* column_family,
const Slice& key, const Slice& val) { const Slice& key, const Slice& val) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
if (!cfh->cfd()->ioptions()->merge_operator) { if (!cfh->cfd()->ioptions()->merge_operator) {
return Status::NotSupported("Provide a merge_operator when opening DB"); return Status::NotSupported("Provide a merge_operator when opening DB");
} else { } else {

@ -40,7 +40,8 @@ class DBIteratorTest : public DBTestBase,
if (column_family == nullptr) { if (column_family == nullptr) {
column_family = db_->DefaultColumnFamily(); column_family = db_->DefaultColumnFamily();
} }
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd(); auto* cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
SequenceNumber seq = read_options.snapshot != nullptr SequenceNumber seq = read_options.snapshot != nullptr
? read_options.snapshot->GetSequenceNumber() ? read_options.snapshot->GetSequenceNumber()
: db_->GetLatestSequenceNumber(); : db_->GetLatestSequenceNumber();
@ -2911,7 +2912,7 @@ TEST_F(DBIteratorWithReadCallbackTest, ReadCallback) {
SequenceNumber seq2 = db_->GetLatestSequenceNumber(); SequenceNumber seq2 = db_->GetLatestSequenceNumber();
auto* cfd = auto* cfd =
reinterpret_cast<ColumnFamilyHandleImpl*>(db_->DefaultColumnFamily()) static_cast_with_check<ColumnFamilyHandleImpl>(db_->DefaultColumnFamily())
->cfd(); ->cfd();
// The iterator are suppose to see data before seq1. // The iterator are suppose to see data before seq1.
Iterator* iter = Iterator* iter =

@ -459,7 +459,7 @@ TEST_F(DBRangeDelTest, ValidUniversalSubcompactionBoundaries) {
// probably means universal compaction + subcompaction + range deletion are // probably means universal compaction + subcompaction + range deletion are
// compatible. // compatible.
ASSERT_OK(dbfull()->RunManualCompaction( ASSERT_OK(dbfull()->RunManualCompaction(
reinterpret_cast<ColumnFamilyHandleImpl*>(db_->DefaultColumnFamily()) static_cast_with_check<ColumnFamilyHandleImpl>(db_->DefaultColumnFamily())
->cfd(), ->cfd(),
1 /* input_level */, 2 /* output_level */, CompactRangeOptions(), 1 /* input_level */, 2 /* output_level */, CompactRangeOptions(),
nullptr /* begin */, nullptr /* end */, true /* exclusive */, nullptr /* begin */, nullptr /* end */, true /* exclusive */,

@ -126,7 +126,7 @@ TEST_F(DBTest, MockEnvTest) {
// TEST_FlushMemTable() is not supported in ROCKSDB_LITE // TEST_FlushMemTable() is not supported in ROCKSDB_LITE
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
DBImpl* dbi = reinterpret_cast<DBImpl*>(db); DBImpl* dbi = static_cast_with_check<DBImpl>(db);
ASSERT_OK(dbi->TEST_FlushMemTable()); ASSERT_OK(dbi->TEST_FlushMemTable());
for (size_t i = 0; i < 3; ++i) { for (size_t i = 0; i < 3; ++i) {
@ -174,7 +174,7 @@ TEST_F(DBTest, MemEnvTest) {
ASSERT_TRUE(!iterator->Valid()); ASSERT_TRUE(!iterator->Valid());
delete iterator; delete iterator;
DBImpl* dbi = reinterpret_cast<DBImpl*>(db); DBImpl* dbi = static_cast_with_check<DBImpl>(db);
ASSERT_OK(dbi->TEST_FlushMemTable()); ASSERT_OK(dbi->TEST_FlushMemTable());
for (size_t i = 0; i < 3; ++i) { for (size_t i = 0; i < 3; ++i) {

@ -1725,7 +1725,7 @@ TEST_F(DBTest2, DuplicateSnapshot) {
Options options; Options options;
options = CurrentOptions(options); options = CurrentOptions(options);
std::vector<const Snapshot*> snapshots; std::vector<const Snapshot*> snapshots;
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
SequenceNumber oldest_ww_snap, first_ww_snap; SequenceNumber oldest_ww_snap, first_ww_snap;
Put("k", "v"); // inc seq Put("k", "v"); // inc seq
@ -4176,7 +4176,7 @@ TEST_F(DBTest2, TestGetColumnFamilyHandleUnlocked) {
CreateColumnFamilies({"test1", "test2"}, Options()); CreateColumnFamilies({"test1", "test2"}, Options());
ASSERT_EQ(handles_.size(), 2); ASSERT_EQ(handles_.size(), 2);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_); DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
port::Thread user_thread1([&]() { port::Thread user_thread1([&]() {
auto cfh = dbi->GetColumnFamilyHandleUnlocked(handles_[0]->GetID()); auto cfh = dbi->GetColumnFamilyHandleUnlocked(handles_[0]->GetID());
ASSERT_EQ(cfh->GetID(), handles_[0]->GetID()); ASSERT_EQ(cfh->GetID(), handles_[0]->GetID());

@ -10,9 +10,9 @@
#pragma once #pragma once
#include <fcntl.h> #include <fcntl.h>
#include <cinttypes>
#include <algorithm> #include <algorithm>
#include <cinttypes>
#include <map> #include <map>
#include <set> #include <set>
#include <string> #include <string>
@ -43,12 +43,12 @@
#include "table/plain/plain_table_factory.h" #include "table/plain/plain_table_factory.h"
#include "table/scoped_arena_iterator.h" #include "table/scoped_arena_iterator.h"
#include "test_util/mock_time_env.h" #include "test_util/mock_time_env.h"
#include "util/compression.h"
#include "util/mutexlock.h"
#include "test_util/sync_point.h" #include "test_util/sync_point.h"
#include "test_util/testharness.h" #include "test_util/testharness.h"
#include "test_util/testutil.h" #include "test_util/testutil.h"
#include "util/cast_util.h"
#include "util/compression.h"
#include "util/mutexlock.h"
#include "util/string_util.h" #include "util/string_util.h"
#include "utilities/merge_operators.h" #include "utilities/merge_operators.h"
@ -922,7 +922,7 @@ class DBTestBase : public testing::Test {
const anon::OptionsOverride& options_override = const anon::OptionsOverride& options_override =
anon::OptionsOverride()) const; anon::OptionsOverride()) const;
DBImpl* dbfull() { return reinterpret_cast<DBImpl*>(db_); } DBImpl* dbfull() { return static_cast_with_check<DBImpl>(db_); }
void CreateColumnFamilies(const std::vector<std::string>& cfs, void CreateColumnFamilies(const std::vector<std::string>& cfs,
const Options& options); const Options& options);

@ -436,7 +436,7 @@ TEST_F(EventListenerTest, MultiDBMultiListeners) {
for (size_t c = 0; c < cf_names.size(); ++c) { for (size_t c = 0; c < cf_names.size(); ++c) {
for (int d = 0; d < kNumDBs; ++d) { for (int d = 0; d < kNumDBs; ++d) {
ASSERT_OK(dbs[d]->Flush(FlushOptions(), vec_handles[d][c])); ASSERT_OK(dbs[d]->Flush(FlushOptions(), vec_handles[d][c]));
reinterpret_cast<DBImpl*>(dbs[d])->TEST_WaitForFlushMemTable(); static_cast_with_check<DBImpl>(dbs[d])->TEST_WaitForFlushMemTable();
} }
} }

@ -32,6 +32,7 @@
#include "table/table_builder.h" #include "table/table_builder.h"
#include "test_util/testharness.h" #include "test_util/testharness.h"
#include "test_util/testutil.h" #include "test_util/testutil.h"
#include "util/cast_util.h"
#include "util/hash.h" #include "util/hash.h"
#include "util/mutexlock.h" #include "util/mutexlock.h"
#include "util/string_util.h" #include "util/string_util.h"
@ -146,9 +147,7 @@ class PlainTableDBTest : public testing::Test,
return options; return options;
} }
DBImpl* dbfull() { DBImpl* dbfull() { return static_cast_with_check<DBImpl>(db_); }
return reinterpret_cast<DBImpl*>(db_);
}
void Reopen(Options* options = nullptr) { void Reopen(Options* options = nullptr) {
ASSERT_OK(TryReopen(options)); ASSERT_OK(TryReopen(options));

@ -27,6 +27,7 @@ int main() {
#include "rocksdb/slice_transform.h" #include "rocksdb/slice_transform.h"
#include "rocksdb/table.h" #include "rocksdb/table.h"
#include "test_util/testharness.h" #include "test_util/testharness.h"
#include "util/cast_util.h"
#include "util/coding.h" #include "util/coding.h"
#include "util/gflags_compat.h" #include "util/gflags_compat.h"
#include "util/random.h" #include "util/random.h"
@ -807,13 +808,13 @@ TEST_F(PrefixTest, PrefixSeekModePrev2) {
PutKey(db.get(), write_options, TestKey(3, 3), "v33"); PutKey(db.get(), write_options, TestKey(3, 3), "v33");
PutKey(db.get(), write_options, TestKey(3, 4), "v34"); PutKey(db.get(), write_options, TestKey(3, 4), "v34");
db->Flush(FlushOptions()); db->Flush(FlushOptions());
reinterpret_cast<DBImpl*>(db.get())->TEST_WaitForFlushMemTable(); static_cast_with_check<DBImpl>(db.get())->TEST_WaitForFlushMemTable();
PutKey(db.get(), write_options, TestKey(1, 1), "v11"); PutKey(db.get(), write_options, TestKey(1, 1), "v11");
PutKey(db.get(), write_options, TestKey(1, 3), "v13"); PutKey(db.get(), write_options, TestKey(1, 3), "v13");
PutKey(db.get(), write_options, TestKey(2, 1), "v21"); PutKey(db.get(), write_options, TestKey(2, 1), "v21");
PutKey(db.get(), write_options, TestKey(2, 2), "v22"); PutKey(db.get(), write_options, TestKey(2, 2), "v22");
db->Flush(FlushOptions()); db->Flush(FlushOptions());
reinterpret_cast<DBImpl*>(db.get())->TEST_WaitForFlushMemTable(); static_cast_with_check<DBImpl>(db.get())->TEST_WaitForFlushMemTable();
std::unique_ptr<Iterator> iter(db->NewIterator(read_options)); std::unique_ptr<Iterator> iter(db->NewIterator(read_options));
SeekIterator(iter.get(), 1, 5); SeekIterator(iter.get(), 1, 5);
iter->Prev(); iter->Prev();
@ -839,13 +840,13 @@ TEST_F(PrefixTest, PrefixSeekModePrev3) {
PutKey(db.get(), write_options, TestKey(1, 2), "v12"); PutKey(db.get(), write_options, TestKey(1, 2), "v12");
PutKey(db.get(), write_options, TestKey(1, 4), "v14"); PutKey(db.get(), write_options, TestKey(1, 4), "v14");
db->Flush(FlushOptions()); db->Flush(FlushOptions());
reinterpret_cast<DBImpl*>(db.get())->TEST_WaitForFlushMemTable(); static_cast_with_check<DBImpl>(db.get())->TEST_WaitForFlushMemTable();
PutKey(db.get(), write_options, TestKey(1, 1), "v11"); PutKey(db.get(), write_options, TestKey(1, 1), "v11");
PutKey(db.get(), write_options, TestKey(1, 3), "v13"); PutKey(db.get(), write_options, TestKey(1, 3), "v13");
PutKey(db.get(), write_options, TestKey(2, 1), "v21"); PutKey(db.get(), write_options, TestKey(2, 1), "v21");
PutKey(db.get(), write_options, TestKey(2, 2), "v22"); PutKey(db.get(), write_options, TestKey(2, 2), "v22");
db->Flush(FlushOptions()); db->Flush(FlushOptions());
reinterpret_cast<DBImpl*>(db.get())->TEST_WaitForFlushMemTable(); static_cast_with_check<DBImpl>(db.get())->TEST_WaitForFlushMemTable();
std::unique_ptr<Iterator> iter(db->NewIterator(read_options)); std::unique_ptr<Iterator> iter(db->NewIterator(read_options));
iter->SeekToLast(); iter->SeekToLast();
ASSERT_EQ(iter->value(), v14); ASSERT_EQ(iter->value(), v14);
@ -861,11 +862,11 @@ TEST_F(PrefixTest, PrefixSeekModePrev3) {
PutKey(db.get(), write_options, TestKey(3, 3), "v33"); PutKey(db.get(), write_options, TestKey(3, 3), "v33");
PutKey(db.get(), write_options, TestKey(3, 4), "v34"); PutKey(db.get(), write_options, TestKey(3, 4), "v34");
db->Flush(FlushOptions()); db->Flush(FlushOptions());
reinterpret_cast<DBImpl*>(db.get())->TEST_WaitForFlushMemTable(); static_cast_with_check<DBImpl>(db.get())->TEST_WaitForFlushMemTable();
PutKey(db.get(), write_options, TestKey(1, 1), "v11"); PutKey(db.get(), write_options, TestKey(1, 1), "v11");
PutKey(db.get(), write_options, TestKey(1, 3), "v13"); PutKey(db.get(), write_options, TestKey(1, 3), "v13");
db->Flush(FlushOptions()); db->Flush(FlushOptions());
reinterpret_cast<DBImpl*>(db.get())->TEST_WaitForFlushMemTable(); static_cast_with_check<DBImpl>(db.get())->TEST_WaitForFlushMemTable();
std::unique_ptr<Iterator> iter(db->NewIterator(read_options)); std::unique_ptr<Iterator> iter(db->NewIterator(read_options));
iter->SeekToLast(); iter->SeekToLast();
ASSERT_EQ(iter->value(), v14); ASSERT_EQ(iter->value(), v14);

@ -1641,7 +1641,8 @@ class MemTableInserter : public WriteBatch::Handler {
if (cf_handle == nullptr) { if (cf_handle == nullptr) {
cf_handle = db_->DefaultColumnFamily(); cf_handle = db_->DefaultColumnFamily();
} }
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(cf_handle)->cfd(); auto* cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(cf_handle)->cfd();
if (!cfd->is_delete_range_supported()) { if (!cfd->is_delete_range_supported()) {
return Status::NotSupported( return Status::NotSupported(
std::string("DeleteRange not supported for table type ") + std::string("DeleteRange not supported for table type ") +

@ -1504,7 +1504,7 @@ void StressTest::TestAcquireSnapshot(ThreadState* thread,
Slice key = keystr; Slice key = keystr;
ColumnFamilyHandle* column_family = column_families_[rand_column_family]; ColumnFamilyHandle* column_family = column_families_[rand_column_family];
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
auto db_impl = reinterpret_cast<DBImpl*>(db_->GetRootDB()); auto db_impl = static_cast_with_check<DBImpl>(db_->GetRootDB());
const bool ww_snapshot = thread->rand.OneIn(10); const bool ww_snapshot = thread->rand.OneIn(10);
const Snapshot* snapshot = const Snapshot* snapshot =
ww_snapshot ? db_impl->GetSnapshotForWriteConflictBoundary() ww_snapshot ? db_impl->GetSnapshotForWriteConflictBoundary()

@ -7,6 +7,7 @@
#include "db/column_family.h" #include "db/column_family.h"
#include "monitoring/thread_status_updater.h" #include "monitoring/thread_status_updater.h"
#include "util/cast_util.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
@ -19,7 +20,7 @@ void ThreadStatusUpdater::TEST_VerifyColumnFamilyInfoMap(
assert(cf_info_map_.size() == handles.size()); assert(cf_info_map_.size() == handles.size());
} }
for (auto* handle : handles) { for (auto* handle : handles) {
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(handle)->cfd(); auto* cfd = static_cast_with_check<ColumnFamilyHandleImpl>(handle)->cfd();
auto iter __attribute__((__unused__)) = cf_info_map_.find(cfd); auto iter __attribute__((__unused__)) = cf_info_map_.find(cfd);
if (check_exist) { if (check_exist) {
assert(iter != cf_info_map_.end()); assert(iter != cf_info_map_.end());

@ -13,6 +13,7 @@
#include "test_util/testharness.h" #include "test_util/testharness.h"
#include "test_util/testutil.h" #include "test_util/testutil.h"
#include "tools/ldb_cmd_impl.h" #include "tools/ldb_cmd_impl.h"
#include "util/cast_util.h"
#include "util/string_util.h" #include "util/string_util.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
@ -47,12 +48,12 @@ public:
if (db_ == nullptr) { if (db_ == nullptr) {
return Status::InvalidArgument("DB not opened."); return Status::InvalidArgument("DB not opened.");
} }
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db_); DBImpl* db_impl = static_cast_with_check<DBImpl>(db_);
return db_impl->TEST_FlushMemTable(); return db_impl->TEST_FlushMemTable();
} }
void MoveL0FileToLevel(int level) { void MoveL0FileToLevel(int level) {
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db_); DBImpl* db_impl = static_cast_with_check<DBImpl>(db_);
for (int i = 0; i < level; ++i) { for (int i = 0; i < level; ++i) {
ASSERT_OK(db_impl->TEST_CompactRange(i, nullptr, nullptr)); ASSERT_OK(db_impl->TEST_CompactRange(i, nullptr, nullptr));
} }

@ -4,11 +4,10 @@
// (found in the LICENSE.Apache file in the root directory). // (found in the LICENSE.Apache file in the root directory).
#pragma once #pragma once
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
// The helper function to assert the move from dynamic_cast<> to // The helper function to assert the move from dynamic_cast<> to
// static_cast<> is correct. This function is to deal with legacy code. // static_cast<> is correct. This function is to deal with legacy code.
// It is not recommanded to add new code to issue class casting. The preferred // It is not recommended to add new code to issue class casting. The preferred
// solution is to implement the functionality without a need of casting. // solution is to implement the functionality without a need of casting.
template <class DestClass, class SrcClass> template <class DestClass, class SrcClass>
inline DestClass* static_cast_with_check(SrcClass* x) { inline DestClass* static_cast_with_check(SrcClass* x) {

@ -9,6 +9,8 @@
#if !defined(ROCKSDB_LITE) && !defined(OS_WIN) #if !defined(ROCKSDB_LITE) && !defined(OS_WIN)
#include "rocksdb/utilities/backupable_db.h"
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
#include <string> #include <string>
@ -22,11 +24,11 @@
#include "rocksdb/rate_limiter.h" #include "rocksdb/rate_limiter.h"
#include "rocksdb/transaction_log.h" #include "rocksdb/transaction_log.h"
#include "rocksdb/types.h" #include "rocksdb/types.h"
#include "rocksdb/utilities/backupable_db.h"
#include "rocksdb/utilities/options_util.h" #include "rocksdb/utilities/options_util.h"
#include "test_util/sync_point.h" #include "test_util/sync_point.h"
#include "test_util/testharness.h" #include "test_util/testharness.h"
#include "test_util/testutil.h" #include "test_util/testutil.h"
#include "util/cast_util.h"
#include "util/mutexlock.h" #include "util/mutexlock.h"
#include "util/random.h" #include "util/random.h"
#include "util/stderr_logger.h" #include "util/stderr_logger.h"
@ -2009,7 +2011,7 @@ TEST_F(BackupableDBTest, ChangeManifestDuringBackupCreation) {
// The last manifest roll would've already been cleaned up by the full scan // The last manifest roll would've already been cleaned up by the full scan
// that happens when CreateNewBackup invokes EnableFileDeletions. We need to // that happens when CreateNewBackup invokes EnableFileDeletions. We need to
// trigger another roll to verify non-full scan purges stale manifests. // trigger another roll to verify non-full scan purges stale manifests.
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db_.get()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db_.get());
std::string prev_manifest_path = std::string prev_manifest_path =
DescriptorFileName(dbname_, db_impl->TEST_Current_Manifest_FileNo()); DescriptorFileName(dbname_, db_impl->TEST_Current_Manifest_FileNo());
FillDB(db_.get(), 0, 100); FillDB(db_.get(), 0, 100);

@ -995,7 +995,8 @@ Status BlobDBImpl::Write(const WriteOptions& options, WriteBatch* updates) {
StopWatch write_sw(env_, statistics_, BLOB_DB_WRITE_MICROS); StopWatch write_sw(env_, statistics_, BLOB_DB_WRITE_MICROS);
RecordTick(statistics_, BLOB_DB_NUM_WRITE); RecordTick(statistics_, BLOB_DB_NUM_WRITE);
uint32_t default_cf_id = uint32_t default_cf_id =
reinterpret_cast<ColumnFamilyHandleImpl*>(DefaultColumnFamily())->GetID(); static_cast_with_check<ColumnFamilyHandleImpl>(DefaultColumnFamily())
->GetID();
Status s; Status s;
BlobInserter blob_inserter(options, this, default_cf_id); BlobInserter blob_inserter(options, this, default_cf_id);
{ {
@ -1050,7 +1051,8 @@ Status BlobDBImpl::PutBlobValue(const WriteOptions& /*options*/,
Status s; Status s;
std::string index_entry; std::string index_entry;
uint32_t column_family_id = uint32_t column_family_id =
reinterpret_cast<ColumnFamilyHandleImpl*>(DefaultColumnFamily())->GetID(); static_cast_with_check<ColumnFamilyHandleImpl>(DefaultColumnFamily())
->GetID();
if (value.size() < bdb_options_.min_blob_size) { if (value.size() < bdb_options_.min_blob_size) {
if (expiration == kNoExpiration) { if (expiration == kNoExpiration) {
// Put as normal value // Put as normal value
@ -2029,7 +2031,8 @@ void BlobDBImpl::CopyBlobFiles(
Iterator* BlobDBImpl::NewIterator(const ReadOptions& read_options) { Iterator* BlobDBImpl::NewIterator(const ReadOptions& read_options) {
auto* cfd = auto* cfd =
reinterpret_cast<ColumnFamilyHandleImpl*>(DefaultColumnFamily())->cfd(); static_cast_with_check<ColumnFamilyHandleImpl>(DefaultColumnFamily())
->cfd();
// Get a snapshot to avoid blob file get deleted between we // Get a snapshot to avoid blob file get deleted between we
// fetch and index entry and reading from the file. // fetch and index entry and reading from the file.
ManagedSnapshot* own_snapshot = nullptr; ManagedSnapshot* own_snapshot = nullptr;

@ -5,11 +5,11 @@
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
#include "utilities/blob_db/blob_db_impl.h"
#include "file/filename.h" #include "file/filename.h"
#include "logging/logging.h" #include "logging/logging.h"
#include "util/cast_util.h"
#include "util/mutexlock.h" #include "util/mutexlock.h"
#include "utilities/blob_db/blob_db_impl.h"
// BlobDBImpl methods to get snapshot of files, e.g. for replication. // BlobDBImpl methods to get snapshot of files, e.g. for replication.
@ -98,7 +98,8 @@ void BlobDBImpl::GetLiveFilesMetaData(std::vector<LiveFileMetaData>* metadata) {
// Path should be relative to db_name, but begin with slash. // Path should be relative to db_name, but begin with slash.
filemetadata.name = BlobFileName("", bdb_options_.blob_dir, file_number); filemetadata.name = BlobFileName("", bdb_options_.blob_dir, file_number);
filemetadata.file_number = file_number; filemetadata.file_number = file_number;
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(DefaultColumnFamily()); auto cfh =
static_cast_with_check<ColumnFamilyHandleImpl>(DefaultColumnFamily());
filemetadata.column_family_name = cfh->GetName(); filemetadata.column_family_name = cfh->GetName();
metadata->emplace_back(filemetadata); metadata->emplace_back(filemetadata);
} }

@ -4,11 +4,13 @@
// (found in the LICENSE.Apache file in the root directory). // (found in the LICENSE.Apache file in the root directory).
#include <iostream> #include <iostream>
#include "db/db_impl/db_impl.h" #include "db/db_impl/db_impl.h"
#include "rocksdb/db.h" #include "rocksdb/db.h"
#include "rocksdb/merge_operator.h" #include "rocksdb/merge_operator.h"
#include "rocksdb/utilities/db_ttl.h" #include "rocksdb/utilities/db_ttl.h"
#include "test_util/testharness.h" #include "test_util/testharness.h"
#include "util/cast_util.h"
#include "util/random.h" #include "util/random.h"
#include "utilities/cassandra/cassandra_compaction_filter.h" #include "utilities/cassandra/cassandra_compaction_filter.h"
#include "utilities/cassandra/merge_operator.h" #include "utilities/cassandra/merge_operator.h"
@ -89,7 +91,7 @@ class CassandraStore {
WriteOptions write_option_; WriteOptions write_option_;
ReadOptions get_option_; ReadOptions get_option_;
DBImpl* dbfull() { return reinterpret_cast<DBImpl*>(db_.get()); } DBImpl* dbfull() { return static_cast_with_check<DBImpl>(db_.get()); }
}; };
class TestCompactionFilterFactory : public CompactionFilterFactory { class TestCompactionFilterFactory : public CompactionFilterFactory {

@ -26,6 +26,7 @@
#include "rocksdb/transaction_log.h" #include "rocksdb/transaction_log.h"
#include "rocksdb/utilities/checkpoint.h" #include "rocksdb/utilities/checkpoint.h"
#include "test_util/sync_point.h" #include "test_util/sync_point.h"
#include "util/cast_util.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
@ -367,7 +368,7 @@ Status CheckpointImpl::CreateCustomCheckpoint(
Status CheckpointImpl::ExportColumnFamily( Status CheckpointImpl::ExportColumnFamily(
ColumnFamilyHandle* handle, const std::string& export_dir, ColumnFamilyHandle* handle, const std::string& export_dir,
ExportImportFilesMetaData** metadata) { ExportImportFilesMetaData** metadata) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(handle); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(handle);
const auto cf_name = cfh->GetName(); const auto cf_name = cfh->GetName();
const auto db_options = db_->GetDBOptions(); const auto db_options = db_->GetDBOptions();

@ -223,7 +223,7 @@ TEST_P(TransactionTest, ValidateSnapshotTest) {
} }
if (with_flush) { if (with_flush) {
auto db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); auto db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
db_impl->TEST_FlushMemTable(true); db_impl->TEST_FlushMemTable(true);
// Make sure the flushed memtable is not kept in memory // Make sure the flushed memtable is not kept in memory
int max_memtable_in_history = int max_memtable_in_history =
@ -882,7 +882,7 @@ TEST_P(TransactionTest, LogMarkLeakTest) {
assert(db != nullptr); assert(db != nullptr);
Random rnd(47); Random rnd(47);
std::vector<Transaction*> txns; std::vector<Transaction*> txns;
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
// At the beginning there should be no log containing prepare data // At the beginning there should be no log containing prepare data
ASSERT_EQ(db_impl->TEST_FindMinLogContainingOutstandingPrep(), 0); ASSERT_EQ(db_impl->TEST_FindMinLogContainingOutstandingPrep(), 0);
for (size_t i = 0; i < 100; i++) { for (size_t i = 0; i < 100; i++) {
@ -923,7 +923,7 @@ TEST_P(TransactionTest, SimpleTwoPhaseTransactionTest) {
string value; string value;
Status s; Status s;
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
Transaction* txn = db->BeginTransaction(write_options, txn_options); Transaction* txn = db->BeginTransaction(write_options, txn_options);
s = txn->SetName("xid"); s = txn->SetName("xid");
@ -1160,7 +1160,7 @@ TEST_P(TransactionTest, TwoPhaseEmptyWriteTest) {
ASSERT_EQ(value, "bar"); ASSERT_EQ(value, "bar");
} else { } else {
if (test_with_empty_wal) { if (test_with_empty_wal) {
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
db_impl->TEST_FlushMemTable(true); db_impl->TEST_FlushMemTable(true);
// After flush the state must be visible // After flush the state must be visible
s = db->Get(read_options, "foo", &value); s = db->Get(read_options, "foo", &value);
@ -1222,7 +1222,7 @@ TEST_P(TransactionTest, TwoPhaseRollbackTest) {
std::string value; std::string value;
Status s; Status s;
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
Transaction* txn = db->BeginTransaction(write_options, txn_options); Transaction* txn = db->BeginTransaction(write_options, txn_options);
s = txn->SetName("xid"); s = txn->SetName("xid");
ASSERT_OK(s); ASSERT_OK(s);
@ -1293,7 +1293,7 @@ TEST_P(TransactionTest, PersistentTwoPhaseTransactionTest) {
std::string value; std::string value;
Status s; Status s;
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
Transaction* txn = db->BeginTransaction(write_options, txn_options); Transaction* txn = db->BeginTransaction(write_options, txn_options);
s = txn->SetName("xid"); s = txn->SetName("xid");
@ -1340,7 +1340,7 @@ TEST_P(TransactionTest, PersistentTwoPhaseTransactionTest) {
s = ReOpenNoDelete(); s = ReOpenNoDelete();
ASSERT_OK(s); ASSERT_OK(s);
assert(db != nullptr); assert(db != nullptr);
db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
// find trans in list of prepared transactions // find trans in list of prepared transactions
std::vector<Transaction*> prepared_trans; std::vector<Transaction*> prepared_trans;
@ -1685,7 +1685,7 @@ TEST_P(TransactionTest, TwoPhaseDoubleRecoveryTest) {
} }
TEST_P(TransactionTest, TwoPhaseLogRollingTest) { TEST_P(TransactionTest, TwoPhaseLogRollingTest) {
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
Status s; Status s;
std::string v; std::string v;
@ -1837,7 +1837,7 @@ TEST_P(TransactionTest, TwoPhaseLogRollingTest) {
} }
TEST_P(TransactionTest, TwoPhaseLogRollingTest2) { TEST_P(TransactionTest, TwoPhaseLogRollingTest2) {
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
Status s; Status s;
ColumnFamilyHandle *cfa, *cfb; ColumnFamilyHandle *cfa, *cfb;
@ -1852,8 +1852,8 @@ TEST_P(TransactionTest, TwoPhaseLogRollingTest2) {
wopts.disableWAL = false; wopts.disableWAL = false;
wopts.sync = true; wopts.sync = true;
auto cfh_a = reinterpret_cast<ColumnFamilyHandleImpl*>(cfa); auto cfh_a = static_cast_with_check<ColumnFamilyHandleImpl>(cfa);
auto cfh_b = reinterpret_cast<ColumnFamilyHandleImpl*>(cfb); auto cfh_b = static_cast_with_check<ColumnFamilyHandleImpl>(cfb);
TransactionOptions topts1; TransactionOptions topts1;
Transaction* txn1 = db->BeginTransaction(wopts, topts1); Transaction* txn1 = db->BeginTransaction(wopts, topts1);
@ -1982,7 +1982,7 @@ TEST_P(TransactionTest, TwoPhaseLogRollingTest2) {
* hidden behind improperly summed sequence ids * hidden behind improperly summed sequence ids
*/ */
TEST_P(TransactionTest, TwoPhaseOutOfOrderDelete) { TEST_P(TransactionTest, TwoPhaseOutOfOrderDelete) {
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
WriteOptions wal_on, wal_off; WriteOptions wal_on, wal_off;
wal_on.sync = true; wal_on.sync = true;
wal_on.disableWAL = false; wal_on.disableWAL = false;
@ -2301,7 +2301,7 @@ TEST_P(TransactionTest, FlushTest2) {
TransactionOptions txn_options; TransactionOptions txn_options;
string value; string value;
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
db->Put(write_options, Slice("foo"), Slice("bar")); db->Put(write_options, Slice("foo"), Slice("bar"));
db->Put(write_options, Slice("foo2"), Slice("bar2")); db->Put(write_options, Slice("foo2"), Slice("bar2"));
@ -5187,13 +5187,13 @@ TEST_P(TransactionTest, ToggleAutoCompactionTest) {
&handles, &db); &handles, &db);
ASSERT_OK(s); ASSERT_OK(s);
auto cfh_default = reinterpret_cast<ColumnFamilyHandleImpl*>(handles[0]); auto cfh_default = static_cast_with_check<ColumnFamilyHandleImpl>(handles[0]);
auto opt_default = *cfh_default->cfd()->GetLatestMutableCFOptions(); auto opt_default = *cfh_default->cfd()->GetLatestMutableCFOptions();
auto cfh_a = reinterpret_cast<ColumnFamilyHandleImpl*>(handles[1]); auto cfh_a = static_cast_with_check<ColumnFamilyHandleImpl>(handles[1]);
auto opt_a = *cfh_a->cfd()->GetLatestMutableCFOptions(); auto opt_a = *cfh_a->cfd()->GetLatestMutableCFOptions();
auto cfh_b = reinterpret_cast<ColumnFamilyHandleImpl*>(handles[2]); auto cfh_b = static_cast_with_check<ColumnFamilyHandleImpl>(handles[2]);
auto opt_b = *cfh_b->cfd()->GetLatestMutableCFOptions(); auto opt_b = *cfh_b->cfd()->GetLatestMutableCFOptions();
ASSERT_EQ(opt_default.disable_auto_compactions, false); ASSERT_EQ(opt_default.disable_auto_compactions, false);
@ -5441,7 +5441,7 @@ TEST_P(TransactionStressTest, SeqAdvanceTest) {
}; };
const size_t max_n = static_cast<size_t>(1) << NUM_BRANCHES; const size_t max_n = static_cast<size_t>(1) << NUM_BRANCHES;
for (size_t n = 0; n < max_n; n++) { for (size_t n = 0; n < max_n; n++) {
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
size_t branch = 0; size_t branch = 0;
auto seq = db_impl->GetLatestSequenceNumber(); auto seq = db_impl->GetLatestSequenceNumber();
exp_seq = seq; exp_seq = seq;
@ -5457,7 +5457,7 @@ TEST_P(TransactionStressTest, SeqAdvanceTest) {
if (!short_test && branch_do(n, &branch)) { if (!short_test && branch_do(n, &branch)) {
ASSERT_OK(db_impl->FlushWAL(true)); ASSERT_OK(db_impl->FlushWAL(true));
ASSERT_OK(ReOpenNoDelete()); ASSERT_OK(ReOpenNoDelete());
db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
seq = db_impl->GetLatestSequenceNumber(); seq = db_impl->GetLatestSequenceNumber();
ASSERT_EQ(exp_seq, seq); ASSERT_EQ(exp_seq, seq);
} }
@ -5479,7 +5479,7 @@ TEST_P(TransactionStressTest, SeqAdvanceTest) {
if (!short_test && branch_do(n, &branch)) { if (!short_test && branch_do(n, &branch)) {
ASSERT_OK(db_impl->FlushWAL(true)); ASSERT_OK(db_impl->FlushWAL(true));
ASSERT_OK(ReOpenNoDelete()); ASSERT_OK(ReOpenNoDelete());
db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
seq = db_impl->GetLatestSequenceNumber(); seq = db_impl->GetLatestSequenceNumber();
ASSERT_EQ(exp_seq, seq); ASSERT_EQ(exp_seq, seq);
} }
@ -5496,7 +5496,7 @@ TEST_P(TransactionStressTest, SeqAdvanceTest) {
if (!short_test && branch_do(n, &branch)) { if (!short_test && branch_do(n, &branch)) {
ASSERT_OK(db_impl->FlushWAL(true)); ASSERT_OK(db_impl->FlushWAL(true));
ASSERT_OK(ReOpenNoDelete()); ASSERT_OK(ReOpenNoDelete());
db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
seq = db_impl->GetLatestSequenceNumber(); seq = db_impl->GetLatestSequenceNumber();
ASSERT_EQ(exp_seq, seq); ASSERT_EQ(exp_seq, seq);
} }
@ -5514,7 +5514,7 @@ TEST_P(TransactionStressTest, SeqAdvanceTest) {
if (!short_test && branch_do(n, &branch)) { if (!short_test && branch_do(n, &branch)) {
ASSERT_OK(db_impl->FlushWAL(true)); ASSERT_OK(db_impl->FlushWAL(true));
ASSERT_OK(ReOpenNoDelete()); ASSERT_OK(ReOpenNoDelete());
db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
seq = db_impl->GetLatestSequenceNumber(); seq = db_impl->GetLatestSequenceNumber();
ASSERT_EQ(exp_seq, seq); ASSERT_EQ(exp_seq, seq);
} }
@ -5531,7 +5531,7 @@ TEST_P(TransactionStressTest, SeqAdvanceTest) {
if (!short_test && branch_do(n, &branch)) { if (!short_test && branch_do(n, &branch)) {
ASSERT_OK(db_impl->FlushWAL(true)); ASSERT_OK(db_impl->FlushWAL(true));
ASSERT_OK(ReOpenNoDelete()); ASSERT_OK(ReOpenNoDelete());
db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
seq = db_impl->GetLatestSequenceNumber(); seq = db_impl->GetLatestSequenceNumber();
ASSERT_EQ(exp_seq, seq); ASSERT_EQ(exp_seq, seq);
} }
@ -5917,7 +5917,7 @@ TEST_P(TransactionTest, DuplicateKeys) {
// This will check the asserts inside recovery code // This will check the asserts inside recovery code
db->FlushWAL(true); db->FlushWAL(true);
// Flush only cf 1 // Flush only cf 1
reinterpret_cast<DBImpl*>(db->GetRootDB()) static_cast_with_check<DBImpl>(db->GetRootDB())
->TEST_FlushMemTable(true, false, handles[1]); ->TEST_FlushMemTable(true, false, handles[1]);
reinterpret_cast<PessimisticTransactionDB*>(db)->TEST_Crash(); reinterpret_cast<PessimisticTransactionDB*>(db)->TEST_Crash();
ASSERT_OK(ReOpenNoDelete(cfds, &handles)); ASSERT_OK(ReOpenNoDelete(cfds, &handles));
@ -5955,7 +5955,7 @@ TEST_P(TransactionTest, DuplicateKeys) {
// This will check the asserts inside recovery code // This will check the asserts inside recovery code
ASSERT_OK(db->FlushWAL(true)); ASSERT_OK(db->FlushWAL(true));
// Flush only cf 1 // Flush only cf 1
reinterpret_cast<DBImpl*>(db->GetRootDB()) static_cast_with_check<DBImpl>(db->GetRootDB())
->TEST_FlushMemTable(true, false, handles[1]); ->TEST_FlushMemTable(true, false, handles[1]);
reinterpret_cast<PessimisticTransactionDB*>(db)->TEST_Crash(); reinterpret_cast<PessimisticTransactionDB*>(db)->TEST_Crash();
ASSERT_OK(ReOpenNoDelete(cfds, &handles)); ASSERT_OK(ReOpenNoDelete(cfds, &handles));
@ -5988,7 +5988,7 @@ TEST_P(TransactionTest, DuplicateKeys) {
// This will check the asserts inside recovery code // This will check the asserts inside recovery code
ASSERT_OK(db->FlushWAL(true)); ASSERT_OK(db->FlushWAL(true));
// Flush only cf 1 // Flush only cf 1
reinterpret_cast<DBImpl*>(db->GetRootDB()) static_cast_with_check<DBImpl>(db->GetRootDB())
->TEST_FlushMemTable(true, false, handles[1]); ->TEST_FlushMemTable(true, false, handles[1]);
reinterpret_cast<PessimisticTransactionDB*>(db)->TEST_Crash(); reinterpret_cast<PessimisticTransactionDB*>(db)->TEST_Crash();
ASSERT_OK(ReOpenNoDelete(cfds, &handles)); ASSERT_OK(ReOpenNoDelete(cfds, &handles));
@ -6015,7 +6015,7 @@ TEST_P(TransactionTest, DuplicateKeys) {
// This will check the asserts inside recovery code // This will check the asserts inside recovery code
ASSERT_OK(db->FlushWAL(true)); ASSERT_OK(db->FlushWAL(true));
// Flush only cf 1 // Flush only cf 1
reinterpret_cast<DBImpl*>(db->GetRootDB()) static_cast_with_check<DBImpl>(db->GetRootDB())
->TEST_FlushMemTable(true, false, handles[1]); ->TEST_FlushMemTable(true, false, handles[1]);
reinterpret_cast<PessimisticTransactionDB*>(db)->TEST_Crash(); reinterpret_cast<PessimisticTransactionDB*>(db)->TEST_Crash();
ASSERT_OK(ReOpenNoDelete(cfds, &handles)); ASSERT_OK(ReOpenNoDelete(cfds, &handles));
@ -6042,7 +6042,7 @@ TEST_P(TransactionTest, DuplicateKeys) {
// This will check the asserts inside recovery code // This will check the asserts inside recovery code
ASSERT_OK(db->FlushWAL(true)); ASSERT_OK(db->FlushWAL(true));
// Flush only cf 1 // Flush only cf 1
reinterpret_cast<DBImpl*>(db->GetRootDB()) static_cast_with_check<DBImpl>(db->GetRootDB())
->TEST_FlushMemTable(true, false, handles[1]); ->TEST_FlushMemTable(true, false, handles[1]);
reinterpret_cast<PessimisticTransactionDB*>(db)->TEST_Crash(); reinterpret_cast<PessimisticTransactionDB*>(db)->TEST_Crash();
ASSERT_OK(ReOpenNoDelete(cfds, &handles)); ASSERT_OK(ReOpenNoDelete(cfds, &handles));
@ -6157,7 +6157,7 @@ TEST_P(TransactionTest, DoubleCrashInRecovery) {
ASSERT_OK(db->Put(write_options, "foo4", "bar4")); ASSERT_OK(db->Put(write_options, "foo4", "bar4"));
db->FlushWAL(true); db->FlushWAL(true);
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
uint64_t wal_file_id = db_impl->TEST_LogfileNumber(); uint64_t wal_file_id = db_impl->TEST_LogfileNumber();
std::string fname = LogFileName(dbname, wal_file_id); std::string fname = LogFileName(dbname, wal_file_id);
reinterpret_cast<PessimisticTransactionDB*>(db)->TEST_Crash(); reinterpret_cast<PessimisticTransactionDB*>(db)->TEST_Crash();

@ -437,7 +437,7 @@ class TransactionTestBase : public ::testing::Test {
if (txn_db_options.write_policy == WRITE_COMMITTED) { if (txn_db_options.write_policy == WRITE_COMMITTED) {
options.unordered_write = false; options.unordered_write = false;
} }
auto db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); auto db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
// Before upgrade/downgrade the WAL must be emptied // Before upgrade/downgrade the WAL must be emptied
if (empty_wal) { if (empty_wal) {
db_impl->TEST_FlushMemTable(); db_impl->TEST_FlushMemTable();
@ -453,7 +453,7 @@ class TransactionTestBase : public ::testing::Test {
ASSERT_TRUE(s.IsNotSupported()); ASSERT_TRUE(s.IsNotSupported());
return; return;
} }
db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
// Check that WAL is empty // Check that WAL is empty
VectorLogPtr log_files; VectorLogPtr log_files;
db_impl->GetSortedWalFiles(log_files); db_impl->GetSortedWalFiles(log_files);

@ -14,6 +14,7 @@
#include "db/db_impl/db_impl.h" #include "db/db_impl/db_impl.h"
#include "rocksdb/status.h" #include "rocksdb/status.h"
#include "rocksdb/utilities/write_batch_with_index.h" #include "rocksdb/utilities/write_batch_with_index.h"
#include "util/cast_util.h"
#include "util/string_util.h" #include "util/string_util.h"
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
@ -24,7 +25,7 @@ Status TransactionUtil::CheckKeyForConflicts(
SequenceNumber min_uncommitted) { SequenceNumber min_uncommitted) {
Status result; Status result;
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfd = cfh->cfd(); auto cfd = cfh->cfd();
SuperVersion* sv = db_impl->GetAndRefSuperVersion(cfd); SuperVersion* sv = db_impl->GetAndRefSuperVersion(cfd);

@ -1676,7 +1676,7 @@ TEST_P(SeqAdvanceConcurrentTest, SeqAdvanceConcurrent) {
if (n % 1000 == 0) { if (n % 1000 == 0) {
printf("Tested %" ROCKSDB_PRIszt " cases so far\n", n); printf("Tested %" ROCKSDB_PRIszt " cases so far\n", n);
} }
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
auto seq = db_impl->TEST_GetLastVisibleSequence(); auto seq = db_impl->TEST_GetLastVisibleSequence();
with_empty_commits = 0; with_empty_commits = 0;
exp_seq = seq; exp_seq = seq;
@ -1768,7 +1768,7 @@ TEST_P(SeqAdvanceConcurrentTest, SeqAdvanceConcurrent) {
db_impl->FlushWAL(true); db_impl->FlushWAL(true);
ReOpenNoDelete(); ReOpenNoDelete();
assert(db != nullptr); assert(db != nullptr);
db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
seq = db_impl->TEST_GetLastVisibleSequence(); seq = db_impl->TEST_GetLastVisibleSequence();
ASSERT_LE(exp_seq, seq + with_empty_commits); ASSERT_LE(exp_seq, seq + with_empty_commits);
@ -1781,7 +1781,7 @@ TEST_P(SeqAdvanceConcurrentTest, SeqAdvanceConcurrent) {
db_impl->FlushWAL(true); db_impl->FlushWAL(true);
ReOpenNoDelete(); ReOpenNoDelete();
assert(db != nullptr); assert(db != nullptr);
db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
seq = db_impl->GetLatestSequenceNumber(); seq = db_impl->GetLatestSequenceNumber();
ASSERT_LE(exp_seq, seq + with_empty_commits); ASSERT_LE(exp_seq, seq + with_empty_commits);
} }
@ -1947,7 +1947,7 @@ TEST_P(WritePreparedTransactionTest, IsInSnapshotEmptyMap) {
delete txn; delete txn;
} }
dynamic_cast<WritePreparedTxnDB*>(db)->TEST_Crash(); dynamic_cast<WritePreparedTxnDB*>(db)->TEST_Crash();
auto db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); auto db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
db_impl->FlushWAL(true); db_impl->FlushWAL(true);
ReOpenNoDelete(); ReOpenNoDelete();
WritePreparedTxnDB* wp_db = dynamic_cast<WritePreparedTxnDB*>(db); WritePreparedTxnDB* wp_db = dynamic_cast<WritePreparedTxnDB*>(db);
@ -2285,7 +2285,7 @@ TEST_P(WritePreparedTransactionTest, Rollback) {
if (crash) { if (crash) {
delete txn; delete txn;
auto db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); auto db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
db_impl->FlushWAL(true); db_impl->FlushWAL(true);
dynamic_cast<WritePreparedTxnDB*>(db)->TEST_Crash(); dynamic_cast<WritePreparedTxnDB*>(db)->TEST_Crash();
ReOpenNoDelete(); ReOpenNoDelete();
@ -2344,7 +2344,7 @@ TEST_P(WritePreparedTransactionTest, DisableGCDuringRecovery) {
} }
std::reverse(std::begin(versions), std::end(versions)); std::reverse(std::begin(versions), std::end(versions));
VerifyInternalKeys(versions); VerifyInternalKeys(versions);
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
db_impl->FlushWAL(true); db_impl->FlushWAL(true);
// Use small buffer to ensure memtable flush during recovery // Use small buffer to ensure memtable flush during recovery
options.write_buffer_size = 1024; options.write_buffer_size = 1024;
@ -2376,7 +2376,7 @@ TEST_P(WritePreparedTransactionTest, SequenceNumberZero) {
TEST_P(WritePreparedTransactionTest, CompactionShouldKeepUncommittedKeys) { TEST_P(WritePreparedTransactionTest, CompactionShouldKeepUncommittedKeys) {
options.disable_auto_compactions = true; options.disable_auto_compactions = true;
ReOpen(); ReOpen();
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
// Snapshots to avoid keys get evicted. // Snapshots to avoid keys get evicted.
std::vector<const Snapshot*> snapshots; std::vector<const Snapshot*> snapshots;
// Keep track of expected sequence number. // Keep track of expected sequence number.
@ -2475,7 +2475,7 @@ TEST_P(WritePreparedTransactionTest, CompactionShouldKeepSnapshotVisibleKeys) {
ASSERT_OK(txn1->Prepare()); ASSERT_OK(txn1->Prepare());
ASSERT_EQ(++expected_seq, db->GetLatestSequenceNumber()); ASSERT_EQ(++expected_seq, db->GetLatestSequenceNumber());
ASSERT_OK(txn1->Commit()); ASSERT_OK(txn1->Commit());
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
ASSERT_EQ(++expected_seq, db_impl->TEST_GetLastVisibleSequence()); ASSERT_EQ(++expected_seq, db_impl->TEST_GetLastVisibleSequence());
delete txn1; delete txn1;
// Take a snapshots to avoid keys get evicted before compaction. // Take a snapshots to avoid keys get evicted before compaction.
@ -2881,7 +2881,7 @@ TEST_P(WritePreparedTransactionTest,
ASSERT_EQ(++expected_seq, db->GetLatestSequenceNumber()); ASSERT_EQ(++expected_seq, db->GetLatestSequenceNumber());
SequenceNumber seq1 = expected_seq; SequenceNumber seq1 = expected_seq;
ASSERT_OK(db->Put(WriteOptions(), "key2", "value2")); ASSERT_OK(db->Put(WriteOptions(), "key2", "value2"));
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
expected_seq++; // one for data expected_seq++; // one for data
if (options.two_write_queues) { if (options.two_write_queues) {
expected_seq++; // one for commit expected_seq++; // one for commit
@ -3019,7 +3019,7 @@ TEST_P(WritePreparedTransactionTest, NonAtomicCommitOfDelayedPrepared) {
UpdateTransactionDBOptions(snapshot_cache_bits, commit_cache_bits); UpdateTransactionDBOptions(snapshot_cache_bits, commit_cache_bits);
ReOpen(); ReOpen();
WritePreparedTxnDB* wp_db = dynamic_cast<WritePreparedTxnDB*>(db); WritePreparedTxnDB* wp_db = dynamic_cast<WritePreparedTxnDB*>(db);
DBImpl* db_impl = reinterpret_cast<DBImpl*>(db->GetRootDB()); DBImpl* db_impl = static_cast_with_check<DBImpl>(db->GetRootDB());
// Fill up the commit cache // Fill up the commit cache
std::string init_value("value1"); std::string init_value("value1");
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {

@ -339,7 +339,8 @@ Iterator* WritePreparedTxnDB::NewIterator(const ReadOptions& options,
own_snapshot = std::make_shared<ManagedSnapshot>(db_impl_, snapshot); own_snapshot = std::make_shared<ManagedSnapshot>(db_impl_, snapshot);
} }
assert(snapshot_seq != kMaxSequenceNumber); assert(snapshot_seq != kMaxSequenceNumber);
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd(); auto* cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
auto* state = auto* state =
new IteratorState(this, snapshot_seq, own_snapshot, min_uncommitted); new IteratorState(this, snapshot_seq, own_snapshot, min_uncommitted);
auto* db_iter = auto* db_iter =
@ -375,7 +376,8 @@ Status WritePreparedTxnDB::NewIterators(
iterators->clear(); iterators->clear();
iterators->reserve(column_families.size()); iterators->reserve(column_families.size());
for (auto* column_family : column_families) { for (auto* column_family : column_families) {
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd(); auto* cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
auto* state = auto* state =
new IteratorState(this, snapshot_seq, own_snapshot, min_uncommitted); new IteratorState(this, snapshot_seq, own_snapshot, min_uncommitted);
auto* db_iter = auto* db_iter =

@ -452,7 +452,8 @@ Iterator* WriteUnpreparedTxnDB::NewIterator(const ReadOptions& options,
min_uncommitted = min_uncommitted =
static_cast_with_check<const SnapshotImpl>(snapshot)->min_uncommitted_; static_cast_with_check<const SnapshotImpl>(snapshot)->min_uncommitted_;
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd(); auto* cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
auto* state = auto* state =
new IteratorState(this, snapshot_seq, own_snapshot, min_uncommitted, txn); new IteratorState(this, snapshot_seq, own_snapshot, min_uncommitted, txn);
auto* db_iter = auto* db_iter =

@ -893,7 +893,7 @@ Status WriteBatchWithIndex::GetFromBatchAndDB(
if (s.ok() || s.IsNotFound()) { // DB Get Succeeded if (s.ok() || s.IsNotFound()) { // DB Get Succeeded
if (result == WriteBatchWithIndexInternal::Result::kMergeInProgress) { if (result == WriteBatchWithIndexInternal::Result::kMergeInProgress) {
// Merge result from DB with merges in Batch // Merge result from DB with merges in Batch
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
const MergeOperator* merge_operator = const MergeOperator* merge_operator =
cfh->cfd()->ioptions()->merge_operator; cfh->cfd()->ioptions()->merge_operator;
Statistics* statistics = immuable_db_options.statistics.get(); Statistics* statistics = immuable_db_options.statistics.get();
@ -997,7 +997,7 @@ void WriteBatchWithIndex::MultiGetFromBatchAndDB(
&sorted_keys); &sorted_keys);
ColumnFamilyHandleImpl* cfh = ColumnFamilyHandleImpl* cfh =
reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
const MergeOperator* merge_operator = cfh->cfd()->ioptions()->merge_operator; const MergeOperator* merge_operator = cfh->cfd()->ioptions()->merge_operator;
for (auto iter = key_context.begin(); iter != key_context.end(); ++iter) { for (auto iter = key_context.begin(); iter != key_context.end(); ++iter) {
KeyContext& key = *iter; KeyContext& key = *iter;

@ -13,6 +13,7 @@
#include "rocksdb/comparator.h" #include "rocksdb/comparator.h"
#include "rocksdb/db.h" #include "rocksdb/db.h"
#include "rocksdb/utilities/write_batch_with_index.h" #include "rocksdb/utilities/write_batch_with_index.h"
#include "util/cast_util.h"
#include "util/coding.h" #include "util/coding.h"
#include "util/string_util.h" #include "util/string_util.h"
@ -249,7 +250,8 @@ WriteBatchWithIndexInternal::Result WriteBatchWithIndexInternal::GetFromBatch(
const MergeOperator* merge_operator; const MergeOperator* merge_operator;
if (column_family != nullptr) { if (column_family != nullptr) {
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); auto cfh =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
merge_operator = cfh->cfd()->ioptions()->merge_operator; merge_operator = cfh->cfd()->ioptions()->merge_operator;
} else { } else {
*s = Status::InvalidArgument("Must provide a column_family"); *s = Status::InvalidArgument("Must provide a column_family");

Loading…
Cancel
Save