summaryrefslogtreecommitdiff
path: root/src/util/statistics_value.cpp
blob: 6db0b3cd3a395ce6e1080b1243475d5285f0c485 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*********************                                                        */
/*! \file statistics_value.cpp
 ** \verbatim
 ** Top contributors (to current version):
 **   Gereon Kremer
 ** This file is part of the CVC4 project.
 ** Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
 ** in the top-level source directory and their institutional affiliations.
 ** All rights reserved.  See the file COPYING in the top-level source
 ** directory for licensing information.\endverbatim
 **
 ** \brief Statistic data classes
 **
 ** The statistic data classes that actually hold the data for the statistics.
 **
 ** Conceptually, every statistic consists of a data object and a proxy object.
 ** The data objects (statistic values) are derived from `StatisticBaseValue`
 ** and live in the `StatisticsRegistry`.
 ** They are solely exported to the proxy objects, which should be the sole
 ** way to manipulate the data of a data object.
 ** The data objects themselves need to implement printing (normal and safe) and
 ** conversion to the API type `Stat`.
 **/

#include "util/statistics_value.h"

#include "util/ostream_util.h"

namespace cvc5 {

// standard helper, see https://en.cppreference.com/w/cpp/utility/variant/visit
template <class... Ts>
struct overloaded : Ts...
{
  using Ts::operator()...;
};
template <class... Ts>
overloaded(Ts...) -> overloaded<Ts...>;

namespace detail {
std::ostream& print(std::ostream& out, const StatExportData& sed)
{
  std::visit(overloaded{
                 [&out](std::monostate v) { out << "<unset>"; },
                 [&out](int64_t v) { out << v; },
                 [&out](uint64_t v) { out << v; },
                 [&out](double v) { out << v; },
                 [&out](const std::string& v) { out << v; },
                 [&out](const std::map<std::string, uint64_t>& v) {
                   out << "{ ";
                   bool first = true;
                   for (const auto& e : v)
                   {
                     if (!first)
                       out << ", ";
                     else
                       first = false;
                     out << e.first << ": " << e.second;
                   }
                   out << " }";
                 },
             },
             sed);
  return out;
}
}

StatisticBaseValue::~StatisticBaseValue() {}

std::ostream& operator<<(std::ostream& out, const StatisticBaseValue& sbv)
{
  return detail::print(out, sbv.hasValue() ? sbv.getViewer() : StatExportData{});
}

StatExportData StatisticAverageValue::getViewer() const { return get(); }

bool StatisticAverageValue::hasValue() const { return d_count > 0; }

void StatisticAverageValue::print(std::ostream& out) const { out << get(); }

void StatisticAverageValue::printSafe(int fd) const
{
  safe_print<double>(fd, get());
}

double StatisticAverageValue::get() const { return d_sum / d_count; }

StatExportData StatisticTimerValue::getViewer() const
{
  return static_cast<int64_t>(get() / std::chrono::milliseconds(1));
}

bool StatisticTimerValue::hasValue() const
{
  return d_running || d_duration.count() > 0;
}

void StatisticTimerValue::print(std::ostream& out) const
{
  StreamFormatScope format_scope(out);
  duration dur = get();

  out << (dur / std::chrono::seconds(1)) << "." << std::setfill('0')
      << std::setw(9) << std::right << (dur % std::chrono::seconds(1)).count();
}

void StatisticTimerValue::printSafe(int fd) const
{
  duration dur = get();
  safe_print<uint64_t>(fd, dur / std::chrono::seconds(1));
  safe_print(fd, ".");
  safe_print_right_aligned(fd, (dur % std::chrono::seconds(1)).count(), 9);
}

/** Make sure that we include the time of a currently running timer */
StatisticTimerValue::duration StatisticTimerValue::get() const
{
  auto data = d_duration;
  if (d_running)
  {
    data += clock::now() - d_start;
  }
  return data;
}

}  // namespace cvc5
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback