// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab /* * Ceph - scalable distributed file system * * Copyright (C) 2004-2008 Sage Weil * * This is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software * Foundation. See file COPYING. * */ #ifndef CEPH_CRUSH_GRAMMAR_H #define CEPH_CRUSH_GRAMMAR_H //#define BOOST_SPIRIT_DEBUG #ifdef USE_BOOST_SPIRIT_OLD_HDR #include #include #include #else #define BOOST_SPIRIT_USE_OLD_NAMESPACE #include #include #include #endif using namespace boost::spirit; struct crush_grammar : public grammar { enum { _int = 1, _posint, _negint, _name, _device, _bucket_type, _bucket_id, _bucket_alg, _bucket_hash, _bucket_item, _bucket, _step_take, _step_set_chooseleaf_tries, _step_set_chooseleaf_vary_r, _step_set_chooseleaf_stable, _step_set_choose_tries, _step_set_choose_local_tries, _step_set_choose_local_fallback_tries, _step_choose, _step_chooseleaf, _step_emit, _step, _crushrule, _weight_set_weights, _weight_set, _choose_arg_ids, _choose_arg, _choose_args, _crushmap, _tunable, }; 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; definition(crush_grammar const& /*self*/) { // base types integer = leaf_node_d[ lexeme_d[ (!ch_p('-') >> +digit_p) ] ]; posint = leaf_node_d[ lexeme_d[ +digit_p ] ]; negint = leaf_node_d[ lexeme_d[ ch_p('-') >> +digit_p ] ]; name = leaf_node_d[ lexeme_d[ +( alnum_p || ch_p('-') || ch_p('_') || ch_p('.')) ] ]; // tunables tunable = str_p("tunable") >> name >> posint; // devices device = str_p("device") >> posint >> name >> !( str_p("class") >> name ); // bucket types bucket_type = str_p("type") >> posint >> name; // buckets bucket_id = str_p("id") >> negint >> !( str_p("class") >> name ); bucket_alg = str_p("alg") >> name; bucket_hash = str_p("hash") >> ( integer | str_p("rjenkins1") ); bucket_item = str_p("item") >> name >> !( str_p("weight") >> real_p ) >> !( str_p("pos") >> posint ); bucket = name >> name >> '{' >> *bucket_id >> bucket_alg >> *bucket_hash >> *bucket_item >> '}'; // rules step_take = str_p("take") >> name >> !( str_p("class") >> name ); step_set_choose_tries = str_p("set_choose_tries") >> posint; step_set_choose_local_tries = str_p("set_choose_local_tries") >> posint; step_set_choose_local_fallback_tries = str_p("set_choose_local_fallback_tries") >> posint; step_set_chooseleaf_tries = str_p("set_chooseleaf_tries") >> posint; step_set_chooseleaf_vary_r = str_p("set_chooseleaf_vary_r") >> posint; step_set_chooseleaf_stable = str_p("set_chooseleaf_stable") >> posint; step_choose = str_p("choose") >> ( str_p("indep") | str_p("firstn") ) >> integer >> str_p("type") >> name; step_chooseleaf = str_p("chooseleaf") >> ( str_p("indep") | str_p("firstn") ) >> integer >> str_p("type") >> name; step_emit = str_p("emit"); step = str_p("step") >> ( step_take | step_set_choose_tries | step_set_choose_local_tries | step_set_choose_local_fallback_tries | step_set_chooseleaf_tries | step_set_chooseleaf_vary_r | step_set_chooseleaf_stable | step_choose | step_chooseleaf | step_emit ); crushrule = str_p("rule") >> !name >> '{' >> (str_p("id") | str_p("ruleset")) >> posint >> str_p("type") >> ( str_p("replicated") | str_p("erasure") ) >> str_p("min_size") >> posint >> str_p("max_size") >> posint >> +step >> '}'; weight_set_weights = str_p("[") >> *real_p >> str_p("]"); weight_set = str_p("weight_set") >> str_p("[") >> *weight_set_weights >> str_p("]"); choose_arg_ids = str_p("ids") >> str_p("[") >> *integer >> str_p("]"); choose_arg = str_p("{") >> str_p("bucket_id") >> negint >> !weight_set >> !choose_arg_ids >> str_p("}"); choose_args = str_p("choose_args") >> posint >> str_p("{") >> *choose_arg >> str_p("}"); // the whole crush map crushmap = *(tunable | device | bucket_type) >> *(bucket | crushrule) >> *choose_args; } rule, parser_tag<_crushmap> > const& start() const { return crushmap; } }; }; #endif