From be9df8bfa22cf5a7164f4f3deba44cdbd2b8e7cf Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Thu, 2 Mar 2017 02:00:41 +0100 Subject: Implement a default destructor to avoid the automatic inlining of large destructors. --- metrics/src/vespa/metrics/CMakeLists.txt | 1 + metrics/src/vespa/metrics/printutils.cpp | 275 +++++++++++++++++++++++++++++++ metrics/src/vespa/metrics/printutils.h | 248 +++------------------------- 3 files changed, 299 insertions(+), 225 deletions(-) create mode 100644 metrics/src/vespa/metrics/printutils.cpp (limited to 'metrics/src') diff --git a/metrics/src/vespa/metrics/CMakeLists.txt b/metrics/src/vespa/metrics/CMakeLists.txt index cd5a5ba4629..f93c1fb63c8 100644 --- a/metrics/src/vespa/metrics/CMakeLists.txt +++ b/metrics/src/vespa/metrics/CMakeLists.txt @@ -13,6 +13,7 @@ vespa_add_library(metrics metrictimer.cpp metricvalueset.cpp namehash.cpp + printutils.cpp state_api_adapter.cpp summetric.cpp textwriter.cpp diff --git a/metrics/src/vespa/metrics/printutils.cpp b/metrics/src/vespa/metrics/printutils.cpp new file mode 100644 index 00000000000..c28b74885d6 --- /dev/null +++ b/metrics/src/vespa/metrics/printutils.cpp @@ -0,0 +1,275 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "printutils.h" + +namespace metrics { +namespace printutils { + +typedef std::pair LongValue; +typedef std::pair DoubleValue; + +MetricSource::MetricSource(const MetricSnapshot& s, + const String& metricsPrefix, + std::map* metricsAccessed) + : _snapshot(s), + _metricsPrefix(metricsPrefix), + _metricsAccessedOwner(), + _metricsAccessed(metricsAccessed == 0 ? _metricsAccessedOwner + : *metricsAccessed) + { + } + + Metric::String + MetricSource::createAbsoluteMetricName(const String& name) const { + String prefix = _metricsPrefix; + String addition = name; + while (addition.find("../") == 0) { + String::size_type pos1 = prefix.rfind('.'); + if (pos1 == String::npos) + throw vespalib::IllegalArgumentException( + "Cannot go back anymore in path " + prefix, + VESPA_STRLOC); + prefix = prefix.substr(0, pos1); + addition = addition.substr(3); + } + return (prefix.empty() ? addition : prefix + "." + addition); + } + + MetricSource::SourceMetricVisitor::SourceMetricVisitor(const String& path, bool prefixMatch) + : _stringPath(path), + _path(vespalib::StringTokenizer(path, ".").getTokens()), + _pathIndex(-1), + _resultMetric(), + _prefixMatch(prefixMatch), + _prefixMatches() + { + } + +MetricSource::SourceMetricVisitor::~SourceMetricVisitor() { } + + void + MetricSource::SourceMetricVisitor::checkForPrefixMatch(const Metric& metric) { + if (metric.getName().size() >= _path[_pathIndex].size()) { + if (metric.getName().find(_path[_pathIndex]) == 0) { + _prefixMatches.push_back(metric.getName()); + } + } + } + + bool + MetricSource::SourceMetricVisitor::visitMetricSet(const MetricSet& set, bool) { + if (_pathIndex == -1) { + _pathIndex = 0; + return true; + } + if (_prefixMatch + && static_cast(_pathIndex + 1) == _path.size()) + { + for (const Metric * entry : set.getRegisteredMetrics()) { + checkForPrefixMatch(*entry); + } + return false; + } + if (set.getName() != _path[_pathIndex]) return false; + if (static_cast(++_pathIndex) >= _path.size()) { + throw vespalib::IllegalArgumentException( + "Path " + _stringPath + " points to a metric set. " + "Only primitive metrics can be retrieved.", + VESPA_STRLOC); + } + return true; + } + bool + MetricSource::SourceMetricVisitor::visitMetric(const Metric& metric, bool) { + if (_prefixMatch) { + checkForPrefixMatch(metric); + } + if (_path[_pathIndex] != metric.getName()) { + return true; + } + if (_prefixMatch) { + throw vespalib::IllegalArgumentException( + "Cannot find existing entries with prefix " + + _stringPath + " since element " + metric.getName() + + " is not a metric set", VESPA_STRLOC); + } + if (static_cast(_pathIndex + 1) < _path.size()) { + throw vespalib::IllegalArgumentException( + "Path " + _stringPath + " cannot exist since element " + + _path[_pathIndex] + " is not a metric set: " + + metric.toString(), + VESPA_STRLOC); + } + std::vector ownerList; + _resultMetric.reset(metric.clone(ownerList, Metric::INACTIVE, 0)); + if (!ownerList.empty()) { + throw vespalib::IllegalArgumentException( + "Metric " + metric.getName() + " added entries to " + "owners list when cloning. This should not happen " + "for primitive metrics.", VESPA_STRLOC); + } + return false; + } + + const Metric* + MetricSource::getMetric(const String& name) { + String path = createAbsoluteMetricName(name); + std::map::const_iterator it( + _metricsAccessed.find(path)); + if (it != _metricsAccessed.end()) { + return it->second.get(); + } + SourceMetricVisitor visitor(path, false); + _snapshot.getMetrics().visit(visitor); + if (visitor._resultMetric.get() == 0) { + throw vespalib::IllegalArgumentException( + "Metric " + path + " was not found.", VESPA_STRLOC); + } + Metric::SP metric(visitor._resultMetric.release()); + _metricsAccessed[path] = metric; + return metric.get(); + } + + std::vector + MetricSource::getPathsMatchingPrefix(const String& prefix) const + { + String path = createAbsoluteMetricName(prefix); + SourceMetricVisitor visitor(path, true); + _snapshot.getMetrics().visit(visitor); + return visitor._prefixMatches; + } + +// Addition functions. Ensure that if floating point value is used, +// result ends up as floating point too. +LongValue operator+(LongValue addend1, LongValue addend2) +{ + return LongValue(addend1.first + addend2.first, + addend1.second && addend2.second); +} + +// Subtraction functions. Ensure that if floating point value is used, +// result ends up as floating point too. +LongValue operator-(LongValue minuend, LongValue subtrahend) +{ + return LongValue(minuend.first - subtrahend.first, + minuend.second && subtrahend.second); +} + +// Multiplication functions. Ensure that if floating point value is used, +// result ends up as floating point too. + +LongValue operator*(LongValue factor1, LongValue factor2) +{ + return std::pair(factor1.first * factor2.first, + factor1.second && factor2.second); +} + +// Division functions. Ensure that if floating point value is used, +// result ends up as floating point too. + +LongValue operator/(LongValue dividend, LongValue divisor) +{ + if (dividend.first == 0) return LongValue( + 0, dividend.second && divisor.second); + if (divisor.first == 0) return LongValue( + std::numeric_limits().max(), + dividend.second && divisor.second); + return LongValue(dividend.first / divisor.first, + dividend.second && divisor.second); +} + +/** Get metric with given name from source. Set bool true if existing. */ +LongValue getLongMetric(const std::string& name, MetricSource& source) +{ + std::string::size_type pos = name.rfind('.'); + const Metric* metric = (pos == std::string::npos + ? 0 : source.getMetric(name.substr(0, pos))); + try{ + return LongValue(metric == 0 + ? 0 : metric->getLongValue(name.substr(pos+1)), metric != 0); + } catch (vespalib::IllegalArgumentException& e) { + return LongValue(0, false); + } +} + +/** Get metric with given name from source. Set bool true if existing. */ +DoubleValue getDoubleMetric(const std::string& name, MetricSource& source) +{ + std::string::size_type pos = name.rfind('.'); + const Metric* metric = (pos == std::string::npos + ? 0 : source.getMetric(name.substr(0, pos))); + try{ + return DoubleValue(metric == 0 + ? 0.0 : metric->getDoubleValue(name.substr(pos+1)), metric != 0); + } catch (vespalib::IllegalArgumentException& e) { + return DoubleValue(0, false); + } +} + +std::string getValueString(LongValue value, const char* format) +{ + if (!value.second) return "na"; + std::vector buffer(30); + snprintf(&buffer[0], 30, format, value.first); + return std::string(&buffer[0]); +} + +std::string getValueString(DoubleValue value, const char* format) +{ + if (!value.second) return "na"; + std::vector buffer(30); + snprintf(&buffer[0], 30, format, value.first); + return std::string(&buffer[0]); +} + + HttpTable::HttpTable(const std::string& title_, const std::string& topLeftText_) + : title(title_), topLeftText(topLeftText_) + {} + HttpTable::~HttpTable() { } + + HttpTable::Row& + HttpTable::operator[](uint32_t i) { + if (i >= cells.size()) cells.resize(i + 1); + return cells[i]; + } + + void + HttpTable::fillInEmptyHoles() { + if (rowNames.size() < cells.size()) rowNames.resize(cells.size()); + if (rowNames.size() > cells.size()) cells.resize(rowNames.size()); + for (uint32_t i=0; i cells[i].cells.size()) + cells[i].cells.resize(colNames.size()); + } + } + + void + HttpTable::print(std::ostream& out) { + out << "

" << title << "

\n"; + out << "\n"; + fillInEmptyHoles(); + for (uint32_t i=0; i<=rowNames.size(); ++i) { + if (i == 0) { + out << ""; + for (uint32_t j=0; j" << colNames[j] << ""; + } + out << "\n"; + } else { + out << ""; + for (uint32_t j=0; j" + << (cells[i - 1][j].set ? cells[i - 1][j].value : "-") + << ""; + } + out << "\n"; + } + } + out << "
" << topLeftText << "
" << rowNames[i - 1] << "
\n"; + } + +} // printutils +} // metrics + diff --git a/metrics/src/vespa/metrics/printutils.h b/metrics/src/vespa/metrics/printutils.h index 10925864824..17562e7e064 100644 --- a/metrics/src/vespa/metrics/printutils.h +++ b/metrics/src/vespa/metrics/printutils.h @@ -32,29 +32,9 @@ struct MetricSource { MetricSource(const MetricSnapshot& s, const String& metricsPrefix, - std::map* metricsAccessed = 0) - : _snapshot(s), - _metricsPrefix(metricsPrefix), - _metricsAccessedOwner(), - _metricsAccessed(metricsAccessed == 0 ? _metricsAccessedOwner - : *metricsAccessed) - { - } - - String createAbsoluteMetricName(const String& name) const { - String prefix = _metricsPrefix; - String addition = name; - while (addition.find("../") == 0) { - String::size_type pos1 = prefix.rfind('.'); - if (pos1 == String::npos) - throw vespalib::IllegalArgumentException( - "Cannot go back anymore in path " + prefix, - VESPA_STRLOC); - prefix = prefix.substr(0, pos1); - addition = addition.substr(3); - } - return (prefix.empty() ? addition : prefix + "." + addition); - } + std::map* metricsAccessed = 0); + ~MetricSource(); + String createAbsoluteMetricName(const String& name) const; struct SourceMetricVisitor : public metrics::MetricVisitor { String _stringPath; @@ -64,115 +44,25 @@ struct MetricSource { bool _prefixMatch; std::vector _prefixMatches; - SourceMetricVisitor(const String& path, bool prefixMatch) - : _stringPath(path), - _path(vespalib::StringTokenizer(path, ".").getTokens()), - _pathIndex(-1), - _resultMetric(), - _prefixMatch(prefixMatch), - _prefixMatches() - { - } + SourceMetricVisitor(const String& path, bool prefixMatch); + ~SourceMetricVisitor(); - void checkForPrefixMatch(const Metric& metric) { - if (metric.getName().size() >= _path[_pathIndex].size()) { - if (metric.getName().find(_path[_pathIndex]) == 0) { - _prefixMatches.push_back(metric.getName()); - } - } - } + void checkForPrefixMatch(const Metric& metric); - bool visitMetricSet(const MetricSet& set, bool) { - if (_pathIndex == -1) { - _pathIndex = 0; - return true; - } - if (_prefixMatch - && static_cast(_pathIndex + 1) == _path.size()) - { - for (const Metric * entry : set.getRegisteredMetrics()) { - checkForPrefixMatch(*entry); - } - return false; - } - if (set.getName() != _path[_pathIndex]) return false; - if (static_cast(++_pathIndex) >= _path.size()) { - throw vespalib::IllegalArgumentException( - "Path " + _stringPath + " points to a metric set. " - "Only primitive metrics can be retrieved.", - VESPA_STRLOC); - } - return true; - } + bool visitMetricSet(const MetricSet& set, bool); void doneVisitingMetricSet(const MetricSet&) { --_pathIndex; } - bool visitMetric(const Metric& metric, bool) { - if (_prefixMatch) { - checkForPrefixMatch(metric); - } - if (_path[_pathIndex] != metric.getName()) { - return true; - } - if (_prefixMatch) { - throw vespalib::IllegalArgumentException( - "Cannot find existing entries with prefix " - + _stringPath + " since element " + metric.getName() - + " is not a metric set", VESPA_STRLOC); - } - if (static_cast(_pathIndex + 1) < _path.size()) { - throw vespalib::IllegalArgumentException( - "Path " + _stringPath + " cannot exist since element " - + _path[_pathIndex] + " is not a metric set: " - + metric.toString(), - VESPA_STRLOC); - } - std::vector ownerList; - _resultMetric.reset(metric.clone(ownerList, Metric::INACTIVE, 0)); - if (!ownerList.empty()) { - throw vespalib::IllegalArgumentException( - "Metric " + metric.getName() + " added entries to " - "owners list when cloning. This should not happen " - "for primitive metrics.", VESPA_STRLOC); - } - return false; - } - + bool visitMetric(const Metric& metric, bool); }; - const Metric* getMetric(const String& name) { - String path = createAbsoluteMetricName(name); - std::map::const_iterator it( - _metricsAccessed.find(path)); - if (it != _metricsAccessed.end()) { - return it->second.get(); - } - SourceMetricVisitor visitor(path, false); - _snapshot.getMetrics().visit(visitor); - if (visitor._resultMetric.get() == 0) { - throw vespalib::IllegalArgumentException( - "Metric " + path + " was not found.", VESPA_STRLOC); - } - Metric::SP metric(visitor._resultMetric.release()); - _metricsAccessed[path] = metric; - return metric.get(); - } + const Metric* getMetric(const String& name); std::vector - getPathsMatchingPrefix(const String& prefix) const - { - String path = createAbsoluteMetricName(prefix); - SourceMetricVisitor visitor(path, true); - _snapshot.getMetrics().visit(visitor); - return visitor._prefixMatches; - } + getPathsMatchingPrefix(const String& prefix) const; }; // Addition functions. Ensure that if floating point value is used, // result ends up as floating point too. -LongValue operator+(LongValue addend1, LongValue addend2) -{ - return LongValue(addend1.first + addend2.first, - addend1.second && addend2.second); -} +LongValue operator+(LongValue addend1, LongValue addend2); template DoubleValue operator+(std::pair addend1, @@ -184,11 +74,7 @@ DoubleValue operator+(std::pair addend1, // Subtraction functions. Ensure that if floating point value is used, // result ends up as floating point too. -LongValue operator-(LongValue minuend, LongValue subtrahend) -{ - return LongValue(minuend.first - subtrahend.first, - minuend.second && subtrahend.second); -} +LongValue operator-(LongValue minuend, LongValue subtrahend); template DoubleValue operator-(std::pair minuend, @@ -201,11 +87,7 @@ DoubleValue operator-(std::pair minuend, // Multiplication functions. Ensure that if floating point value is used, // result ends up as floating point too. -LongValue operator*(LongValue factor1, LongValue factor2) -{ - return std::pair(factor1.first * factor2.first, - factor1.second && factor2.second); -} +LongValue operator*(LongValue factor1, LongValue factor2); template DoubleValue operator*(std::pair factor1, @@ -218,16 +100,7 @@ DoubleValue operator*(std::pair factor1, // Division functions. Ensure that if floating point value is used, // result ends up as floating point too. -LongValue operator/(LongValue dividend, LongValue divisor) -{ - if (dividend.first == 0) return LongValue( - 0, dividend.second && divisor.second); - if (divisor.first == 0) return LongValue( - std::numeric_limits().max(), - dividend.second && divisor.second); - return LongValue(dividend.first / divisor.first, - dividend.second && divisor.second); -} +LongValue operator/(LongValue dividend, LongValue divisor); template DoubleValue operator/(std::pair dividend, @@ -276,49 +149,10 @@ typedef VW LVW; typedef VW DVW; -/** Get metric with given name from source. Set bool true if existing. */ -LongValue getLongMetric(const std::string& name, MetricSource& source) -{ - std::string::size_type pos = name.rfind('.'); - const Metric* metric = (pos == std::string::npos - ? 0 : source.getMetric(name.substr(0, pos))); - try{ - return LongValue(metric == 0 - ? 0 : metric->getLongValue(name.substr(pos+1)), metric != 0); - } catch (vespalib::IllegalArgumentException& e) { - return LongValue(0, false); - } -} - -/** Get metric with given name from source. Set bool true if existing. */ -DoubleValue getDoubleMetric(const std::string& name, MetricSource& source) -{ - std::string::size_type pos = name.rfind('.'); - const Metric* metric = (pos == std::string::npos - ? 0 : source.getMetric(name.substr(0, pos))); - try{ - return DoubleValue(metric == 0 - ? 0.0 : metric->getDoubleValue(name.substr(pos+1)), metric != 0); - } catch (vespalib::IllegalArgumentException& e) { - return DoubleValue(0, false); - } -} - -std::string getValueString(LongValue value, const char* format = "%'lld") -{ - if (!value.second) return "na"; - std::vector buffer(30); - snprintf(&buffer[0], 30, format, value.first); - return std::string(&buffer[0]); -} - -std::string getValueString(DoubleValue value, const char* format = "%'f") -{ - if (!value.second) return "na"; - std::vector buffer(30); - snprintf(&buffer[0], 30, format, value.first); - return std::string(&buffer[0]); -} +LongValue getLongMetric(const std::string& name, MetricSource& source); +DoubleValue getDoubleMetric(const std::string& name, MetricSource& source); +std::string getValueString(LongValue value, const char* format = "%'lld"); +std::string getValueString(DoubleValue value, const char* format = "%'f"); template std::string getByteValueString(std::pair val) @@ -367,48 +201,12 @@ struct HttpTable { }; std::vector cells; - HttpTable(const std::string& title_, const std::string& topLeftText_) - : title(title_), topLeftText(topLeftText_) {} - - Row& operator[](uint32_t i) { - if (i >= cells.size()) cells.resize(i + 1); - return cells[i]; - } - - void fillInEmptyHoles() { - if (rowNames.size() < cells.size()) rowNames.resize(cells.size()); - if (rowNames.size() > cells.size()) cells.resize(rowNames.size()); - for (uint32_t i=0; i cells[i].cells.size()) - cells[i].cells.resize(colNames.size()); - } - } + HttpTable(const std::string& title_, const std::string& topLeftText_); + ~HttpTable(); - void print(std::ostream& out) { - out << "

" << title << "

\n"; - out << "\n"; - fillInEmptyHoles(); - for (uint32_t i=0; i<=rowNames.size(); ++i) { - if (i == 0) { - out << ""; - for (uint32_t j=0; j" << colNames[j] << ""; - } - out << "\n"; - } else { - out << ""; - for (uint32_t j=0; j" - << (cells[i - 1][j].set ? cells[i - 1][j].value : "-") - << ""; - } - out << "\n"; - } - } - out << "
" << topLeftText << "
" << rowNames[i - 1] << "
\n"; - } + Row& operator[](uint32_t i); + void fillInEmptyHoles(); + void print(std::ostream& out); }; } // printutils -- cgit v1.2.3