From 2a55463461d7ea43eb590cbcfca8dcb7ed3a5441 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 5 Jan 2018 16:19:44 -0600 Subject: [PATCH] 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 --- src/mon/ConfigMap.cc | 6 +++--- src/mon/ConfigMap.h | 19 ++++++++++++++++--- src/mon/ConfigMonitor.cc | 9 ++++----- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/mon/ConfigMap.cc b/src/mon/ConfigMap.cc index 8b6f5e09070..b1228343bfd 100644 --- a/src/mon/ConfigMap.cc +++ b/src/mon/ConfigMap.cc @@ -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 && diff --git a/src/mon/ConfigMap.h b/src/mon/ConfigMap.h index 86c25841962..7f6de46e198 100644 --- a/src/mon/ConfigMap.h +++ b/src/mon/ConfigMap.h @@ -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 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); diff --git a/src/mon/ConfigMonitor.cc b/src/mon/ConfigMonitor.cc index 4f3b049d6c7..3b9dc704b48 100644 --- a/src/mon/ConfigMonitor.cc +++ b/src/mon/ConfigMonitor.cc @@ -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, §ion_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(); -- 2.39.5