
The test may fail if the client/maxscale/mariadb combo is too slow. TODO, maybe: today I saw mysql_query() hang (in a poll) when maxscale disconnected. Is there something that can be done about that? I added a source directory, base, for stuff that should become part of a common utility library in the future.
149 lines
3.7 KiB
C++
149 lines
3.7 KiB
C++
/*
|
|
* Copyright (c) 2018 MariaDB Corporation Ab
|
|
*
|
|
* Use of this software is governed by the Business Source License included
|
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
|
|
*
|
|
* Change Date: 2020-01-01
|
|
*
|
|
* On the date above, in accordance with the Business Source License, use
|
|
* of this software will be governed by version 2 or later of the General
|
|
* Public License.
|
|
*/
|
|
|
|
#include "stopwatch.h"
|
|
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <ctime>
|
|
|
|
namespace base
|
|
{
|
|
|
|
StopWatch::StopWatch()
|
|
{
|
|
restart();
|
|
}
|
|
|
|
Duration StopWatch::lap() const
|
|
{
|
|
return {Clock::now() - m_start};
|
|
}
|
|
|
|
Duration StopWatch::restart()
|
|
{
|
|
TimePoint now = Clock::now();
|
|
Duration lap = now - m_start;
|
|
m_start = now;
|
|
return lap;
|
|
}
|
|
} // base
|
|
|
|
/********** OUTPUT ***********/
|
|
namespace
|
|
{
|
|
using namespace base;
|
|
struct TimeConvert
|
|
{
|
|
double div; // divide the value of the previous unit by this
|
|
std::string suffix; // milliseconds, hours etc.
|
|
double max_visual; // threashold to switch to the next unit
|
|
};
|
|
// Will never get to centuries because the duration is a long carrying nanoseconds
|
|
TimeConvert convert[]
|
|
{
|
|
{1, "ns", 1000}, {1000, "us", 1000}, {1000, "ms", 1000},
|
|
{1000, "s", 60}, {60, "min", 60}, {60, "hours", 24},
|
|
{24, "days", 365.25}, {365.25, "years", 10000},
|
|
{100, "centuries", std::numeric_limits<double>::max()}
|
|
};
|
|
|
|
int convert_size = sizeof(convert) / sizeof(convert[0]);
|
|
|
|
}
|
|
|
|
namespace base
|
|
{
|
|
std::pair<double, std::string> dur_to_human_readable(Duration dur)
|
|
{
|
|
using namespace std::chrono;
|
|
double time = duration_cast<nanoseconds>(dur).count();
|
|
bool negative = (time < 0) ? time = -time, true : false;
|
|
|
|
for (int i = 0; i <= convert_size; ++i)
|
|
{
|
|
if (i == convert_size)
|
|
{
|
|
return std::make_pair(negative ? -time : time,
|
|
convert[convert_size - 1].suffix);
|
|
}
|
|
|
|
time /= convert[i].div;
|
|
|
|
if (time < convert[i].max_visual)
|
|
{
|
|
return std::make_pair(negative ? -time : time, convert[i].suffix);
|
|
}
|
|
}
|
|
|
|
abort(); // should never get here
|
|
}
|
|
|
|
std::ostream& operator<<(std::ostream& os, Duration dur)
|
|
{
|
|
auto p = dur_to_human_readable(dur);
|
|
os << p.first << p.second;
|
|
|
|
return os;
|
|
}
|
|
|
|
// TODO: this will require some thought. time_point_to_string() for a system_clock is
|
|
// obvious, but not so for a steady_clock. Maybe TimePoint belongs to a system clock
|
|
// and sould be called something else here, and live in a time_measuring namespace.
|
|
std::string time_point_to_string(TimePoint tp, const std::string &fmt)
|
|
{
|
|
using namespace std::chrono;
|
|
std::time_t timet = system_clock::to_time_t(system_clock::now()
|
|
+ (tp - Clock::now()));
|
|
struct tm * ptm;
|
|
ptm = gmtime(&timet);
|
|
const int sz = 1024;
|
|
char buf[sz];
|
|
strftime(buf, sz, fmt.c_str(), ptm);
|
|
return buf;
|
|
}
|
|
|
|
std::ostream & operator<<(std::ostream & os, TimePoint tp)
|
|
{
|
|
os << time_point_to_string(tp);
|
|
return os;
|
|
}
|
|
|
|
void test_stopwatch_output(std::ostream & os)
|
|
{
|
|
long long dur[] =
|
|
{
|
|
400, // 400ns
|
|
5 * 1000, // 5us
|
|
500 * 1000, // 500us
|
|
1 * 1000000, // 1ms
|
|
700 * 1000000LL, // 700ms
|
|
5 * 1000000000LL, // 5s
|
|
200 * 1000000000LL, // 200s
|
|
5 * 60 * 1000000000LL, // 5m
|
|
45 * 60 * 1000000000LL, // 45m
|
|
130 * 60 * 1000000000LL, // 130m
|
|
24 * 60 * 60 * 1000000000LL, // 24 hours
|
|
3 * 24 * 60 * 60 * 1000000000LL, // 72 hours
|
|
180 * 24 * 60 * 60 * 1000000000LL, // 180 days
|
|
1000 * 24 * 60 * 60 * 1000000000LL // 1000 days
|
|
};
|
|
|
|
for (unsigned i = 0; i < sizeof(dur) / sizeof(dur[0]); ++i)
|
|
{
|
|
os << Duration(dur[i]) << std::endl;
|
|
}
|
|
}
|
|
} // base
|