Add OptionTypeInfo::Enum and related methods (#6423)

Summary:
Add methods and constructors for handling enums to the OptionTypeInfo.  This change allows enums to be converted/compared without adding a special "type" to the OptionType.

This change addresses a couple of issues:
- It allows new enumerated types to be added to the options without editing the OptionType base class (and related methods)
- It standardizes the procedure for adding enumerated types to the options, reducing potential mistakes
- It moves the enum maps to the location where they are used, allowing them to be static file members rather than global values
- It reduces the number of types and cases that need to be handled in the various OptionType methods
Pull Request resolved: https://github.com/facebook/rocksdb/pull/6423

Reviewed By: siying

Differential Revision: D21408713

Pulled By: zhichao-cao

fbshipit-source-id: fc492af285d011822578b95d186a0fce25d35626
main
mrambacher 5 years ago committed by Facebook GitHub Bot
parent a96461d169
commit 394f2bbd13
  1. 7
      db/db_wal_test.cc
  2. 42
      options/db_options.cc
  3. 145
      options/options_helper.cc
  4. 25
      options/options_helper.h
  5. 92
      options/options_test.cc
  6. 97
      options/options_type.h
  7. 47
      table/block_based/block_based_table_factory.cc

@ -1422,8 +1422,11 @@ TEST_F(DBWALTest, RecoverFromCorruptedWALWithoutFlush) {
delete iter; delete iter;
return data; return data;
}; };
for (auto& mode : wal_recovery_mode_string_map) { for (auto& mode : {WALRecoveryMode::kTolerateCorruptedTailRecords,
options.wal_recovery_mode = mode.second; WALRecoveryMode::kAbsoluteConsistency,
WALRecoveryMode::kPointInTimeRecovery,
WALRecoveryMode::kSkipAnyCorruptedRecords}) {
options.wal_recovery_mode = mode;
for (auto trunc : {true, false}) { for (auto trunc : {true, false}) {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
for (int j = jstart; j < jend; j++) { for (int j = jstart; j < jend; j++) {

@ -20,6 +20,29 @@
namespace ROCKSDB_NAMESPACE { namespace ROCKSDB_NAMESPACE {
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
static std::unordered_map<std::string, WALRecoveryMode>
wal_recovery_mode_string_map = {
{"kTolerateCorruptedTailRecords",
WALRecoveryMode::kTolerateCorruptedTailRecords},
{"kAbsoluteConsistency", WALRecoveryMode::kAbsoluteConsistency},
{"kPointInTimeRecovery", WALRecoveryMode::kPointInTimeRecovery},
{"kSkipAnyCorruptedRecords",
WALRecoveryMode::kSkipAnyCorruptedRecords}};
static std::unordered_map<std::string, DBOptions::AccessHint>
access_hint_string_map = {{"NONE", DBOptions::AccessHint::NONE},
{"NORMAL", DBOptions::AccessHint::NORMAL},
{"SEQUENTIAL", DBOptions::AccessHint::SEQUENTIAL},
{"WILLNEED", DBOptions::AccessHint::WILLNEED}};
static std::unordered_map<std::string, InfoLogLevel> info_log_level_string_map =
{{"DEBUG_LEVEL", InfoLogLevel::DEBUG_LEVEL},
{"INFO_LEVEL", InfoLogLevel::INFO_LEVEL},
{"WARN_LEVEL", InfoLogLevel::WARN_LEVEL},
{"ERROR_LEVEL", InfoLogLevel::ERROR_LEVEL},
{"FATAL_LEVEL", InfoLogLevel::FATAL_LEVEL},
{"HEADER_LEVEL", InfoLogLevel::HEADER_LEVEL}};
std::unordered_map<std::string, OptionTypeInfo> std::unordered_map<std::string, OptionTypeInfo>
OptionsHelper::db_options_type_info = { OptionsHelper::db_options_type_info = {
/* /*
@ -247,10 +270,9 @@ std::unordered_map<std::string, OptionTypeInfo>
{offsetof(struct DBOptions, allow_concurrent_memtable_write), {offsetof(struct DBOptions, allow_concurrent_memtable_write),
OptionType::kBoolean, OptionVerificationType::kNormal, OptionType::kBoolean, OptionVerificationType::kNormal,
OptionTypeFlags::kNone, 0}}, OptionTypeFlags::kNone, 0}},
{"wal_recovery_mode", {"wal_recovery_mode", OptionTypeInfo::Enum<WALRecoveryMode>(
{offsetof(struct DBOptions, wal_recovery_mode), offsetof(struct DBOptions, wal_recovery_mode),
OptionType::kWALRecoveryMode, OptionVerificationType::kNormal, &wal_recovery_mode_string_map)},
OptionTypeFlags::kNone, 0}},
{"enable_write_thread_adaptive_yield", {"enable_write_thread_adaptive_yield",
{offsetof(struct DBOptions, enable_write_thread_adaptive_yield), {offsetof(struct DBOptions, enable_write_thread_adaptive_yield),
OptionType::kBoolean, OptionVerificationType::kNormal, OptionType::kBoolean, OptionVerificationType::kNormal,
@ -268,12 +290,12 @@ std::unordered_map<std::string, OptionTypeInfo>
OptionType::kUInt64T, OptionVerificationType::kNormal, OptionType::kUInt64T, OptionVerificationType::kNormal,
OptionTypeFlags::kNone, 0}}, OptionTypeFlags::kNone, 0}},
{"access_hint_on_compaction_start", {"access_hint_on_compaction_start",
{offsetof(struct DBOptions, access_hint_on_compaction_start), OptionTypeInfo::Enum<DBOptions::AccessHint>(
OptionType::kAccessHint, OptionVerificationType::kNormal, offsetof(struct DBOptions, access_hint_on_compaction_start),
OptionTypeFlags::kNone, 0}}, &access_hint_string_map)},
{"info_log_level", {"info_log_level", OptionTypeInfo::Enum<InfoLogLevel>(
{offsetof(struct DBOptions, info_log_level), OptionType::kInfoLogLevel, offsetof(struct DBOptions, info_log_level),
OptionVerificationType::kNormal, OptionTypeFlags::kNone, 0}}, &info_log_level_string_map)},
{"dump_malloc_stats", {"dump_malloc_stats",
{offsetof(struct DBOptions, dump_malloc_stats), OptionType::kBoolean, {offsetof(struct DBOptions, dump_malloc_stats), OptionType::kBoolean,
OptionVerificationType::kNormal, OptionTypeFlags::kNone, 0}}, OptionVerificationType::kNormal, OptionTypeFlags::kNone, 0}},

@ -273,29 +273,6 @@ std::vector<CompressionType> GetSupportedCompressions() {
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
namespace { namespace {
template <typename T>
bool ParseEnum(const std::unordered_map<std::string, T>& type_map,
const std::string& type, T* value) {
auto iter = type_map.find(type);
if (iter != type_map.end()) {
*value = iter->second;
return true;
}
return false;
}
template <typename T>
bool SerializeEnum(const std::unordered_map<std::string, T>& type_map,
const T& type, std::string* value) {
for (const auto& pair : type_map) {
if (pair.second == type) {
*value = pair.first;
return true;
}
}
return false;
}
bool SerializeVectorCompressionType(const std::vector<CompressionType>& types, bool SerializeVectorCompressionType(const std::vector<CompressionType>& types,
std::string* value) { std::string* value) {
std::stringstream ss; std::stringstream ss;
@ -535,36 +512,10 @@ bool ParseOptionHelper(char* opt_address, const OptionType& opt_type,
return ParseEnum<ChecksumType>( return ParseEnum<ChecksumType>(
checksum_type_string_map, value, checksum_type_string_map, value,
reinterpret_cast<ChecksumType*>(opt_address)); reinterpret_cast<ChecksumType*>(opt_address));
case OptionType::kBlockBasedTableIndexType:
return ParseEnum<BlockBasedTableOptions::IndexType>(
block_base_table_index_type_string_map, value,
reinterpret_cast<BlockBasedTableOptions::IndexType*>(opt_address));
case OptionType::kBlockBasedTableDataBlockIndexType:
return ParseEnum<BlockBasedTableOptions::DataBlockIndexType>(
block_base_table_data_block_index_type_string_map, value,
reinterpret_cast<BlockBasedTableOptions::DataBlockIndexType*>(
opt_address));
case OptionType::kBlockBasedTableIndexShorteningMode:
return ParseEnum<BlockBasedTableOptions::IndexShorteningMode>(
block_base_table_index_shortening_mode_string_map, value,
reinterpret_cast<BlockBasedTableOptions::IndexShorteningMode*>(
opt_address));
case OptionType::kEncodingType: case OptionType::kEncodingType:
return ParseEnum<EncodingType>( return ParseEnum<EncodingType>(
encoding_type_string_map, value, encoding_type_string_map, value,
reinterpret_cast<EncodingType*>(opt_address)); reinterpret_cast<EncodingType*>(opt_address));
case OptionType::kWALRecoveryMode:
return ParseEnum<WALRecoveryMode>(
wal_recovery_mode_string_map, value,
reinterpret_cast<WALRecoveryMode*>(opt_address));
case OptionType::kAccessHint:
return ParseEnum<DBOptions::AccessHint>(
access_hint_string_map, value,
reinterpret_cast<DBOptions::AccessHint*>(opt_address));
case OptionType::kInfoLogLevel:
return ParseEnum<InfoLogLevel>(
info_log_level_string_map, value,
reinterpret_cast<InfoLogLevel*>(opt_address));
case OptionType::kCompactionOptionsFIFO: { case OptionType::kCompactionOptionsFIFO: {
if (!FIFOCompactionOptionsSpecialCase( if (!FIFOCompactionOptionsSpecialCase(
value, reinterpret_cast<CompactionOptionsFIFO*>(opt_address))) { value, reinterpret_cast<CompactionOptionsFIFO*>(opt_address))) {
@ -729,24 +680,6 @@ bool SerializeSingleOptionHelper(const char* opt_address,
return SerializeEnum<ChecksumType>( return SerializeEnum<ChecksumType>(
checksum_type_string_map, checksum_type_string_map,
*reinterpret_cast<const ChecksumType*>(opt_address), value); *reinterpret_cast<const ChecksumType*>(opt_address), value);
case OptionType::kBlockBasedTableIndexType:
return SerializeEnum<BlockBasedTableOptions::IndexType>(
block_base_table_index_type_string_map,
*reinterpret_cast<const BlockBasedTableOptions::IndexType*>(
opt_address),
value);
case OptionType::kBlockBasedTableDataBlockIndexType:
return SerializeEnum<BlockBasedTableOptions::DataBlockIndexType>(
block_base_table_data_block_index_type_string_map,
*reinterpret_cast<const BlockBasedTableOptions::DataBlockIndexType*>(
opt_address),
value);
case OptionType::kBlockBasedTableIndexShorteningMode:
return SerializeEnum<BlockBasedTableOptions::IndexShorteningMode>(
block_base_table_index_shortening_mode_string_map,
*reinterpret_cast<const BlockBasedTableOptions::IndexShorteningMode*>(
opt_address),
value);
case OptionType::kFlushBlockPolicyFactory: { case OptionType::kFlushBlockPolicyFactory: {
const auto* ptr = const auto* ptr =
reinterpret_cast<const std::shared_ptr<FlushBlockPolicyFactory>*>( reinterpret_cast<const std::shared_ptr<FlushBlockPolicyFactory>*>(
@ -758,18 +691,6 @@ bool SerializeSingleOptionHelper(const char* opt_address,
return SerializeEnum<EncodingType>( return SerializeEnum<EncodingType>(
encoding_type_string_map, encoding_type_string_map,
*reinterpret_cast<const EncodingType*>(opt_address), value); *reinterpret_cast<const EncodingType*>(opt_address), value);
case OptionType::kWALRecoveryMode:
return SerializeEnum<WALRecoveryMode>(
wal_recovery_mode_string_map,
*reinterpret_cast<const WALRecoveryMode*>(opt_address), value);
case OptionType::kAccessHint:
return SerializeEnum<DBOptions::AccessHint>(
access_hint_string_map,
*reinterpret_cast<const DBOptions::AccessHint*>(opt_address), value);
case OptionType::kInfoLogLevel:
return SerializeEnum<InfoLogLevel>(
info_log_level_string_map,
*reinterpret_cast<const InfoLogLevel*>(opt_address), value);
case OptionType::kCompactionOptionsFIFO: case OptionType::kCompactionOptionsFIFO:
return SerializeStruct(opt_address, value, return SerializeStruct(opt_address, value,
fifo_compaction_options_type_info); fifo_compaction_options_type_info);
@ -1231,32 +1152,6 @@ Status GetTableFactoryFromMap(
return Status::OK(); return Status::OK();
} }
std::unordered_map<std::string, BlockBasedTableOptions::IndexType>
OptionsHelper::block_base_table_index_type_string_map = {
{"kBinarySearch", BlockBasedTableOptions::IndexType::kBinarySearch},
{"kHashSearch", BlockBasedTableOptions::IndexType::kHashSearch},
{"kTwoLevelIndexSearch",
BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch},
{"kBinarySearchWithFirstKey",
BlockBasedTableOptions::IndexType::kBinarySearchWithFirstKey}};
std::unordered_map<std::string, BlockBasedTableOptions::DataBlockIndexType>
OptionsHelper::block_base_table_data_block_index_type_string_map = {
{"kDataBlockBinarySearch",
BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch},
{"kDataBlockBinaryAndHash",
BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinaryAndHash}};
std::unordered_map<std::string, BlockBasedTableOptions::IndexShorteningMode>
OptionsHelper::block_base_table_index_shortening_mode_string_map = {
{"kNoShortening",
BlockBasedTableOptions::IndexShorteningMode::kNoShortening},
{"kShortenSeparators",
BlockBasedTableOptions::IndexShorteningMode::kShortenSeparators},
{"kShortenSeparatorsAndSuccessor",
BlockBasedTableOptions::IndexShorteningMode::
kShortenSeparatorsAndSuccessor}};
std::unordered_map<std::string, EncodingType> std::unordered_map<std::string, EncodingType>
OptionsHelper::encoding_type_string_map = {{"kPlain", kPlain}, OptionsHelper::encoding_type_string_map = {{"kPlain", kPlain},
{"kPrefix", kPrefix}}; {"kPrefix", kPrefix}};
@ -1275,31 +1170,6 @@ std::unordered_map<std::string, CompactionPri>
{"kOldestSmallestSeqFirst", kOldestSmallestSeqFirst}, {"kOldestSmallestSeqFirst", kOldestSmallestSeqFirst},
{"kMinOverlappingRatio", kMinOverlappingRatio}}; {"kMinOverlappingRatio", kMinOverlappingRatio}};
std::unordered_map<std::string, WALRecoveryMode>
OptionsHelper::wal_recovery_mode_string_map = {
{"kTolerateCorruptedTailRecords",
WALRecoveryMode::kTolerateCorruptedTailRecords},
{"kAbsoluteConsistency", WALRecoveryMode::kAbsoluteConsistency},
{"kPointInTimeRecovery", WALRecoveryMode::kPointInTimeRecovery},
{"kSkipAnyCorruptedRecords",
WALRecoveryMode::kSkipAnyCorruptedRecords}};
std::unordered_map<std::string, DBOptions::AccessHint>
OptionsHelper::access_hint_string_map = {
{"NONE", DBOptions::AccessHint::NONE},
{"NORMAL", DBOptions::AccessHint::NORMAL},
{"SEQUENTIAL", DBOptions::AccessHint::SEQUENTIAL},
{"WILLNEED", DBOptions::AccessHint::WILLNEED}};
std::unordered_map<std::string, InfoLogLevel>
OptionsHelper::info_log_level_string_map = {
{"DEBUG_LEVEL", InfoLogLevel::DEBUG_LEVEL},
{"INFO_LEVEL", InfoLogLevel::INFO_LEVEL},
{"WARN_LEVEL", InfoLogLevel::WARN_LEVEL},
{"ERROR_LEVEL", InfoLogLevel::ERROR_LEVEL},
{"FATAL_LEVEL", InfoLogLevel::FATAL_LEVEL},
{"HEADER_LEVEL", InfoLogLevel::HEADER_LEVEL}};
LRUCacheOptions OptionsHelper::dummy_lru_cache_options; LRUCacheOptions OptionsHelper::dummy_lru_cache_options;
CompactionOptionsUniversal OptionsHelper::dummy_comp_options_universal; CompactionOptionsUniversal OptionsHelper::dummy_comp_options_universal;
CompactionOptionsFIFO OptionsHelper::dummy_comp_options; CompactionOptionsFIFO OptionsHelper::dummy_comp_options;
@ -1510,21 +1380,6 @@ static bool AreOptionsEqual(OptionType type, const char* this_offset,
return IsOptionEqual<ChecksumType>(this_offset, that_offset); return IsOptionEqual<ChecksumType>(this_offset, that_offset);
case OptionType::kEncodingType: case OptionType::kEncodingType:
return IsOptionEqual<EncodingType>(this_offset, that_offset); return IsOptionEqual<EncodingType>(this_offset, that_offset);
case OptionType::kBlockBasedTableIndexType:
return IsOptionEqual<BlockBasedTableOptions::IndexType>(this_offset,
that_offset);
case OptionType::kBlockBasedTableDataBlockIndexType:
return IsOptionEqual<BlockBasedTableOptions::DataBlockIndexType>(
this_offset, that_offset);
case OptionType::kBlockBasedTableIndexShorteningMode:
return IsOptionEqual<BlockBasedTableOptions::IndexShorteningMode>(
this_offset, that_offset);
case OptionType::kWALRecoveryMode:
return IsOptionEqual<WALRecoveryMode>(this_offset, that_offset);
case OptionType::kAccessHint:
return IsOptionEqual<DBOptions::AccessHint>(this_offset, that_offset);
case OptionType::kInfoLogLevel:
return IsOptionEqual<InfoLogLevel>(this_offset, that_offset);
case OptionType::kCompactionOptionsFIFO: { case OptionType::kCompactionOptionsFIFO: {
CompactionOptionsFIFO lhs = CompactionOptionsFIFO lhs =
*reinterpret_cast<const CompactionOptionsFIFO*>(this_offset); *reinterpret_cast<const CompactionOptionsFIFO*>(this_offset);

@ -107,25 +107,11 @@ struct OptionsHelper {
static std::unordered_map<std::string, OptionTypeInfo> db_options_type_info; static std::unordered_map<std::string, OptionTypeInfo> db_options_type_info;
static std::unordered_map<std::string, OptionTypeInfo> static std::unordered_map<std::string, OptionTypeInfo>
lru_cache_options_type_info; lru_cache_options_type_info;
static std::unordered_map<std::string, BlockBasedTableOptions::IndexType>
block_base_table_index_type_string_map;
static std::unordered_map<std::string,
BlockBasedTableOptions::DataBlockIndexType>
block_base_table_data_block_index_type_string_map;
static std::unordered_map<std::string,
BlockBasedTableOptions::IndexShorteningMode>
block_base_table_index_shortening_mode_string_map;
static std::unordered_map<std::string, EncodingType> encoding_type_string_map; static std::unordered_map<std::string, EncodingType> encoding_type_string_map;
static std::unordered_map<std::string, CompactionStyle> static std::unordered_map<std::string, CompactionStyle>
compaction_style_string_map; compaction_style_string_map;
static std::unordered_map<std::string, CompactionPri> static std::unordered_map<std::string, CompactionPri>
compaction_pri_string_map; compaction_pri_string_map;
static std::unordered_map<std::string, WALRecoveryMode>
wal_recovery_mode_string_map;
static std::unordered_map<std::string, DBOptions::AccessHint>
access_hint_string_map;
static std::unordered_map<std::string, InfoLogLevel>
info_log_level_string_map;
static ColumnFamilyOptions dummy_cf_options; static ColumnFamilyOptions dummy_cf_options;
static CompactionOptionsFIFO dummy_comp_options; static CompactionOptionsFIFO dummy_comp_options;
static LRUCacheOptions dummy_lru_cache_options; static LRUCacheOptions dummy_lru_cache_options;
@ -153,22 +139,11 @@ static auto& lru_cache_options_type_info =
OptionsHelper::lru_cache_options_type_info; OptionsHelper::lru_cache_options_type_info;
static auto& compression_type_string_map = static auto& compression_type_string_map =
OptionsHelper::compression_type_string_map; OptionsHelper::compression_type_string_map;
static auto& block_base_table_index_type_string_map =
OptionsHelper::block_base_table_index_type_string_map;
static auto& block_base_table_data_block_index_type_string_map =
OptionsHelper::block_base_table_data_block_index_type_string_map;
static auto& block_base_table_index_shortening_mode_string_map =
OptionsHelper::block_base_table_index_shortening_mode_string_map;
static auto& encoding_type_string_map = OptionsHelper::encoding_type_string_map; static auto& encoding_type_string_map = OptionsHelper::encoding_type_string_map;
static auto& compaction_style_string_map = static auto& compaction_style_string_map =
OptionsHelper::compaction_style_string_map; OptionsHelper::compaction_style_string_map;
static auto& compaction_pri_string_map = static auto& compaction_pri_string_map =
OptionsHelper::compaction_pri_string_map; OptionsHelper::compaction_pri_string_map;
static auto& wal_recovery_mode_string_map =
OptionsHelper::wal_recovery_mode_string_map;
static auto& access_hint_string_map = OptionsHelper::access_hint_string_map;
static auto& info_log_level_string_map =
OptionsHelper::info_log_level_string_map;
#endif // !ROCKSDB_LITE #endif // !ROCKSDB_LITE
} // namespace ROCKSDB_NAMESPACE } // namespace ROCKSDB_NAMESPACE

@ -3004,6 +3004,17 @@ static void TestAndCompareOption(const ConfigOptions& config_options,
comp_addr, &mismatch)); comp_addr, &mismatch));
} }
static void TestAndCompareOption(const ConfigOptions& config_options,
const OptionTypeInfo& opt_info,
const std::string& opt_name,
const std::string& opt_value, void* base_ptr,
void* comp_ptr) {
char* base_addr = reinterpret_cast<char*>(base_ptr) + opt_info.offset;
ASSERT_OK(
opt_info.ParseOption(config_options, opt_name, opt_value, base_addr));
TestAndCompareOption(config_options, opt_info, opt_name, base_ptr, comp_ptr);
}
template <typename T> template <typename T>
void TestOptInfo(const ConfigOptions& config_options, OptionType opt_type, void TestOptInfo(const ConfigOptions& config_options, OptionType opt_type,
T* base, T* comp) { T* base, T* comp) {
@ -3264,6 +3275,87 @@ TEST_F(OptionTypeInfoTest, TestOptionFlags) {
ASSERT_NE(base, comp); ASSERT_NE(base, comp);
} }
TEST_F(OptionTypeInfoTest, TestCustomEnum) {
enum TestEnum { kA, kB, kC };
std::unordered_map<std::string, TestEnum> enum_map = {
{"A", TestEnum::kA},
{"B", TestEnum::kB},
{"C", TestEnum::kC},
};
OptionTypeInfo opt_info = OptionTypeInfo::Enum<TestEnum>(0, &enum_map);
TestEnum e1, e2;
ConfigOptions config_options;
std::string result, mismatch;
e2 = TestEnum::kA;
ASSERT_OK(opt_info.ParseOption(config_options, "", "B",
reinterpret_cast<char*>(&e1)));
ASSERT_OK(opt_info.SerializeOption(config_options, "",
reinterpret_cast<char*>(&e1), &result));
ASSERT_EQ(e1, TestEnum::kB);
ASSERT_EQ(result, "B");
ASSERT_FALSE(opt_info.MatchesOption(config_options, "Enum",
reinterpret_cast<char*>(&e1),
reinterpret_cast<char*>(&e2), &mismatch));
ASSERT_EQ(mismatch, "Enum");
TestAndCompareOption(config_options, opt_info, "", "C",
reinterpret_cast<char*>(&e1),
reinterpret_cast<char*>(&e2));
ASSERT_EQ(e2, TestEnum::kC);
ASSERT_NOK(opt_info.ParseOption(config_options, "", "D",
reinterpret_cast<char*>(&e1)));
ASSERT_EQ(e1, TestEnum::kC);
}
TEST_F(OptionTypeInfoTest, TestBuiltinEnum) {
ConfigOptions config_options;
for (auto iter : OptionsHelper::compaction_style_string_map) {
CompactionStyle e1, e2;
TestAndCompareOption(config_options,
OptionTypeInfo(0, OptionType::kCompactionStyle),
"CompactionStyle", iter.first, &e1, &e2);
ASSERT_EQ(e1, iter.second);
}
for (auto iter : OptionsHelper::compaction_pri_string_map) {
CompactionPri e1, e2;
TestAndCompareOption(config_options,
OptionTypeInfo(0, OptionType::kCompactionPri),
"CompactionPri", iter.first, &e1, &e2);
ASSERT_EQ(e1, iter.second);
}
for (auto iter : OptionsHelper::compression_type_string_map) {
CompressionType e1, e2;
TestAndCompareOption(config_options,
OptionTypeInfo(0, OptionType::kCompressionType),
"CompressionType", iter.first, &e1, &e2);
ASSERT_EQ(e1, iter.second);
}
for (auto iter : OptionsHelper::compaction_stop_style_string_map) {
CompactionStopStyle e1, e2;
TestAndCompareOption(config_options,
OptionTypeInfo(0, OptionType::kCompactionStopStyle),
"CompactionStopStyle", iter.first, &e1, &e2);
ASSERT_EQ(e1, iter.second);
}
for (auto iter : OptionsHelper::checksum_type_string_map) {
ChecksumType e1, e2;
TestAndCompareOption(config_options,
OptionTypeInfo(0, OptionType::kChecksumType),
"CheckSumType", iter.first, &e1, &e2);
ASSERT_EQ(e1, iter.second);
}
for (auto iter : OptionsHelper::encoding_type_string_map) {
EncodingType e1, e2;
TestAndCompareOption(config_options,
OptionTypeInfo(0, OptionType::kEncodingType),
"EncodingType", iter.first, &e1, &e2);
ASSERT_EQ(e1, iter.second);
}
}
#endif // !ROCKSDB_LITE #endif // !ROCKSDB_LITE
} // namespace ROCKSDB_NAMESPACE } // namespace ROCKSDB_NAMESPACE

@ -41,18 +41,13 @@ enum class OptionType {
kCompactionStopStyle, kCompactionStopStyle,
kMergeOperator, kMergeOperator,
kMemTableRepFactory, kMemTableRepFactory,
kBlockBasedTableIndexType,
kBlockBasedTableDataBlockIndexType,
kBlockBasedTableIndexShorteningMode,
kFilterPolicy, kFilterPolicy,
kFlushBlockPolicyFactory, kFlushBlockPolicyFactory,
kChecksumType, kChecksumType,
kEncodingType, kEncodingType,
kWALRecoveryMode,
kAccessHint,
kInfoLogLevel,
kLRUCacheOptions, kLRUCacheOptions,
kEnv, kEnv,
kEnum,
kUnknown, kUnknown,
}; };
@ -97,6 +92,39 @@ inline OptionTypeFlags operator&(const OptionTypeFlags &a,
static_cast<uint32_t>(b)); static_cast<uint32_t>(b));
} }
// Converts an string into its enumerated value.
// @param type_map Mapping between strings and enum values
// @param type The string representation of the enum
// @param value Returns the enum value represented by the string
// @return true if the string was found in the enum map, false otherwise.
template <typename T>
bool ParseEnum(const std::unordered_map<std::string, T>& type_map,
const std::string& type, T* value) {
auto iter = type_map.find(type);
if (iter != type_map.end()) {
*value = iter->second;
return true;
}
return false;
}
// Converts an enum into its string representation.
// @param type_map Mapping between strings and enum values
// @param type The enum
// @param value Returned as the string representation of the enum
// @return true if the enum was found in the enum map, false otherwise.
template <typename T>
bool SerializeEnum(const std::unordered_map<std::string, T>& type_map,
const T& type, std::string* value) {
for (const auto& pair : type_map) {
if (pair.second == type) {
*value = pair.first;
return true;
}
}
return false;
}
// Function for converting a option string value into its underlying // Function for converting a option string value into its underlying
// representation in "addr" // representation in "addr"
// On success, Status::OK is returned and addr is set to the parsed form // On success, Status::OK is returned and addr is set to the parsed form
@ -198,6 +226,63 @@ class OptionTypeInfo {
verification(_verification), verification(_verification),
flags(_flags) {} flags(_flags) {}
// Creates an OptionTypeInfo for an enum type. Enums use an additional
// map to convert the enums to/from their string representation.
// To create an OptionTypeInfo that is an Enum, one should:
// - Create a static map of string values to the corresponding enum value
// - Call this method passing the static map in as a parameter.
// Note that it is not necessary to add a new OptionType or make any
// other changes -- the returned object handles parsing, serialiation, and
// comparisons.
//
// @param _offset The offset in the option object for this enum
// @param map The string to enum mapping for this enum
template <typename T>
static OptionTypeInfo Enum(
int _offset, const std::unordered_map<std::string, T>* const map) {
return OptionTypeInfo(
_offset, OptionType::kEnum, OptionVerificationType::kNormal,
OptionTypeFlags::kNone, 0,
// Uses the map argument to convert the input string into
// its corresponding enum value. If value is found in the map,
// addr is updated to the corresponding map entry.
// @return OK if the value is found in the map
// @return InvalidArgument if the value is not found in the map
[map](const ConfigOptions&, const std::string& name,
const std::string& value, char* addr) {
if (map == nullptr) {
return Status::NotSupported("No enum mapping ", name);
} else if (ParseEnum<T>(*map, value, reinterpret_cast<T*>(addr))) {
return Status::OK();
} else {
return Status::InvalidArgument("No mapping for enum ", name);
}
},
// Uses the map argument to convert the input enum into
// its corresponding string value. If enum value is found in the map,
// value is updated to the corresponding string value in the map.
// @return OK if the enum is found in the map
// @return InvalidArgument if the enum is not found in the map
[map](const ConfigOptions&, const std::string& name, const char* addr,
std::string* value) {
if (map == nullptr) {
return Status::NotSupported("No enum mapping ", name);
} else if (SerializeEnum<T>(*map, (*reinterpret_cast<const T*>(addr)),
value)) {
return Status::OK();
} else {
return Status::InvalidArgument("No mapping for enum ", name);
}
},
// Casts addr1 and addr2 to the enum type and returns true if
// they are equal, false otherwise.
[](const ConfigOptions&, const std::string&, const char* addr1,
const char* addr2, std::string*) {
return (*reinterpret_cast<const T*>(addr1) ==
*reinterpret_cast<const T*>(addr2));
});
} // End OptionTypeInfo::Enum
bool IsEnabled(OptionTypeFlags otf) const { return (flags & otf) == otf; } bool IsEnabled(OptionTypeFlags otf) const { return (flags & otf) == otf; }
bool IsMutable() const { return IsEnabled(OptionTypeFlags::kMutable); } bool IsMutable() const { return IsEnabled(OptionTypeFlags::kMutable); }

@ -160,6 +160,34 @@ size_t TailPrefetchStats::GetSuggestedPrefetchSize() {
} }
#ifndef ROCKSDB_LITE #ifndef ROCKSDB_LITE
static std::unordered_map<std::string, BlockBasedTableOptions::IndexType>
block_base_table_index_type_string_map = {
{"kBinarySearch", BlockBasedTableOptions::IndexType::kBinarySearch},
{"kHashSearch", BlockBasedTableOptions::IndexType::kHashSearch},
{"kTwoLevelIndexSearch",
BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch},
{"kBinarySearchWithFirstKey",
BlockBasedTableOptions::IndexType::kBinarySearchWithFirstKey}};
static std::unordered_map<std::string,
BlockBasedTableOptions::DataBlockIndexType>
block_base_table_data_block_index_type_string_map = {
{"kDataBlockBinarySearch",
BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch},
{"kDataBlockBinaryAndHash",
BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinaryAndHash}};
static std::unordered_map<std::string,
BlockBasedTableOptions::IndexShorteningMode>
block_base_table_index_shortening_mode_string_map = {
{"kNoShortening",
BlockBasedTableOptions::IndexShorteningMode::kNoShortening},
{"kShortenSeparators",
BlockBasedTableOptions::IndexShorteningMode::kShortenSeparators},
{"kShortenSeparatorsAndSuccessor",
BlockBasedTableOptions::IndexShorteningMode::
kShortenSeparatorsAndSuccessor}};
static std::unordered_map<std::string, OptionTypeInfo> static std::unordered_map<std::string, OptionTypeInfo>
block_based_table_type_info = { block_based_table_type_info = {
/* currently not supported /* currently not supported
@ -185,22 +213,21 @@ static std::unordered_map<std::string, OptionTypeInfo>
pin_l0_filter_and_index_blocks_in_cache), pin_l0_filter_and_index_blocks_in_cache),
OptionType::kBoolean, OptionVerificationType::kNormal, OptionType::kBoolean, OptionVerificationType::kNormal,
OptionTypeFlags::kNone, 0}}, OptionTypeFlags::kNone, 0}},
{"index_type", {"index_type", OptionTypeInfo::Enum<BlockBasedTableOptions::IndexType>(
{offsetof(struct BlockBasedTableOptions, index_type), offsetof(struct BlockBasedTableOptions, index_type),
OptionType::kBlockBasedTableIndexType, &block_base_table_index_type_string_map)},
OptionVerificationType::kNormal, OptionTypeFlags::kNone, 0}},
{"hash_index_allow_collision", {"hash_index_allow_collision",
{offsetof(struct BlockBasedTableOptions, hash_index_allow_collision), {offsetof(struct BlockBasedTableOptions, hash_index_allow_collision),
OptionType::kBoolean, OptionVerificationType::kNormal, OptionType::kBoolean, OptionVerificationType::kNormal,
OptionTypeFlags::kNone, 0}}, OptionTypeFlags::kNone, 0}},
{"data_block_index_type", {"data_block_index_type",
{offsetof(struct BlockBasedTableOptions, data_block_index_type), OptionTypeInfo::Enum<BlockBasedTableOptions::DataBlockIndexType>(
OptionType::kBlockBasedTableDataBlockIndexType, offsetof(struct BlockBasedTableOptions, data_block_index_type),
OptionVerificationType::kNormal, OptionTypeFlags::kNone, 0}}, &block_base_table_data_block_index_type_string_map)},
{"index_shortening", {"index_shortening",
{offsetof(struct BlockBasedTableOptions, index_shortening), OptionTypeInfo::Enum<BlockBasedTableOptions::IndexShorteningMode>(
OptionType::kBlockBasedTableIndexShorteningMode, offsetof(struct BlockBasedTableOptions, index_shortening),
OptionVerificationType::kNormal, OptionTypeFlags::kNone, 0}}, &block_base_table_index_shortening_mode_string_map)},
{"data_block_hash_table_util_ratio", {"data_block_hash_table_util_ratio",
{offsetof(struct BlockBasedTableOptions, {offsetof(struct BlockBasedTableOptions,
data_block_hash_table_util_ratio), data_block_hash_table_util_ratio),

Loading…
Cancel
Save