X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fcommon%2Fperf_histogram.cc;fp=src%2Fceph%2Fsrc%2Fcommon%2Fperf_histogram.cc;h=035e326728464226f17c1a77a74db2e9c01452f1;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/common/perf_histogram.cc b/src/ceph/src/common/perf_histogram.cc new file mode 100644 index 0000000..035e326 --- /dev/null +++ b/src/ceph/src/common/perf_histogram.cc @@ -0,0 +1,121 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2017 OVH + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "common/perf_histogram.h" + +#include + +void PerfHistogramCommon::dump_formatted_axis( + ceph::Formatter *f, const PerfHistogramCommon::axis_config_d &ac) { + f->open_object_section("axis"); + + // Dump axis configuration + f->dump_string("name", ac.m_name); + f->dump_int("min", ac.m_min); + f->dump_int("quant_size", ac.m_quant_size); + f->dump_int("buckets", ac.m_buckets); + switch (ac.m_scale_type) { + case SCALE_LINEAR: + f->dump_string("scale_type", "linear"); + break; + case SCALE_LOG2: + f->dump_string("scale_type", "log2"); + break; + default: + assert(false && "Invalid scale type"); + } + + { + // Dump concrete ranges for axis buckets + f->open_array_section("ranges"); + auto ranges = get_axis_bucket_ranges(ac); + for (int i = 0; i < ac.m_buckets; ++i) { + f->open_object_section("bucket"); + if (i > 0) { + f->dump_int("min", ranges[i].first); + } + if (i < ac.m_buckets - 1) { + f->dump_int("max", ranges[i].second); + } + f->close_section(); + } + f->close_section(); + } + + f->close_section(); +} + +int64_t get_quants(int64_t i, PerfHistogramCommon::scale_type_d st) { + switch (st) { + case PerfHistogramCommon::SCALE_LINEAR: + return i; + case PerfHistogramCommon::SCALE_LOG2: + return int64_t(1) << (i - 1); + } + assert(false && "Invalid scale type"); +} + +int64_t PerfHistogramCommon::get_bucket_for_axis( + int64_t value, const PerfHistogramCommon::axis_config_d &ac) { + if (value < ac.m_min) { + return 0; + } + + value -= ac.m_min; + value /= ac.m_quant_size; + + switch (ac.m_scale_type) { + case SCALE_LINEAR: + return std::min(value + 1, ac.m_buckets - 1); + + case SCALE_LOG2: + for (int64_t i = 1; i < ac.m_buckets; ++i) { + if (value < get_quants(i, SCALE_LOG2)) { + return i; + } + } + return ac.m_buckets - 1; + } + assert(false && "Invalid scale type"); +} + +std::vector> +PerfHistogramCommon::get_axis_bucket_ranges( + const PerfHistogramCommon::axis_config_d &ac) { + std::vector> ret; + ret.resize(ac.m_buckets); + + // First bucket is for value < min + int64_t min = ac.m_min; + for (int64_t i = 1; i < ac.m_buckets - 1; i++) { + int64_t max_exclusive = + ac.m_min + get_quants(i, ac.m_scale_type) * ac.m_quant_size; + + // Dump bucket range + ret[i].first = min; + ret[i].second = max_exclusive - 1; + + // Shift min to next bucket + min = max_exclusive; + } + + // Fill up first and last element, note that in case m_buckets == 1 + // those will point to the same element, the order is important here + ret.front().second = ac.m_min - 1; + ret.back().first = min; + + ret.front().first = std::numeric_limits::min(); + ret.back().second = std::numeric_limits::max(); + return ret; +}