Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / crush / grammar.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4  * Ceph - scalable distributed file system
5  *
6  * Copyright (C) 2004-2008 Sage Weil <sage@newdream.net>
7  *
8  * This is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License version 2.1, as published by the Free Software
11  * Foundation.  See file COPYING.
12  *
13  */
14
15 #ifndef CEPH_CRUSH_GRAMMAR_H
16 #define CEPH_CRUSH_GRAMMAR_H
17
18 //#define BOOST_SPIRIT_DEBUG
19
20 #ifdef USE_BOOST_SPIRIT_OLD_HDR
21 #include <boost/spirit/core.hpp>
22 #include <boost/spirit/tree/ast.hpp>
23 #include <boost/spirit/tree/tree_to_xml.hpp>
24 #else
25 #define BOOST_SPIRIT_USE_OLD_NAMESPACE
26 #include <boost/spirit/include/classic_core.hpp>
27 #include <boost/spirit/include/classic_ast.hpp>
28 #include <boost/spirit/include/classic_tree_to_xml.hpp>
29 #endif
30 using namespace boost::spirit;
31
32 struct crush_grammar : public grammar<crush_grammar>
33 {
34   enum {
35     _int = 1,
36     _posint,
37     _negint,
38     _name,
39     _device,
40     _bucket_type,
41     _bucket_id,
42     _bucket_alg,
43     _bucket_hash,
44     _bucket_item,
45     _bucket,
46     _step_take,
47     _step_set_chooseleaf_tries,
48     _step_set_chooseleaf_vary_r,
49     _step_set_chooseleaf_stable,
50     _step_set_choose_tries,
51     _step_set_choose_local_tries,
52     _step_set_choose_local_fallback_tries,
53     _step_choose,
54     _step_chooseleaf,
55     _step_emit,
56     _step,
57     _crushrule,
58     _weight_set_weights,
59     _weight_set,
60     _choose_arg_ids,
61     _choose_arg,
62     _choose_args,
63     _crushmap,
64     _tunable,
65   };
66
67   template <typename ScannerT>
68   struct definition
69   {
70     rule<ScannerT, parser_context<>, parser_tag<_int> >      integer;
71     rule<ScannerT, parser_context<>, parser_tag<_posint> >      posint;
72     rule<ScannerT, parser_context<>, parser_tag<_negint> >      negint;
73     rule<ScannerT, parser_context<>, parser_tag<_name> >      name;
74
75     rule<ScannerT, parser_context<>, parser_tag<_tunable> >      tunable;
76
77     rule<ScannerT, parser_context<>, parser_tag<_device> >      device;
78
79     rule<ScannerT, parser_context<>, parser_tag<_bucket_type> >    bucket_type;
80
81     rule<ScannerT, parser_context<>, parser_tag<_bucket_id> >      bucket_id;
82     rule<ScannerT, parser_context<>, parser_tag<_bucket_alg> >     bucket_alg;
83     rule<ScannerT, parser_context<>, parser_tag<_bucket_hash> >    bucket_hash;
84     rule<ScannerT, parser_context<>, parser_tag<_bucket_item> >    bucket_item;
85     rule<ScannerT, parser_context<>, parser_tag<_bucket> >      bucket;
86
87     rule<ScannerT, parser_context<>, parser_tag<_step_take> >      step_take;
88     rule<ScannerT, parser_context<>, parser_tag<_step_set_choose_tries> >    step_set_choose_tries;
89     rule<ScannerT, parser_context<>, parser_tag<_step_set_choose_local_tries> >    step_set_choose_local_tries;
90     rule<ScannerT, parser_context<>, parser_tag<_step_set_choose_local_fallback_tries> >    step_set_choose_local_fallback_tries;
91     rule<ScannerT, parser_context<>, parser_tag<_step_set_chooseleaf_tries> >    step_set_chooseleaf_tries;
92     rule<ScannerT, parser_context<>, parser_tag<_step_set_chooseleaf_vary_r> >    step_set_chooseleaf_vary_r;
93     rule<ScannerT, parser_context<>, parser_tag<_step_set_chooseleaf_stable> >    step_set_chooseleaf_stable;
94     rule<ScannerT, parser_context<>, parser_tag<_step_choose> >    step_choose;
95     rule<ScannerT, parser_context<>, parser_tag<_step_chooseleaf> >      step_chooseleaf;
96     rule<ScannerT, parser_context<>, parser_tag<_step_emit> >      step_emit;
97     rule<ScannerT, parser_context<>, parser_tag<_step> >      step;
98     rule<ScannerT, parser_context<>, parser_tag<_crushrule> >      crushrule;
99     rule<ScannerT, parser_context<>, parser_tag<_weight_set_weights> >     weight_set_weights;
100     rule<ScannerT, parser_context<>, parser_tag<_weight_set> >     weight_set;
101     rule<ScannerT, parser_context<>, parser_tag<_choose_arg_ids> >     choose_arg_ids;
102     rule<ScannerT, parser_context<>, parser_tag<_choose_arg> >     choose_arg;
103     rule<ScannerT, parser_context<>, parser_tag<_choose_args> >     choose_args;
104
105     rule<ScannerT, parser_context<>, parser_tag<_crushmap> >      crushmap;
106
107     definition(crush_grammar const& /*self*/)
108     {
109       // base types
110       integer     =   leaf_node_d[ lexeme_d[
111                                             (!ch_p('-') >> +digit_p)
112                                             ] ];
113       posint     =   leaf_node_d[ lexeme_d[ +digit_p ] ];
114       negint     =   leaf_node_d[ lexeme_d[ ch_p('-') >> +digit_p ] ];
115       name = leaf_node_d[ lexeme_d[ +( alnum_p || ch_p('-') || ch_p('_') || ch_p('.')) ] ];
116
117       // tunables
118       tunable = str_p("tunable") >> name >> posint;
119
120       // devices
121       device = str_p("device") >> posint >> name >> !( str_p("class") >> name );
122
123       // bucket types
124       bucket_type = str_p("type") >> posint >> name;
125
126       // buckets
127       bucket_id = str_p("id") >> negint >> !( str_p("class") >> name );
128       bucket_alg = str_p("alg") >> name;
129       bucket_hash = str_p("hash") >> ( integer |
130                                        str_p("rjenkins1") );
131       bucket_item = str_p("item") >> name
132                                   >> !( str_p("weight") >> real_p )
133                                   >> !( str_p("pos") >> posint );
134       bucket = name >> name >> '{' >> *bucket_id >> bucket_alg >> *bucket_hash >> *bucket_item >> '}';
135
136       // rules
137       step_take = str_p("take") >> name >> !( str_p("class") >> name );
138       step_set_choose_tries = str_p("set_choose_tries") >> posint;
139       step_set_choose_local_tries = str_p("set_choose_local_tries") >> posint;
140       step_set_choose_local_fallback_tries = str_p("set_choose_local_fallback_tries") >> posint;
141       step_set_chooseleaf_tries = str_p("set_chooseleaf_tries") >> posint;
142       step_set_chooseleaf_vary_r = str_p("set_chooseleaf_vary_r") >> posint;
143       step_set_chooseleaf_stable = str_p("set_chooseleaf_stable") >> posint;
144       step_choose = str_p("choose")
145         >> ( str_p("indep") | str_p("firstn") )
146         >> integer
147         >> str_p("type") >> name;
148       step_chooseleaf = str_p("chooseleaf")
149         >> ( str_p("indep") | str_p("firstn") )
150         >> integer
151         >> str_p("type") >> name;
152       step_emit = str_p("emit");
153       step = str_p("step") >> ( step_take |
154                                 step_set_choose_tries |
155                                 step_set_choose_local_tries |
156                                 step_set_choose_local_fallback_tries |
157                                 step_set_chooseleaf_tries |
158                                 step_set_chooseleaf_vary_r |
159                                 step_set_chooseleaf_stable |
160                                 step_choose |
161                                 step_chooseleaf |
162                                 step_emit );
163       crushrule = str_p("rule") >> !name >> '{'
164                                 >> (str_p("id") | str_p("ruleset")) >> posint
165                            >> str_p("type") >> ( str_p("replicated") | str_p("erasure") )
166                            >> str_p("min_size") >> posint
167                            >> str_p("max_size") >> posint
168                            >> +step
169                            >> '}';
170
171       weight_set_weights = str_p("[") >> *real_p >> str_p("]");
172       weight_set = str_p("weight_set") >> str_p("[")
173                                        >> *weight_set_weights
174                                        >> str_p("]");
175       choose_arg_ids = str_p("ids") >> str_p("[") >> *integer >> str_p("]");
176       choose_arg = str_p("{") >> str_p("bucket_id") >> negint
177                               >> !weight_set
178                               >> !choose_arg_ids
179                               >> str_p("}");
180       choose_args = str_p("choose_args") >> posint >> str_p("{") >> *choose_arg >> str_p("}");
181
182       // the whole crush map
183       crushmap = *(tunable | device | bucket_type) >> *(bucket | crushrule) >> *choose_args;
184     }
185
186     rule<ScannerT, parser_context<>, parser_tag<_crushmap> > const&
187     start() const { return crushmap; }
188   };
189 };
190
191 #endif