From 6ed31d08d7cbbcbfdf77f6112c2523e41560ea83 Mon Sep 17 00:00:00 2001 From: "Adam C. Emerson" Date: Thu, 28 Mar 2019 21:08:50 -0400 Subject: [PATCH] crush: Update to work without using namespace Signed-off-by: Adam C. Emerson --- src/crush/CrushCompiler.cc | 13 +- src/crush/CrushCompiler.h | 42 ++--- src/crush/CrushLocation.cc | 8 +- src/crush/CrushTester.cc | 41 ++--- src/crush/CrushTester.h | 70 ++++---- src/crush/CrushTreeDumper.h | 38 ++--- src/crush/CrushWrapper.cc | 23 ++- src/crush/CrushWrapper.h | 310 +++++++++++++++++++----------------- src/crush/grammar.h | 85 +++++----- 9 files changed, 341 insertions(+), 289 deletions(-) diff --git a/src/crush/CrushCompiler.cc b/src/crush/CrushCompiler.cc index a512489bc57..811852e25b3 100644 --- a/src/crush/CrushCompiler.cc +++ b/src/crush/CrushCompiler.cc @@ -1,4 +1,3 @@ - #include "CrushCompiler.h" #if defined(_AIX) @@ -12,6 +11,14 @@ #include "common/errno.h" #include +using std::cout; +using std::istream; +using std::map; +using std::ostream; +using std::set; +using std::string; +using std::vector; + // ------------- static void print_type_name(ostream& out, int t, CrushWrapper &crush) @@ -1248,8 +1255,8 @@ int CrushCompiler::compile(istream& in, const char *infn) crush_grammar crushg; const char *start = big.c_str(); //tree_parse_info info = ast_parse(start, crushg, space_p); - tree_parse_info<> info = ast_parse(start, crushg, space_p); - + auto info = ast_parse(start, crushg, boost::spirit::space_p); + // parse error? if (!info.full) { int cpos = info.stop - start; diff --git a/src/crush/CrushCompiler.h b/src/crush/CrushCompiler.h index f035085e70e..26dac58cb33 100644 --- a/src/crush/CrushCompiler.h +++ b/src/crush/CrushCompiler.h @@ -12,7 +12,7 @@ class CrushCompiler { CrushWrapper& crush; - ostream& err; + std::ostream& err; int verbose; bool unsafe_tunables; @@ -23,39 +23,39 @@ class CrushCompiler { }; int decompile_weight_set_weights(crush_weight_set weight_set, - ostream &out); + std::ostream &out); int decompile_weight_set(crush_weight_set *weight_set, __u32 size, - ostream &out); + std::ostream &out); int decompile_choose_arg(crush_choose_arg *arg, int bucket_id, - ostream &out); + std::ostream &out); int decompile_ids(int *ids, __u32 size, - ostream &out); + std::ostream &out); int decompile_choose_arg_map(crush_choose_arg_map arg_map, - ostream &out); + std::ostream &out); int decompile_choose_args(const std::pair &i, - ostream &out); - int decompile_bucket_impl(int i, ostream &out); + std::ostream &out); + int decompile_bucket_impl(int i, std::ostream &out); int decompile_bucket(int cur, std::map& dcb_states, - ostream &out); + std::ostream &out); // compile typedef char const* iterator_t; - typedef tree_match parse_tree_match_t; + typedef boost::spirit::tree_match parse_tree_match_t; typedef parse_tree_match_t::tree_iterator iter_t; typedef parse_tree_match_t::node_t node_t; - map item_id; - map id_item; - map item_weight; - map type_id; - map rule_id; - std::map > class_bucket; // bucket id -> class id -> shadow bucket id + std::map item_id; + std::map id_item; + std::map item_weight; + std::map type_id; + std::map rule_id; + std::map > class_bucket; // bucket id -> class id -> shadow bucket id - string string_node(node_t &node); + std::string string_node(node_t &node); int int_node(node_t &node); float float_node(node_t &node); @@ -72,11 +72,11 @@ class CrushCompiler { void find_used_bucket_ids(iter_t const& i); int parse_crush(iter_t const& i); void dump(iter_t const& i, int ind=1); - string consolidate_whitespace(string in); + std::string consolidate_whitespace(std::string in); int adjust_bucket_item_place(iter_t const &i); public: - CrushCompiler(CrushWrapper& c, ostream& eo, int verbosity=0) + CrushCompiler(CrushWrapper& c, std::ostream& eo, int verbosity=0) : crush(c), err(eo), verbose(verbosity), unsafe_tunables(false) {} ~CrushCompiler() {} @@ -85,8 +85,8 @@ public: unsafe_tunables = true; } - int decompile(ostream& out); - int compile(istream& in, const char *infn=0); + int decompile(std::ostream& out); + int compile(std::istream& in, const char *infn=0); }; #endif diff --git a/src/crush/CrushLocation.cc b/src/crush/CrushLocation.cc index a73a739c785..39f89f323e2 100644 --- a/src/crush/CrushLocation.cc +++ b/src/crush/CrushLocation.cc @@ -67,13 +67,13 @@ int CrushLocation::update_from_hook() return ret; } - bufferlist bl; + ceph::buffer::list bl; ret = bl.read_fd(hook.get_stdout(), 100 * 1024); if (ret < 0) { lderr(cct) << "error: failed read stdout from " << cct->_conf->crush_location_hook << ": " << cpp_strerror(-ret) << dendl; - bufferlist err; + ceph::buffer::list err; err.read_fd(hook.get_stderr(), 100 * 1024); lderr(cct) << "stderr:\n"; err.hexdump(*_dout); @@ -117,8 +117,8 @@ int CrushLocation::init_on_startup() } std::lock_guard l(lock); loc.clear(); - loc.insert(make_pair("host", hostname)); - loc.insert(make_pair("root", "default")); + loc.insert(std::make_pair("host", hostname)); + loc.insert(std::make_pair("root", "default")); lgeneric_dout(cct, 10) << "crush_location is (default) " << loc << dendl; return 0; } diff --git a/src/crush/CrushTester.cc b/src/crush/CrushTester.cc index 86f91ef3d22..9e59096f32a 100644 --- a/src/crush/CrushTester.cc +++ b/src/crush/CrushTester.cc @@ -1,26 +1,31 @@ // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab -#include "include/stringify.h" -#include "CrushTester.h" -#include "CrushTreeDumper.h" -#include "include/ceph_features.h" - #include -#include +#include +#include + #include -// to workaround https://svn.boost.org/trac/boost/ticket/9501 -#ifdef _LIBCPP_VERSION -#include -#if BOOST_VERSION < 105600 -#define ICL_USE_BOOST_MOVE_IMPLEMENTATION -#endif -#endif #include #include + #include "common/SubProcess.h" #include "common/fork_function.h" +#include "include/stringify.h" +#include "CrushTester.h" +#include "CrushTreeDumper.h" +#include "include/ceph_features.h" + + +using std::cerr; +using std::cout; +using std::map; +using std::ostringstream; +using std::string; +using std::stringstream; +using std::vector; + void CrushTester::set_device_weight(int dev, float f) { int w = (int)(f * 0x10000); @@ -77,7 +82,7 @@ int CrushTester::get_maximum_affected_by_rule(int ruleno) * get the smallest number of buckets available of any type as this is our upper bound on * the number of replicas we can place */ - int max_affected = max( crush.get_max_buckets(), crush.get_max_devices() ); + int max_affected = std::max( crush.get_max_buckets(), crush.get_max_devices() ); for(std::vector::iterator it = affected_types.begin(); it != affected_types.end(); ++it){ if (max_devices_of_type[*it] > 0 && max_devices_of_type[*it] < max_affected ) @@ -264,7 +269,7 @@ int CrushTester::random_placement(int ruleno, vector& out, int maxout, vect return -EINVAL; // determine the real maximum number of devices to return - int devices_requested = min(maxout, get_maximum_affected_by_rule(ruleno)); + int devices_requested = std::min(maxout, get_maximum_affected_by_rule(ruleno)); bool accept_placement = false; vector trial_placement(devices_requested); @@ -498,7 +503,7 @@ int CrushTester::test() } if (output_utilization_all) - err << "devices weights (hex): " << hex << weight << dec << std::endl; + cerr << "devices weights (hex): " << std::hex << weight << std::dec << std::endl; // make adjustments adjust_weights(weight); @@ -560,7 +565,7 @@ int CrushTester::test() continue; // compute the expected number of objects stored per device in the absence of weighting - float expected_objects = min(nr, get_maximum_affected_by_rule(r)) * num_objects; + float expected_objects = std::min(nr, get_maximum_affected_by_rule(r)) * num_objects; // compute each device's proportional weight vector proportional_weights( per.size() ); @@ -595,7 +600,7 @@ int CrushTester::test() objects_per_batch = (batch_max - batch_min + 1); } - float batch_expected_objects = min(nr, get_maximum_affected_by_rule(r)) * objects_per_batch; + float batch_expected_objects = std::min(nr, get_maximum_affected_by_rule(r)) * objects_per_batch; vector batch_num_objects_expected( per.size() ); for (unsigned i = 0; i < per.size() ; i++) diff --git a/src/crush/CrushTester.h b/src/crush/CrushTester.h index c4257b63d6b..1bbc01a70c8 100644 --- a/src/crush/CrushTester.h +++ b/src/crush/CrushTester.h @@ -10,9 +10,9 @@ class CrushTester { CrushWrapper& crush; - ostream& err; + std::ostream& err; - map device_weight; + std::map device_weight; int min_rule, max_rule; int ruleset; int min_x, max_x; @@ -35,13 +35,13 @@ class CrushTester { bool output_data_file; bool output_csv; - string output_data_file_name; + std::string output_data_file_name; /* * mark a ratio of devices down, can be used to simulate placement distributions * under degrated cluster conditions */ - void adjust_weights(vector<__u32>& weight); + void adjust_weights(std::vector<__u32>& weight); /* * Get the maximum number of devices that could be selected to satisfy ruleno. @@ -60,56 +60,56 @@ class CrushTester { * * which can help make post-processing easier */ - map get_collapsed_mapping(); + std::map get_collapsed_mapping(); /* * Essentially a re-implementation of CRUSH. Given a vector of devices * check that the vector represents a valid placement for a given ruleno. */ - bool check_valid_placement(int ruleno, vector in, const vector<__u32>& weight); + bool check_valid_placement(int ruleno, std::vector in, const std::vector<__u32>& weight); /* * Generate a random selection of devices which satisfies ruleno. Essentially a * monte-carlo simulator for CRUSH placements which can be used to compare the * statistical distribution of the CRUSH algorithm to a random number generator */ - int random_placement(int ruleno, vector& out, int maxout, vector<__u32>& weight); + int random_placement(int ruleno, std::vector& out, int maxout, std::vector<__u32>& weight); // scaffolding to store data for off-line processing struct tester_data_set { - vector device_utilization; - vector device_utilization_all; - vector placement_information; - vector batch_device_utilization_all; - vector batch_device_expected_utilization_all; - map proportional_weights; - map proportional_weights_all; - map absolute_weights; + std::vector device_utilization; + std::vector device_utilization_all; + std::vector placement_information; + std::vector batch_device_utilization_all; + std::vector batch_device_expected_utilization_all; + std::map proportional_weights; + std::map proportional_weights_all; + std::map absolute_weights; } ; - void write_to_csv(ofstream& csv_file, vector& payload) + void write_to_csv(std::ofstream& csv_file, std::vector& payload) { if (csv_file.good()) - for (vector::iterator it = payload.begin(); it != payload.end(); ++it) + for (std::vector::iterator it = payload.begin(); it != payload.end(); ++it) csv_file << (*it); } - void write_to_csv(ofstream& csv_file, map& payload) + void write_to_csv(std::ofstream& csv_file, std::map& payload) { if (csv_file.good()) - for (map::iterator it = payload.begin(); it != payload.end(); ++it) + for (std::map::iterator it = payload.begin(); it != payload.end(); ++it) csv_file << (*it).first << ',' << (*it).second << std::endl; } - void write_data_set_to_csv(string user_tag, tester_data_set& tester_data) + void write_data_set_to_csv(std::string user_tag, tester_data_set& tester_data) { - ofstream device_utilization_file ((user_tag + (string)"-device_utilization.csv").c_str()); - ofstream device_utilization_all_file ((user_tag + (string)"-device_utilization_all.csv").c_str()); - ofstream placement_information_file ((user_tag + (string)"-placement_information.csv").c_str()); - ofstream proportional_weights_file ((user_tag + (string)"-proportional_weights.csv").c_str()); - ofstream proportional_weights_all_file ((user_tag + (string)"-proportional_weights_all.csv").c_str()); - ofstream absolute_weights_file ((user_tag + (string)"-absolute_weights.csv").c_str()); + std::ofstream device_utilization_file((user_tag + (std::string)"-device_utilization.csv").c_str()); + std::ofstream device_utilization_all_file((user_tag + (std::string)"-device_utilization_all.csv").c_str()); + std::ofstream placement_information_file((user_tag + (std::string)"-placement_information.csv").c_str()); + std::ofstream proportional_weights_file((user_tag + (std::string)"-proportional_weights.csv").c_str()); + std::ofstream proportional_weights_all_file((user_tag + (std::string)"-proportional_weights_all.csv").c_str()); + std::ofstream absolute_weights_file((user_tag + (std::string)"-absolute_weights.csv").c_str()); // write the headers device_utilization_file << "Device ID, Number of Objects Stored, Number of Objects Expected" << std::endl; @@ -138,8 +138,8 @@ class CrushTester { absolute_weights_file.close(); if (num_batches > 1) { - ofstream batch_device_utilization_all_file ((user_tag + (string)"-batch_device_utilization_all.csv").c_str()); - ofstream batch_device_expected_utilization_all_file ((user_tag + (string)"-batch_device_expected_utilization_all.csv").c_str()); + std::ofstream batch_device_utilization_all_file ((user_tag + (std::string)"-batch_device_utilization_all.csv").c_str()); + std::ofstream batch_device_expected_utilization_all_file ((user_tag + (std::string)"-batch_device_expected_utilization_all.csv").c_str()); batch_device_utilization_all_file << "Batch Round"; for (unsigned i = 0; i < tester_data.device_utilization.size(); i++) { @@ -160,13 +160,13 @@ class CrushTester { } } - void write_integer_indexed_vector_data_string(vector &dst, int index, vector vector_data); - void write_integer_indexed_vector_data_string(vector &dst, int index, vector vector_data); - void write_integer_indexed_scalar_data_string(vector &dst, int index, int scalar_data); - void write_integer_indexed_scalar_data_string(vector &dst, int index, float scalar_data); + void write_integer_indexed_vector_data_string(std::vector &dst, int index, std::vector vector_data); + void write_integer_indexed_vector_data_string(std::vector &dst, int index, std::vector vector_data); + void write_integer_indexed_scalar_data_string(std::vector &dst, int index, int scalar_data); + void write_integer_indexed_scalar_data_string(std::vector &dst, int index, float scalar_data); public: - CrushTester(CrushWrapper& c, ostream& eo) + CrushTester(CrushWrapper& c, std::ostream& eo) : crush(c), err(eo), min_rule(-1), max_rule(-1), ruleset(-1), @@ -189,10 +189,10 @@ public: { } - void set_output_data_file_name(string name) { + void set_output_data_file_name(std::string name) { output_data_file_name = name; } - string get_output_data_file_name() const { + std::string get_output_data_file_name() const { return output_data_file_name; } diff --git a/src/crush/CrushTreeDumper.h b/src/crush/CrushTreeDumper.h index 5c0430c2ed8..a10c0f2c13c 100644 --- a/src/crush/CrushTreeDumper.h +++ b/src/crush/CrushTreeDumper.h @@ -54,7 +54,7 @@ namespace CrushTreeDumper { int parent; int depth; float weight; - list children; + std::list children; Item() : id(0), parent(0), depth(0), weight(0) {} Item(int i, int p, int d, float w) : id(i), parent(p), depth(d), weight(w) {} @@ -63,7 +63,7 @@ namespace CrushTreeDumper { }; template - class Dumper : public list { + class Dumper : public std::list { public: explicit Dumper(const CrushWrapper *crush_, const name_map_t& weight_set_names_) @@ -129,11 +129,11 @@ namespace CrushTreeDumper { if (qi.is_bucket()) { // queue bucket contents, sorted by (class, name) int s = crush->get_bucket_size(qi.id); - map> sorted; + std::map> sorted; for (int k = s - 1; k >= 0; k--) { int id = crush->get_bucket_item(qi.id, k); if (should_dump(id)) { - string sort_by; + std::string sort_by; if (id >= 0) { const char *c = crush->get_item_class(id); sort_by = c ? c : ""; @@ -145,7 +145,7 @@ namespace CrushTreeDumper { sort_by = "_"; sort_by += crush->get_item_name(id); } - sorted[sort_by] = make_pair( + sorted[sort_by] = std::make_pair( id, crush->get_bucket_item_weightf(qi.id, k)); } } @@ -167,7 +167,7 @@ namespace CrushTreeDumper { bool is_touched(int id) const { return touched.count(id) > 0; } - void set_root(const string& bucket) { + void set_root(const std::string& bucket) { roots.clear(); if (crush->name_exists(bucket)) { int i = crush->get_item_id(bucket); @@ -183,14 +183,14 @@ namespace CrushTreeDumper { const name_map_t &weight_set_names; private: - set touched; - set roots; - set::iterator root; + std::set touched; + std::set roots; + std::set::iterator root; }; inline void dump_item_fields(const CrushWrapper *crush, const name_map_t& weight_set_names, - const Item &qi, Formatter *f) { + const Item &qi, ceph::Formatter *f) { f->dump_int("id", qi.id); const char *c = crush->get_item_class(qi.id); if (c) @@ -222,7 +222,7 @@ namespace CrushTreeDumper { bpos < (int)cmap.args[bidx].weight_set[0].size && b->items[bpos] != qi.id; ++bpos) ; - string name; + std::string name; if (p.first == CrushWrapper::DEFAULT_CHOOSE_ARGS) { name = "(compat)"; } else { @@ -246,12 +246,12 @@ namespace CrushTreeDumper { } inline void dump_bucket_children(const CrushWrapper *crush, - const Item &qi, Formatter *f) { + const Item &qi, ceph::Formatter *f) { if (!qi.is_bucket()) return; f->open_array_section("children"); - for (list::const_iterator i = qi.children.begin(); + for (std::list::const_iterator i = qi.children.begin(); i != qi.children.end(); ++i) { f->dump_int("child", *i); @@ -259,29 +259,29 @@ namespace CrushTreeDumper { f->close_section(); } - class FormattingDumper : public Dumper { + class FormattingDumper : public Dumper { public: explicit FormattingDumper(const CrushWrapper *crush, const name_map_t& weight_set_names) - : Dumper(crush, weight_set_names) {} + : Dumper(crush, weight_set_names) {} explicit FormattingDumper(const CrushWrapper *crush, const name_map_t& weight_set_names, bool show_shadow) - : Dumper(crush, weight_set_names, show_shadow) {} + : Dumper(crush, weight_set_names, show_shadow) {} protected: - void dump_item(const Item &qi, Formatter *f) override { + void dump_item(const Item &qi, ceph::Formatter *f) override { f->open_object_section("item"); dump_item_fields(qi, f); dump_bucket_children(qi, f); f->close_section(); } - virtual void dump_item_fields(const Item &qi, Formatter *f) { + virtual void dump_item_fields(const Item &qi, ceph::Formatter *f) { CrushTreeDumper::dump_item_fields(crush, weight_set_names, qi, f); } - virtual void dump_bucket_children(const Item &qi, Formatter *f) { + virtual void dump_bucket_children(const Item &qi, ceph::Formatter *f) { CrushTreeDumper::dump_bucket_children(crush, qi, f); } }; diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index ec1716decd8..a4c699bf003 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -13,6 +13,23 @@ #define dout_subsys ceph_subsys_crush +using std::cout; +using std::list; +using std::map; +using std::make_pair; +using std::ostream; +using std::ostringstream; +using std::pair; +using std::set; +using std::string; +using std::vector; + +using ceph::bufferlist; +using ceph::decode; +using ceph::decode_nohead; +using ceph::encode; +using ceph::Formatter; + bool CrushWrapper::has_legacy_rule_ids() const { for (unsigned i=0; imax_rules; i++) { @@ -1787,7 +1804,7 @@ int32_t CrushWrapper::_alloc_class_id() const { return class_id; } // wrapped, pick a random start and do exhaustive search - uint32_t upperlimit = numeric_limits::max(); + uint32_t upperlimit = std::numeric_limits::max(); upperlimit++; class_id = rand() % upperlimit; const auto start = class_id; @@ -3060,7 +3077,7 @@ void CrushWrapper::decode(bufferlist::const_iterator& blp) __u32 magic; decode(magic, blp); if (magic != CRUSH_MAGIC) - throw buffer::malformed_input("bad magic number"); + throw ceph::buffer::malformed_input("bad magic number"); decode(crush->max_buckets, blp); decode(crush->max_rules, blp); @@ -3212,7 +3229,7 @@ void CrushWrapper::decode_crush_bucket(crush_bucket** bptr, bufferlist::const_it { char str[128]; snprintf(str, sizeof(str), "unsupported bucket algorithm: %d", alg); - throw buffer::malformed_input(str); + throw ceph::buffer::malformed_input(str); } } crush_bucket *bucket = reinterpret_cast(calloc(1, size)); diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index 5abd0f42d63..ce3ddf3b3ad 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -32,19 +32,19 @@ namespace ceph { } namespace CrushTreeDumper { - typedef mempool::osdmap::map name_map_t; +typedef mempool::osdmap::map name_map_t; } WRITE_RAW_ENCODER(crush_rule_mask) // it's all u8's -inline void encode(const crush_rule_step &s, bufferlist &bl) +inline void encode(const crush_rule_step &s, ceph::buffer::list &bl) { using ceph::encode; encode(s.op, bl); encode(s.arg1, bl); encode(s.arg2, bl); } -inline void decode(crush_rule_step &s, bufferlist::const_iterator &p) +inline void decode(crush_rule_step &s, ceph::buffer::list::const_iterator &p) { using ceph::decode; decode(s.op, p); @@ -61,14 +61,14 @@ public: DEFAULT_CHOOSE_ARGS = -1 }; - std::map type_map; /* bucket/device type names */ - std::map name_map; /* bucket/device names */ - std::map rule_name_map; + std::map type_map; /* bucket/device type names */ + std::map name_map; /* bucket/device names */ + std::map rule_name_map; std::map class_map; /* item id -> class id */ - std::map class_name; /* class id -> class name */ - std::map class_rname; /* class name -> class id */ - std::map > class_bucket; /* bucket[id][class] == id */ + std::map class_name; /* class id -> class name */ + std::map class_rname; /* class name -> class id */ + std::map > class_bucket; /* bucket[id][class] == id */ std::map choose_args; private: @@ -78,7 +78,7 @@ private: /* reverse maps */ mutable bool have_rmaps = false; - mutable std::map type_rmap, name_rmap, rule_name_rmap; + mutable std::map type_rmap, name_rmap, rule_name_rmap; void build_rmaps() const { if (have_rmaps) return; build_rmap(type_map, type_rmap); @@ -86,9 +86,9 @@ private: build_rmap(rule_name_map, rule_name_rmap); have_rmaps = true; } - void build_rmap(const map &f, std::map &r) const { + void build_rmap(const std::map &f, std::map &r) const { r.clear(); - for (std::map::const_iterator p = f.begin(); p != f.end(); ++p) + for (auto p = f.begin(); p != f.end(); ++p) r[p->second] = p->first; } @@ -360,7 +360,7 @@ public: bool is_v3_rule(unsigned ruleid) const; bool is_v5_rule(unsigned ruleid) const; - string get_min_required_version() const { + std::string get_min_required_version() const { if (has_v5_rules() || has_nondefault_tunables5()) return "jewel"; else if (has_v4_buckets()) @@ -398,45 +398,45 @@ public: return 0; return type_map.rbegin()->first; } - int get_type_id(const string& name) const { + int get_type_id(const std::string& name) const { build_rmaps(); if (type_rmap.count(name)) return type_rmap[name]; return -1; } const char *get_type_name(int t) const { - std::map::const_iterator p = type_map.find(t); + auto p = type_map.find(t); if (p != type_map.end()) return p->second.c_str(); return 0; } - void set_type_name(int i, const string& name) { + void set_type_name(int i, const std::string& name) { type_map[i] = name; if (have_rmaps) type_rmap[name] = i; } // item/bucket names - bool name_exists(const string& name) const { + bool name_exists(const std::string& name) const { build_rmaps(); return name_rmap.count(name); } bool item_exists(int i) const { return name_map.count(i); } - int get_item_id(const string& name) const { + int get_item_id(const std::string& name) const { build_rmaps(); if (name_rmap.count(name)) return name_rmap[name]; return 0; /* hrm */ } const char *get_item_name(int t) const { - std::map::const_iterator p = name_map.find(t); + std::map::const_iterator p = name_map.find(t); if (p != name_map.end()) return p->second.c_str(); return 0; } - int set_item_name(int i, const string& name) { + int set_item_name(int i, const std::string& name) { if (!is_valid_crush_name(name)) return -EINVAL; name_map[i] = name; @@ -445,8 +445,8 @@ public: return 0; } void swap_names(int a, int b) { - string an = name_map[a]; - string bn = name_map[b]; + std::string an = name_map[a]; + std::string bn = name_map[b]; name_map[a] = bn; name_map[b] = an; if (have_rmaps) { @@ -456,7 +456,7 @@ public: } int split_id_class(int i, int *idout, int *classout) const; - bool class_exists(const string& name) const { + bool class_exists(const std::string& name) const { return class_rname.count(name); } const char *get_class_name(int i) const { @@ -465,14 +465,14 @@ public: return p->second.c_str(); return 0; } - int get_class_id(const string& name) const { + int get_class_id(const std::string& name) const { auto p = class_rname.find(name); if (p != class_rname.end()) return p->second; else return -EINVAL; } - int remove_class_name(const string& name) { + int remove_class_name(const std::string& name) { auto p = class_rname.find(name); if (p == class_rname.end()) return -ENOENT; @@ -487,7 +487,7 @@ public: int32_t _alloc_class_id() const; - int get_or_create_class_id(const string& name) { + int get_or_create_class_id(const std::string& name) { int c = get_class_id(name); if (c < 0) { int i = _alloc_class_id(); @@ -505,7 +505,7 @@ public: return 0; return get_class_name(p->second); } - int set_item_class(int i, const string& name) { + int set_item_class(int i, const std::string& name) { if (!is_valid_crush_name(name)) return -EINVAL; class_map[i] = get_or_create_class_id(name); @@ -515,7 +515,8 @@ public: class_map[i] = c; return c; } - void get_devices_by_class(const string &name, set *devices) const { + void get_devices_by_class(const std::string &name, + std::set *devices) const { ceph_assert(devices); devices->clear(); if (!class_exists(name)) { @@ -535,40 +536,40 @@ public: } class_map.erase(it); } - int can_rename_item(const string& srcname, - const string& dstname, - ostream *ss) const; - int rename_item(const string& srcname, - const string& dstname, - ostream *ss); - int can_rename_bucket(const string& srcname, - const string& dstname, - ostream *ss) const; - int rename_bucket(const string& srcname, - const string& dstname, - ostream *ss); + int can_rename_item(const std::string& srcname, + const std::string& dstname, + std::ostream *ss) const; + int rename_item(const std::string& srcname, + const std::string& dstname, + std::ostream *ss); + int can_rename_bucket(const std::string& srcname, + const std::string& dstname, + std::ostream *ss) const; + int rename_bucket(const std::string& srcname, + const std::string& dstname, + std::ostream *ss); // rule names - int rename_rule(const string& srcname, - const string& dstname, - ostream *ss); - bool rule_exists(string name) const { + int rename_rule(const std::string& srcname, + const std::string& dstname, + std::ostream *ss); + bool rule_exists(std::string name) const { build_rmaps(); return rule_name_rmap.count(name); } - int get_rule_id(string name) const { + int get_rule_id(std::string name) const { build_rmaps(); if (rule_name_rmap.count(name)) return rule_name_rmap[name]; return -ENOENT; } const char *get_rule_name(int t) const { - std::map::const_iterator p = rule_name_map.find(t); + auto p = rule_name_map.find(t); if (p != rule_name_map.end()) return p->second.c_str(); return 0; } - void set_rule_name(int i, const string& name) { + void set_rule_name(int i, const std::string& name) { rule_name_map[i] = name; if (have_rmaps) rule_name_rmap[name] = i; @@ -584,22 +585,22 @@ public: * * Note that these may not be parentless roots. */ - void find_takes(set *roots) const; - void find_takes_by_rule(int rule, set *roots) const; + void find_takes(std::set *roots) const; + void find_takes_by_rule(int rule, std::set *roots) const; /** * find tree roots * * These are parentless nodes in the map. */ - void find_roots(set *roots) const; + void find_roots(std::set *roots) const; /** * find tree roots that contain shadow (device class) items only */ - void find_shadow_roots(set *roots) const { - set all; + void find_shadow_roots(std::set *roots) const { + std::set all; find_roots(&all); for (auto& p: all) { if (is_shadow_item(p)) { @@ -614,8 +615,8 @@ public: * These are parentless nodes in the map that are not shadow * items for device classes. */ - void find_nonshadow_roots(set *roots) const { - set all; + void find_nonshadow_roots(std::set *roots) const { + std::set all; find_roots(&all); for (auto& p: all) { if (!is_shadow_item(p)) { @@ -661,8 +662,12 @@ public: * @param weight optional pointer to weight of item at that location * @return true if item is at specified location */ - bool check_item_loc(CephContext *cct, int item, const map& loc, int *iweight); - bool check_item_loc(CephContext *cct, int item, const map& loc, float *weight) { + bool check_item_loc(CephContext *cct, int item, + const std::map& loc, + int *iweight); + bool check_item_loc(CephContext *cct, int item, + const std::map& loc, + float *weight) { int iweight; bool ret = check_item_loc(cct, item, loc, &iweight); if (weight) @@ -676,7 +681,7 @@ public: * * FIXME: ambiguous for items that occur multiple times in the map */ - pair get_immediate_parent(int id, int *ret = NULL) const; + std::pair get_immediate_parent(int id, int *ret = NULL) const; int get_immediate_parent_id(int id, int *parent) const; @@ -696,14 +701,14 @@ public: * returns the location in the form of (type=foo) where type is a type of bucket * specified in the CRUSH map and foo is a name specified in the CRUSH map */ - map get_full_location(int id) const; + std::map get_full_location(int id) const; /** * return location map for a item, by name */ int get_full_location( - const string& name, - std::map *ploc); + const std::string& name, + std::map *ploc); /* * identical to get_full_location(int id) although it returns the type/name @@ -711,7 +716,9 @@ public: * * returns -ENOENT if id is not found. */ - int get_full_location_ordered(int id, vector >& path) const; + int get_full_location_ordered( + int id, + std::vector >& path) const; /* * identical to get_full_location_ordered(int id, vector >& path), @@ -720,13 +727,13 @@ public: * * returns the location in descending hierarchy as a string. */ - string get_full_location_ordered_string(int id) const; + std::string get_full_location_ordered_string(int id) const; /** * returns (type_id, type) of all parent buckets between id and * default, can be used to check for anomalous CRUSH maps */ - map get_parent_hierarchy(int id) const; + std::map get_parent_hierarchy(int id) const; /** * enumerate immediate children of given node @@ -734,22 +741,22 @@ public: * @param id parent bucket or device id * @return number of items, or error */ - int get_children(int id, list *children) const; + int get_children(int id, std::list *children) const; /** * enumerate all children of given node * * @param id parent bucket or device id * @return number of items, or error */ - int get_all_children(int id, set *children) const; + int get_all_children(int id, std::set *children) const; void get_children_of_type(int id, int type, - vector *children, + std::vector *children, bool exclude_shadow = true) const; /** * enumerate all subtrees by type */ - void get_subtree_of_type(int type, vector *subtrees); + void get_subtree_of_type(int type, std::vector *subtrees); /** @@ -759,7 +766,7 @@ public: int verify_upmap(CephContext *cct, int rule_id, int pool_size, - const vector& up); + const std::vector& up); /** * enumerate leaves(devices) of given node @@ -767,10 +774,10 @@ public: * @param name parent bucket name * @return 0 on success or a negative errno on error. */ - int get_leaves(const string &name, set *leaves) const; + int get_leaves(const std::string &name, std::set *leaves) const; private: - int _get_leaves(int id, list *leaves) const; // worker + int _get_leaves(int id, std::list *leaves) const; // worker public: /** @@ -804,8 +811,8 @@ public: * @param init_weight_sets initialize weight-set weights to weight (vs 0) * @return 0 for success, negative on error */ - int insert_item(CephContext *cct, int id, float weight, string name, - const map& loc, + int insert_item(CephContext *cct, int id, float weight, std::string name, + const std::map& loc, bool init_weight_sets=true); /** @@ -819,7 +826,7 @@ public: * @param loc location (map of type to bucket names) * @return 0 for success, negative on error */ - int move_bucket(CephContext *cct, int id, const map& loc); + int move_bucket(CephContext *cct, int id, const std::map& loc); /** * swap bucket contents of two buckets without touching bucket ids @@ -843,7 +850,8 @@ public: * @param loc location (map of type to bucket names) * @return 0 for success, negative on error */ - int link_bucket(CephContext *cct, int id, const map& loc); + int link_bucket(CephContext *cct, int id, + const std::map& loc); /** * add or update an item's position in the map @@ -858,7 +866,8 @@ public: * @param loc location (map of type to bucket names) * @return 0 for no change, 1 for successful change, negative on error */ - int update_item(CephContext *cct, int id, float weight, string name, const map& loc); + int update_item(CephContext *cct, int id, float weight, std::string name, + const std::map& loc); /** * create or move an item, but do not adjust its weight if it already exists @@ -871,8 +880,9 @@ public: * @param init_weight_sets initialize weight-set values to weight (vs 0) * @return 0 for no change, 1 for successful change, negative on error */ - int create_or_move_item(CephContext *cct, int item, float weight, string name, - const map& loc, + int create_or_move_item(CephContext *cct, int item, float weight, + std::string name, + const std::map& loc, bool init_weight_sets=true); /** @@ -921,7 +931,7 @@ public: * @param loc a set of key=value pairs describing a location in the hierarchy */ int get_common_ancestor_distance(CephContext *cct, int id, - const std::multimap& loc) const; + const std::multimap& loc) const; /** * parse a set of key/value pairs out of a string vector @@ -931,10 +941,10 @@ public: * @param args list of strings (each key= or key=value) * @param ploc pointer to a resulting location map or multimap */ - static int parse_loc_map(const std::vector& args, - std::map *ploc); - static int parse_loc_multimap(const std::vector& args, - std::multimap *ploc); + static int parse_loc_map(const std::vector& args, + std::map *ploc); + static int parse_loc_multimap(const std::vector& args, + std::multimap *ploc); /** @@ -949,8 +959,10 @@ public: float get_item_weightf(int id) const { return (float)get_item_weight(id) / (float)0x10000; } - int get_item_weight_in_loc(int id, const map &loc); - float get_item_weightf_in_loc(int id, const map &loc) { + int get_item_weight_in_loc(int id, + const std::map &loc); + float get_item_weightf_in_loc(int id, + const std::map &loc) { return (float)get_item_weight_in_loc(id, loc) / (float)0x10000; } @@ -976,10 +988,10 @@ public: int bucket_id, bool update_weight_sets); int adjust_item_weight_in_loc(CephContext *cct, int id, int weight, - const map& loc, + const std::map& loc, bool update_weight_sets=true); int adjust_item_weightf_in_loc(CephContext *cct, int id, float weight, - const map& loc, + const std::map& loc, bool update_weight_sets=true) { int r = validate_weightf(weight); if (r < 0) { @@ -991,7 +1003,7 @@ public: void reweight(CephContext *cct); void reweight_bucket(crush_bucket *b, crush_choose_arg_map& arg_map, - vector *weightv); + std::vector *weightv); int adjust_subtree_weight(CephContext *cct, int id, int weight, bool update_weight_sets=true); @@ -1097,9 +1109,9 @@ public: } private: - float _get_take_weight_osd_map(int root, map *pmap) const; - void _normalize_weight_map(float sum, const map& m, - map *pmap) const; + float _get_take_weight_osd_map(int root, std::map *pmap) const; + void _normalize_weight_map(float sum, const std::map& m, + std::map *pmap) const; public: /** @@ -1112,7 +1124,7 @@ public: * @param pmap [out] map of osd to weight * @return 0 for success, or negative error code */ - int get_rule_weight_osd_map(unsigned ruleno, map *pmap) const; + int get_rule_weight_osd_map(unsigned ruleno, std::map *pmap) const; /** * calculate a map of osds to weights for a given starting root @@ -1124,7 +1136,7 @@ public: * @param pmap [out] map of osd to weight * @return 0 for success, or negative error code */ - int get_take_weight_osd_map(int root, map *pmap) const; + int get_take_weight_osd_map(int root, std::map *pmap) const; /* modifiers */ @@ -1185,17 +1197,17 @@ public: } int add_simple_rule( - string name, string root_name, string failure_domain_type, - string device_class, - string mode, int rule_type, ostream *err = 0); + std::string name, std::string root_name, std::string failure_domain_type, + std::string device_class, std::string mode, int rule_type, + std::ostream *err = 0); /** * @param rno rule[set] id to use, -1 to pick the lowest available */ int add_simple_rule_at( - string name, string root_name, - string failure_domain_type, string device_class, string mode, - int rule_type, int rno, ostream *err = 0); + std::string name, std::string root_name, + std::string failure_domain_type, std::string device_class, std::string mode, + int rule_type, int rno, std::ostream *err = 0); int remove_rule(int ruleno); @@ -1318,20 +1330,21 @@ public: } int bucket_set_alg(int id, int alg); - int update_device_class(int id, const string& class_name, const string& name, ostream *ss); - int remove_device_class(CephContext *cct, int id, ostream *ss); + int update_device_class(int id, const std::string& class_name, + const std::string& name, std::ostream *ss); + int remove_device_class(CephContext *cct, int id, std::ostream *ss); int device_class_clone( int original, int device_class, - const std::map>& old_class_bucket, + const std::map>& old_class_bucket, const std::set& used_ids, int *clone, - map>> *cmap_item_weight); - bool class_is_in_use(int class_id, ostream *ss = nullptr); - int rename_class(const string& srcname, const string& dstname); + std::map>> *cmap_item_weight); + bool class_is_in_use(int class_id, std::ostream *ss = nullptr); + int rename_class(const std::string& srcname, const std::string& dstname); int populate_classes( - const std::map>& old_class_bucket); - int get_rules_by_class(const string &class_name, set *rules); - int get_rules_by_osd(int osd, set *rules); + const std::map>& old_class_bucket); + int get_rules_by_class(const std::string &class_name, std::set *rules); + int get_rules_by_osd(int osd, std::set *rules); bool _class_is_dead(int class_id); void cleanup_dead_classes(); int rebuild_roots_with_classes(CephContext *cct); @@ -1340,12 +1353,12 @@ public: int reclassify( CephContext *cct, - ostream& out, - const map& classify_root, - const map>& classify_bucket + std::ostream& out, + const std::map& classify_root, + const std::map>& classify_bucket ); - int set_subtree_class(const string& name, const string& class_name); + int set_subtree_class(const std::string& name, const std::string& class_name); void start_choose_profile() { free(crush->choose_tries); @@ -1522,19 +1535,19 @@ public: crush_choose_arg_map cmap, int bucketid, int id, - const vector& weight, - ostream *ss); + const std::vector& weight, + std::ostream *ss); int choose_args_adjust_item_weight( CephContext *cct, crush_choose_arg_map cmap, - int id, const vector& weight, - ostream *ss); + int id, const std::vector& weight, + std::ostream *ss); int choose_args_adjust_item_weightf( CephContext *cct, crush_choose_arg_map cmap, - int id, const vector& weightf, - ostream *ss) { - vector weight(weightf.size()); + int id, const std::vector& weightf, + std::ostream *ss) { + std::vector weight(weightf.size()); for (unsigned i = 0; i < weightf.size(); ++i) { weight[i] = (int)(weightf[i] * (double)0x10000); } @@ -1552,7 +1565,7 @@ public: } template - void do_rule(int rule, int x, vector& out, int maxout, + void do_rule(int rule, int x, std::vector& out, int maxout, const WeightVector& weight, uint64_t choose_args_index) const { int rawout[maxout]; @@ -1571,25 +1584,25 @@ public: int _choose_type_stack( CephContext *cct, - const vector>& stack, - const set& overfull, - const vector& underfull, - const vector& orig, - vector::const_iterator& i, - set& used, - vector *pw, + const std::vector>& stack, + const std::set& overfull, + const std::vector& underfull, + const std::vector& orig, + std::vector::const_iterator& i, + std::set& used, + std::vector *pw, int root_bucket) const; int try_remap_rule( CephContext *cct, int rule, int maxout, - const set& overfull, - const vector& underfull, - const vector& orig, - vector *out) const; + const std::set& overfull, + const std::vector& underfull, + const std::vector& orig, + std::vector *out) const; - bool check_crush_rule(int ruleset, int type, int size, ostream& ss) { + bool check_crush_rule(int ruleset, int type, int size, std::ostream& ss) { ceph_assert(crush); __u32 i; @@ -1614,32 +1627,33 @@ public: return false; } - void encode(bufferlist &bl, uint64_t features) const; - void decode(bufferlist::const_iterator &blp); - void decode_crush_bucket(crush_bucket** bptr, bufferlist::const_iterator &blp); - void dump(Formatter *f) const; - void dump_rules(Formatter *f) const; - void dump_rule(int ruleset, Formatter *f) const; - void dump_tunables(Formatter *f) const; - void dump_choose_args(Formatter *f) const; - void list_rules(Formatter *f) const; - void list_rules(ostream *ss) const; - void dump_tree(ostream *out, - Formatter *f, + void encode(ceph::buffer::list &bl, uint64_t features) const; + void decode(ceph::buffer::list::const_iterator &blp); + void decode_crush_bucket(crush_bucket** bptr, + ceph::buffer::list::const_iterator &blp); + void dump(ceph::Formatter *f) const; + void dump_rules(ceph::Formatter *f) const; + void dump_rule(int ruleset, ceph::Formatter *f) const; + void dump_tunables(ceph::Formatter *f) const; + void dump_choose_args(ceph::Formatter *f) const; + void list_rules(ceph::Formatter *f) const; + void list_rules(std::ostream *ss) const; + void dump_tree(std::ostream *out, + ceph::Formatter *f, const CrushTreeDumper::name_map_t& ws, bool show_shadow = false) const; - void dump_tree(ostream *out, Formatter *f) { + void dump_tree(std::ostream *out, ceph::Formatter *f) { dump_tree(out, f, CrushTreeDumper::name_map_t()); } - void dump_tree(Formatter *f, + void dump_tree(ceph::Formatter *f, const CrushTreeDumper::name_map_t& ws) const; - static void generate_test_instances(list& o); + static void generate_test_instances(std::list& o); int get_osd_pool_default_crush_replicated_ruleset(CephContext *cct); - static bool is_valid_crush_name(const string& s); + static bool is_valid_crush_name(const std::string& s); static bool is_valid_crush_loc(CephContext *cct, - const map& loc); + const std::map& loc); }; WRITE_CLASS_ENCODER_FEATURES(CrushWrapper) diff --git a/src/crush/grammar.h b/src/crush/grammar.h index 42a6068b362..582e502e640 100644 --- a/src/crush/grammar.h +++ b/src/crush/grammar.h @@ -29,7 +29,7 @@ #endif using namespace boost::spirit; -struct crush_grammar : public grammar +struct crush_grammar : public boost::spirit::grammar { enum { _int = 1, @@ -67,45 +67,53 @@ struct crush_grammar : public grammar template struct definition { - rule, parser_tag<_int> > integer; - rule, parser_tag<_posint> > posint; - rule, parser_tag<_negint> > negint; - rule, parser_tag<_name> > name; - - rule, parser_tag<_tunable> > tunable; - - rule, parser_tag<_device> > device; - - rule, parser_tag<_bucket_type> > bucket_type; - - rule, parser_tag<_bucket_id> > bucket_id; - rule, parser_tag<_bucket_alg> > bucket_alg; - rule, parser_tag<_bucket_hash> > bucket_hash; - rule, parser_tag<_bucket_item> > bucket_item; - rule, parser_tag<_bucket> > bucket; - - rule, parser_tag<_step_take> > step_take; - rule, parser_tag<_step_set_choose_tries> > step_set_choose_tries; - rule, parser_tag<_step_set_choose_local_tries> > step_set_choose_local_tries; - rule, parser_tag<_step_set_choose_local_fallback_tries> > step_set_choose_local_fallback_tries; - rule, parser_tag<_step_set_chooseleaf_tries> > step_set_chooseleaf_tries; - rule, parser_tag<_step_set_chooseleaf_vary_r> > step_set_chooseleaf_vary_r; - rule, parser_tag<_step_set_chooseleaf_stable> > step_set_chooseleaf_stable; - rule, parser_tag<_step_choose> > step_choose; - rule, parser_tag<_step_chooseleaf> > step_chooseleaf; - rule, parser_tag<_step_emit> > step_emit; - rule, parser_tag<_step> > step; - rule, parser_tag<_crushrule> > crushrule; - rule, parser_tag<_weight_set_weights> > weight_set_weights; - rule, parser_tag<_weight_set> > weight_set; - rule, parser_tag<_choose_arg_ids> > choose_arg_ids; - rule, parser_tag<_choose_arg> > choose_arg; - rule, parser_tag<_choose_args> > choose_args; - - rule, parser_tag<_crushmap> > crushmap; + boost::spirit::rule,boost::spirit::parser_tag<_int> > integer; + boost::spirit::rule, boost::spirit::parser_tag<_posint> > posint; + boost::spirit::rule, boost::spirit::parser_tag<_negint> > negint; + boost::spirit::rule, boost::spirit::parser_tag<_name> > name; + + boost::spirit::rule, boost::spirit::parser_tag<_tunable> > tunable; + + boost::spirit::rule, boost::spirit::parser_tag<_device> > device; + + boost::spirit::rule, boost::spirit::parser_tag<_bucket_type> > bucket_type; + + boost::spirit::rule, boost::spirit::parser_tag<_bucket_id> > bucket_id; + boost::spirit::rule, boost::spirit::parser_tag<_bucket_alg> > bucket_alg; + boost::spirit::rule, boost::spirit::parser_tag<_bucket_hash> > bucket_hash; + boost::spirit::rule, boost::spirit::parser_tag<_bucket_item> > bucket_item; + boost::spirit::rule, boost::spirit::parser_tag<_bucket> > bucket; + + boost::spirit::rule, boost::spirit::parser_tag<_step_take> > step_take; + boost::spirit::rule, boost::spirit::parser_tag<_step_set_choose_tries> > step_set_choose_tries; + boost::spirit::rule, boost::spirit::parser_tag<_step_set_choose_local_tries> > step_set_choose_local_tries; + boost::spirit::rule, boost::spirit::parser_tag<_step_set_choose_local_fallback_tries> > step_set_choose_local_fallback_tries; + boost::spirit::rule, boost::spirit::parser_tag<_step_set_chooseleaf_tries> > step_set_chooseleaf_tries; + boost::spirit::rule, boost::spirit::parser_tag<_step_set_chooseleaf_vary_r> > step_set_chooseleaf_vary_r; + boost::spirit::rule, boost::spirit::parser_tag<_step_set_chooseleaf_stable> > step_set_chooseleaf_stable; + boost::spirit::rule, boost::spirit::parser_tag<_step_choose> > step_choose; + boost::spirit::rule, boost::spirit::parser_tag<_step_chooseleaf> > step_chooseleaf; + boost::spirit::rule, boost::spirit::parser_tag<_step_emit> > step_emit; + boost::spirit::rule, boost::spirit::parser_tag<_step> > step; + boost::spirit::rule, boost::spirit::parser_tag<_crushrule> > crushrule; + boost::spirit::rule, boost::spirit::parser_tag<_weight_set_weights> > weight_set_weights; + boost::spirit::rule, boost::spirit::parser_tag<_weight_set> > weight_set; + boost::spirit::rule, boost::spirit::parser_tag<_choose_arg_ids> > choose_arg_ids; + boost::spirit::rule, boost::spirit::parser_tag<_choose_arg> > choose_arg; + boost::spirit::rule, boost::spirit::parser_tag<_choose_args> > choose_args; + + boost::spirit::rule, boost::spirit::parser_tag<_crushmap> > crushmap; definition(crush_grammar const& /*self*/) { + using boost::spirit::leaf_node_d; + using boost::spirit::lexeme_d; + using boost::spirit::str_p; + using boost::spirit::ch_p; + using boost::spirit::digit_p; + using boost::spirit::alnum_p; + using boost::spirit::real_p; + // base types integer = leaf_node_d[ lexeme_d[ (!ch_p('-') >> +digit_p) @@ -183,7 +191,8 @@ struct crush_grammar : public grammar crushmap = *(tunable | device | bucket_type) >> *(bucket | crushrule) >> *choose_args; } - rule, parser_tag<_crushmap> > const& + boost::spirit::rule, + boost::spirit::parser_tag<_crushmap> > const& start() const { return crushmap; } }; }; -- 2.39.5