z3-z3-4.13.0.src.util.statistics.cpp Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
statistics.h
Abstract:
Wrapper for reporting statistics
Author:
Leonardo (leonardo) 2011-05-17
Notes:
--*/
#include "util/statistics.h"
#include "util/map.h"
#include "util/str_hashtable.h"
#include "util/buffer.h"
#include "util/smt2_util.h"
#include
void statistics::update(char const * key, unsigned inc) {
if (inc != 0)
m_stats.push_back(key_val_pair(key, inc));
}
void statistics::update(char const * key, double inc) {
if (inc != 0.0)
m_d_stats.push_back(key_d_val_pair(key, inc));
}
void statistics::copy(statistics const & st) {
m_stats.append(st.m_stats);
m_d_stats.append(st.m_d_stats);
}
void statistics::reset() {
m_stats.reset();
m_d_stats.reset();
}
template
static void mk_map(V const & v, M & m) {
for (auto const& p : v) {
typename V::data_t::second_type val;
if (m.find(p.first, val))
m.insert(p.first, p.second + val);
else
m.insert(p.first, p.second);
}
}
template
static void get_keys(M const & m, ptr_buffer & keys) {
for (auto const& kv : m)
keys.push_back(const_cast(kv.m_key));
}
static void display_smt2_key(std::ostream & out, char const * key) {
SASSERT(key != 0);
out << ":";
if (*key == ':')
key++;
while (*key) {
if (is_smt2_simple_symbol_char(*key))
out << *key;
else
out << "-";
key++;
}
}
struct str_lt {
bool operator()(char const * s1, char const * s2) const { return strcmp(s1, s2) < 0; }
};
typedef map key2val;
typedef map key2dval;
unsigned get_max_len(ptr_buffer & keys) {
unsigned max = 0;
for (unsigned i = 0; i < static_cast(keys.size()); i++) {
char * k = keys.get(i);
if (*k == ':')
k++;
unsigned curr = static_cast(strlen(k));
if (curr > max)
max = curr;
}
return max;
}
std::ostream& statistics::display_smt2(std::ostream & out) const {
#define INIT_DISPLAY() \
key2val m_u; \
key2dval m_d; \
mk_map(m_stats, m_u); \
mk_map(m_d_stats, m_d); \
ptr_buffer keys; \
get_keys(m_u, keys); \
get_keys(m_d, keys); \
std::sort(keys.begin(), keys.end(), str_lt()); \
unsigned max = get_max_len(keys);
INIT_DISPLAY();
bool first = true;
#define DISPLAY_KEY() { \
if (!first) \
out << "\n "; \
display_smt2_key(out, k); \
unsigned len = static_cast(strlen(k)); \
for (unsigned j = len; j < max; j++) \
out << " "; \
first = false; \
}
out << "(";
for (unsigned i = 0; i < keys.size(); i++) {
char * k = keys.get(i);
unsigned val;
if (m_u.find(k, val)) {
DISPLAY_KEY();
out << " " << val;
}
else {
double d_val = 0.0;
m_d.find(k, d_val);
DISPLAY_KEY();
out << " " << std::fixed << std::setprecision(2) << d_val;
}
}
out << ")\n";
return out;
}
std::ostream& statistics::display(std::ostream & out) const {
INIT_DISPLAY();
#undef DISPLAY_KEY
#define DISPLAY_KEY() { \
if (*k == ':') \
k++; \
out << k << ":"; \
unsigned len = static_cast(strlen(k)); \
for (unsigned j = len; j < max; j++) \
out << " "; \
}
for (unsigned i = 0; i < keys.size(); i++) {
char * k = keys.get(i);
unsigned val;
if (m_u.find(k, val)) {
DISPLAY_KEY();
out << " " << val << "\n";
}
else {
double d_val = 0.0;
m_d.find(k, d_val);
DISPLAY_KEY();
out << " " << std::fixed << std::setprecision(2) << d_val << "\n";
}
}
return out;
}
template
static void display_internal(std::ostream & out, M const & m) {
for (auto const& kv : m) {
char const * key = kv.m_key;
if (*key == ':') key++;
while (*key) {
if ('a' <= *key && *key <= 'z')
out << ('A' + (*key - 'a'));
else if (*key == ' ')
out << "_";
else
out << *key;
}
out << " " << kv.m_value << "\n";
}
}
void statistics::display_internal(std::ostream & out) const {
key2val m_u;
key2dval m_d;
mk_map(m_stats, m_u);
mk_map(m_d_stats, m_d);
::display_internal(out, m_u);
::display_internal(out, m_d);
}
unsigned statistics::size() const {
return m_stats.size() + m_d_stats.size();
}
bool statistics::is_uint(unsigned idx) const {
return idx < m_stats.size();
}
char const * statistics::get_key(unsigned idx) const {
if (is_uint(idx))
return m_stats[idx].first;
else
return m_d_stats[idx - m_stats.size()].first;
}
unsigned statistics::get_uint_value(unsigned idx) const {
SASSERT(idx < size());
SASSERT(is_uint(idx));
return m_stats[idx].second;
}
double statistics::get_double_value(unsigned idx) const {
SASSERT(idx < size());
SASSERT(!is_uint(idx));
return m_d_stats[idx - m_stats.size()].second;
}
static void get_uint64_stats(statistics& st, char const* name, unsigned long long value) {
if (value <= UINT_MAX) {
st.update(name, static_cast(value));
}
else {
st.update(name, static_cast(value));
}
}
void get_memory_statistics(statistics& st) {
unsigned long long max_mem = memory::get_max_used_memory();
unsigned long long mem = memory::get_allocation_size();
max_mem = (100*max_mem)/(1024*1024);
mem = (100*mem)/(1024*1024);
st.update("max memory", static_cast(max_mem)/100.0);
st.update("memory", static_cast(mem)/100.0);
get_uint64_stats(st, "num allocs", memory::get_allocation_count());
}
void get_rlimit_statistics(reslimit& l, statistics& st) {
get_uint64_stats(st, "rlimit count", l.count());
}