]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/perf_histogram.cc
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / common / perf_histogram.cc
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) 2017 OVH
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 #include "common/perf_histogram.h"
16
17 #include <limits>
18
19 void PerfHistogramCommon::dump_formatted_axis(
20 ceph::Formatter *f, const PerfHistogramCommon::axis_config_d &ac) {
21 f->open_object_section("axis");
22
23 // Dump axis configuration
24 f->dump_string("name", ac.m_name);
25 f->dump_int("min", ac.m_min);
26 f->dump_int("quant_size", ac.m_quant_size);
27 f->dump_int("buckets", ac.m_buckets);
28 switch (ac.m_scale_type) {
29 case SCALE_LINEAR:
30 f->dump_string("scale_type", "linear");
31 break;
32 case SCALE_LOG2:
33 f->dump_string("scale_type", "log2");
34 break;
35 default:
36 assert(false && "Invalid scale type");
37 }
38
39 {
40 // Dump concrete ranges for axis buckets
41 f->open_array_section("ranges");
42 auto ranges = get_axis_bucket_ranges(ac);
43 for (int i = 0; i < ac.m_buckets; ++i) {
44 f->open_object_section("bucket");
45 if (i > 0) {
46 f->dump_int("min", ranges[i].first);
47 }
48 if (i < ac.m_buckets - 1) {
49 f->dump_int("max", ranges[i].second);
50 }
51 f->close_section();
52 }
53 f->close_section();
54 }
55
56 f->close_section();
57 }
58
59 int64_t get_quants(int64_t i, PerfHistogramCommon::scale_type_d st) {
60 switch (st) {
61 case PerfHistogramCommon::SCALE_LINEAR:
62 return i;
63 case PerfHistogramCommon::SCALE_LOG2:
64 return int64_t(1) << (i - 1);
65 }
66 assert(false && "Invalid scale type");
67 }
68
69 int64_t PerfHistogramCommon::get_bucket_for_axis(
70 int64_t value, const PerfHistogramCommon::axis_config_d &ac) {
71 if (value < ac.m_min) {
72 return 0;
73 }
74
75 value -= ac.m_min;
76 value /= ac.m_quant_size;
77
78 switch (ac.m_scale_type) {
79 case SCALE_LINEAR:
80 return std::min<int64_t>(value + 1, ac.m_buckets - 1);
81
82 case SCALE_LOG2:
83 for (int64_t i = 1; i < ac.m_buckets; ++i) {
84 if (value < get_quants(i, SCALE_LOG2)) {
85 return i;
86 }
87 }
88 return ac.m_buckets - 1;
89 }
90 assert(false && "Invalid scale type");
91 }
92
93 std::vector<std::pair<int64_t, int64_t>>
94 PerfHistogramCommon::get_axis_bucket_ranges(
95 const PerfHistogramCommon::axis_config_d &ac) {
96 std::vector<std::pair<int64_t, int64_t>> ret;
97 ret.resize(ac.m_buckets);
98
99 // First bucket is for value < min
100 int64_t min = ac.m_min;
101 for (int64_t i = 1; i < ac.m_buckets - 1; i++) {
102 int64_t max_exclusive =
103 ac.m_min + get_quants(i, ac.m_scale_type) * ac.m_quant_size;
104
105 // Dump bucket range
106 ret[i].first = min;
107 ret[i].second = max_exclusive - 1;
108
109 // Shift min to next bucket
110 min = max_exclusive;
111 }
112
113 // Fill up first and last element, note that in case m_buckets == 1
114 // those will point to the same element, the order is important here
115 ret.front().second = ac.m_min - 1;
116 ret.back().first = min;
117
118 ret.front().first = std::numeric_limits<int64_t>::min();
119 ret.back().second = std::numeric_limits<int64_t>::max();
120 return ret;
121 }