| 156 | } |
| 157 | |
| 158 | void MappingToCsv(string const & keyName, Stats::NameToCountMapping const & mapping, bool printPercentage, |
| 159 | basic_ostream<char> & ss) |
| 160 | { |
| 161 | struct KeyValue |
| 162 | { |
| 163 | string m_key; |
| 164 | uint64_t m_value = 0; |
| 165 | }; |
| 166 | |
| 167 | if (mapping.empty()) |
| 168 | return; |
| 169 | |
| 170 | ss << keyName; |
| 171 | if (printPercentage) |
| 172 | ss << ",number,percent\n"; |
| 173 | else |
| 174 | ss << ",number\n"; |
| 175 | |
| 176 | // Sorting from bigger to smaller values. |
| 177 | vector<KeyValue> keyValues; |
| 178 | keyValues.reserve(mapping.size()); |
| 179 | for (auto const & kv : mapping) |
| 180 | keyValues.push_back({kv.first, kv.second}); |
| 181 | |
| 182 | sort(keyValues.begin(), keyValues.end(), |
| 183 | [](KeyValue const & a, KeyValue const & b) { return a.m_value > b.m_value; }); |
| 184 | |
| 185 | uint64_t allValues = 0; |
| 186 | for (auto const & kv : keyValues) |
| 187 | allValues += kv.m_value; |
| 188 | |
| 189 | for (auto const & kv : keyValues) |
| 190 | { |
| 191 | if (kv.m_value == 0) |
| 192 | continue; |
| 193 | |
| 194 | ss << kv.m_key << "," << kv.m_value; |
| 195 | if (printPercentage) |
| 196 | ss << "," << 100.0 * static_cast<double>(kv.m_value) / allValues; |
| 197 | ss << '\n'; |
| 198 | } |
| 199 | ss.flush(); |
| 200 | } |
| 201 | |
| 202 | void MappingFromCsv(basic_istream<char> & ss, Stats::NameToCountMapping & mapping) |
| 203 | { |