}
void add_to_reports(
+ const std::map<OSDPerfMetricQuery, OSDPerfMetricLimits> & limits,
std::map<OSDPerfMetricQuery, OSDPerfMetricReport> *reports) {
for (auto &it : data) {
auto &query = it.first;
+ auto &counters = it.second;
auto &report = (*reports)[query];
query.get_performance_counter_descriptors(
&report.performance_counter_descriptors);
- for (auto &it_counters : it.second) {
- auto &bl = report.group_packed_performance_counters[it_counters.first];
- query.pack_counters(it_counters.second, &bl);
+ auto &descriptors = report.performance_counter_descriptors;
+ ceph_assert(descriptors.size() > 0);
+
+ if (!is_limited(limits.at(query), counters.size())) {
+ for (auto &it_counters : counters) {
+ auto &bl = report.group_packed_performance_counters[it_counters.first];
+ query.pack_counters(it_counters.second, &bl);
+ }
+ continue;
+ }
+
+ for (auto &limit : limits.at(query)) {
+ size_t index = 0;
+ for (; index < descriptors.size(); index++) {
+ if (descriptors[index] == limit.order_by) {
+ break;
+ }
+ }
+ if (index == descriptors.size()) {
+ // should not happen
+ continue;
+ }
+
+ typedef std::map<OSDPerfMetricKey, PerformanceCounters>::iterator
+ Iterator;
+ std::vector<Iterator> counter_iterators;
+ counter_iterators.reserve(counters.size());
+ for (Iterator it_counters = counters.begin();
+ it_counters != counters.end(); it_counters++) {
+ counter_iterators.push_back(it_counters);
+ }
+ std::sort(counter_iterators.begin(), counter_iterators.end(),
+ [index](const Iterator &a, const Iterator &b) -> bool {
+ return a->second[index].first > b->second[index].first;
+ });
+
+ uint64_t count = 0;
+ for (auto it_counters : counter_iterators) {
+ if (count == limit.max_count) {
+ break;
+ }
+ auto &bl =
+ report.group_packed_performance_counters[it_counters->first];
+ if (bl.length() == 0) {
+ query.pack_counters(it_counters->second, &bl);
+ }
+ count++;
+ }
}
}
}
private:
+ static bool is_limited(const OSDPerfMetricLimits &limits,
+ size_t counters_size) {
+ if (limits.empty()) {
+ return false;
+ }
+
+ for (auto &limit : limits) {
+ if (limit.max_count >= counters_size) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
std::map<OSDPerfMetricQuery,
std::map<OSDPerfMetricKey, PerformanceCounters>> data;
};