Add ability to change "priority" of registered options

This commit is contained in:
mrambacher 2021-08-27 13:31:27 -04:00
parent 22ecd7edc1
commit 9cfb5a0feb
3 changed files with 64 additions and 5 deletions

View File

@ -379,15 +379,22 @@ class Configurable {
// @param name The name of this set of options (@see GetOptionsPtr)
// @param opt_ptr Pointer to the options to associate with this name
// @param opt_map Options map that controls how this option is configured.
// @param high_pri If high_pri is true, the registered options will be
// evaluated before low priority options. This parameter is rarely true, but
// may be used to set some options (like Env) on which other options may
// depend, or may be used to specify "TEST" options that alter the default
// settings under specific circumstances.
template <typename T>
void RegisterOptions(
T* opt_ptr,
const std::unordered_map<std::string, OptionTypeInfo>* opt_map) {
RegisterOptions(T::kName(), opt_ptr, opt_map);
const std::unordered_map<std::string, OptionTypeInfo>* opt_map,
bool high_pri = false) {
RegisterOptions(T::kName(), opt_ptr, opt_map, high_pri);
}
void RegisterOptions(
const std::string& name, void* opt_ptr,
const std::unordered_map<std::string, OptionTypeInfo>* opt_map);
const std::unordered_map<std::string, OptionTypeInfo>* opt_map,
bool high_pri = false);
private:
// Contains the collection of options (name, opt_ptr, opt_map) associated with

View File

@ -19,7 +19,8 @@ namespace ROCKSDB_NAMESPACE {
void Configurable::RegisterOptions(
const std::string& name, void* opt_ptr,
const std::unordered_map<std::string, OptionTypeInfo>* type_map) {
const std::unordered_map<std::string, OptionTypeInfo>* type_map,
bool high_pri) {
RegisteredOptions opts;
opts.name = name;
#ifndef ROCKSDB_LITE
@ -28,7 +29,11 @@ void Configurable::RegisterOptions(
(void)type_map;
#endif // ROCKSDB_LITE
opts.opt_ptr = opt_ptr;
options_.emplace_back(opts);
if (high_pri) {
options_.insert(options_.begin(), opts);
} else {
options_.emplace_back(opts);
}
}
//*************************************************************************

View File

@ -810,6 +810,53 @@ TEST_P(ConfigurableParamTest, ConfigureFromPropsTest) {
ASSERT_TRUE(object_->AreEquivalent(config_options_, copy.get(), &mismatch));
}
#ifndef ROCKSDB_LITE
TEST_F(ConfigurableTest, HigherPriorityOptions) {
static OptionTypeInfo info(0, OptionType::kString,
OptionVerificationType::kNormal,
OptionTypeFlags::kNone,
[](const ConfigOptions&, const std::string& name,
const std::string& value, void* addr) {
auto* str = static_cast<std::string*>(addr);
str->append(name).append(value);
return Status::OK();
});
static std::unordered_map<std::string, OptionTypeInfo> a_opt_info = {
{"A", info}};
static std::unordered_map<std::string, OptionTypeInfo> b_opt_info = {
{"B", info}};
static std::unordered_map<std::string, OptionTypeInfo> c_opt_info = {
{"C", info}};
class HighPriConfigurable : public Configurable {
public:
HighPriConfigurable(int which) {
RegisterOptions("A", &value_, &a_opt_info, (which == 0));
RegisterOptions("B", &value_, &b_opt_info, (which == 1));
RegisterOptions("C", &value_, &c_opt_info, (which == 2));
}
std::string value_;
};
std::string opts_str;
std::unique_ptr<HighPriConfigurable> hc(new HighPriConfigurable(0));
ASSERT_OK(hc->ConfigureFromString(config_options_, "A=1; B=2; C=3;"));
ASSERT_EQ(hc->value_, "A1B2C3");
ASSERT_OK(hc->GetOptionString(config_options_, &opts_str));
ASSERT_TRUE(StartsWith(opts_str, "A=A1B2C3;"));
hc.reset(new HighPriConfigurable(1));
ASSERT_OK(hc->ConfigureFromString(config_options_, "A=1; B=2; C=3;"));
ASSERT_EQ(hc->value_, "B2A1C3");
ASSERT_OK(hc->GetOptionString(config_options_, &opts_str));
ASSERT_TRUE(StartsWith(opts_str, "B=B2A1C3;"));
hc.reset(new HighPriConfigurable(2));
ASSERT_OK(hc->ConfigureFromString(config_options_, "A=1; B=2; C=3;"));
ASSERT_EQ(hc->value_, "C3A1B2");
ASSERT_OK(hc->GetOptionString(config_options_, &opts_str));
ASSERT_TRUE(StartsWith(opts_str, "C=C3A1B2;"));
}
#endif // ROCKSDB_LITE
INSTANTIATE_TEST_CASE_P(
ParamTest, ConfigurableParamTest,
testing::Values(