mon/ConfigMap: const * to Option, so we don't have to copy it

These are biggish structs (lots of strings), so it's expensive to make
copies of Option when it is an immutable struct.  However, we need to
handle arbitrary strings that we don't recognize, too.

Signed-off-by: Sage Weil <sage@redhat.com>
This commit is contained in:
Sage Weil 2018-01-05 16:19:44 -06:00
parent cf68ce511f
commit 2a55463461
3 changed files with 23 additions and 11 deletions

View File

@ -37,14 +37,14 @@ void OptionMask::dump(Formatter *f) const
void MaskedOption::dump(Formatter *f) const
{
f->dump_string("name", opt.name);
f->dump_string("name", opt->name);
f->dump_string("value", raw_value);
mask.dump(f);
}
ostream& operator<<(ostream& out, const MaskedOption& o)
{
out << o.opt.name;
out << o.opt->name;
if (o.mask.location_type.size()) {
out << "@" << o.mask.location_type << '=' << o.mask.location_value;
}
@ -114,7 +114,7 @@ void ConfigMap::generate_entity_map(
continue;
}
}
if (prev && prev->opt.name != i.first) {
if (prev && prev->opt->name != i.first) {
prev = nullptr;
}
if (prev &&

View File

@ -51,11 +51,24 @@ struct OptionMask {
};
struct MaskedOption {
string raw_value; ///< raw, unparsed, unvalidated value
Option opt; ///< the option
string raw_value; ///< raw, unparsed, unvalidated value
const Option *opt; ///< the option
OptionMask mask;
unique_ptr<const Option> unknown_opt; ///< if fabricated for an unknown option
MaskedOption(const Option& o) : opt(o) {}
MaskedOption(const Option *o, bool fab=false) : opt(o) {
if (fab) {
unknown_opt.reset(o);
}
}
MaskedOption(MaskedOption&& o) {
raw_value = std::move(o.raw_value);
opt = o.opt;
mask = std::move(o.mask);
unknown_opt = std::move(o.unknown_opt);
}
const MaskedOption& operator=(const MaskedOption& o) = delete;
const MaskedOption& operator=(MaskedOption&& o) = delete;
/// return a precision metric (smaller is more precise)
int get_precision(const CrushWrapper *crush);

View File

@ -151,7 +151,7 @@ bool ConfigMonitor::preprocess_command(MonOpRequestRef op)
f->open_array_section("config");
}
for (auto s : sections) {
for (auto i : s.second->options) {
for (auto& i : s.second->options) {
if (!f) {
tbl << s.first;
tbl << i.second.mask.to_str();
@ -389,11 +389,10 @@ void ConfigMonitor::load_config()
who = key.substr(0, last_slash);
}
Option fake_opt(name, Option::TYPE_STR, Option::LEVEL_DEV);
const Option *opt = g_conf->find_option(name);
if (!opt) {
dout(10) << __func__ << " unrecognized option '" << name << "'" << dendl;
opt = &fake_opt;
opt = new Option(name, Option::TYPE_STR, Option::LEVEL_DEV);
}
string err;
int r = opt->pre_validate(&value, &err);
@ -403,7 +402,7 @@ void ConfigMonitor::load_config()
}
string section_name;
MaskedOption mopt(*opt);
MaskedOption mopt(opt);
mopt.raw_value = value;
if (who.size() &&
!ConfigMap::parse_mask(who, &section_name, &mopt.mask)) {
@ -417,7 +416,7 @@ void ConfigMonitor::load_config()
section = &config_map.by_type[section_name];
}
}
section->options.insert(make_pair(name, mopt));
section->options.insert(make_pair(name, std::move(mopt)));
++num;
}
it->next();