| 136 | } |
| 137 | |
| 138 | std::map<std::string,std::string,std::less<>> |
| 139 | ConfigMap::generate_entity_map( |
| 140 | const EntityName& name, |
| 141 | const map<std::string,std::string>& crush_location, |
| 142 | const CrushWrapper *crush, |
| 143 | const std::string& device_class, |
| 144 | std::unordered_map<std::string, ValueSource> *src) |
| 145 | { |
| 146 | // global, then by type, then by name prefix component(s), then name. |
| 147 | // name prefix components are .-separated, |
| 148 | // e.g. client.a.b.c -> [global, client, client.a, client.a.b, client.a.b.c] |
| 149 | vector<pair<string,Section*>> sections = { make_pair("global", &global) }; |
| 150 | auto p = by_type.find(name.get_type_name()); |
| 151 | if (p != by_type.end()) { |
| 152 | sections.emplace_back(name.get_type_name(), &p->second); |
| 153 | } |
| 154 | vector<std::string> name_bits; |
| 155 | boost::split(name_bits, name.to_str(), [](char c){ return c == '.'; }); |
| 156 | std::string tname; |
| 157 | for (unsigned p = 0; p < name_bits.size(); ++p) { |
| 158 | if (p) { |
| 159 | tname += '.'; |
| 160 | } |
| 161 | tname += name_bits[p]; |
| 162 | auto q = by_id.find(tname); |
| 163 | if (q != by_id.end()) { |
| 164 | sections.push_back(make_pair(tname, &q->second)); |
| 165 | } |
| 166 | } |
| 167 | std::map<std::string,std::string,std::less<>> out; |
| 168 | MaskedOption *prev = nullptr; |
| 169 | for (auto s : sections) { |
| 170 | for (auto& i : s.second->options) { |
| 171 | auto& o = i.second; |
| 172 | // match against crush location, class |
| 173 | if (o.mask.device_class.size() && |
| 174 | o.mask.device_class != device_class) { |
| 175 | continue; |
| 176 | } |
| 177 | if (o.mask.location_type.size()) { |
| 178 | auto p = crush_location.find(o.mask.location_type); |
| 179 | if (p == crush_location.end() || |
| 180 | p->second != o.mask.location_value) { |
| 181 | continue; |
| 182 | } |
| 183 | } |
| 184 | if (prev && prev->opt->name != i.first) { |
| 185 | prev = nullptr; |
| 186 | } |
| 187 | if (prev && |
| 188 | prev->get_precision(crush) < o.get_precision(crush)) { |
| 189 | continue; |
| 190 | } |
| 191 | out[i.first] = o.raw_value; |
| 192 | if (src) { |
| 193 | (*src).emplace(i.first, ConfigMap::ValueSource(s.first, &o)); |
| 194 | } |
| 195 | prev = &o; |