MXS-1777 Create new utility library
The purpose of this library is to create a utility library that is not dependent on maxscale for use in both maxscale and system test, and possibly other apps. As time permits general purpose utilities from maxscale-common can be moved to the new library. Here are answers to questions you may have: - A top level directory "maxutils" contains the libraries. The current structure is simply maxutils/maxbase. Each library has an 'include' and a 'scr' directory where public headers exist in 'include' - Code is in a namespace with the same name as the directory. - Headers are included like this: `#include <maxbase/stopwatch.hh>` - In case the library is published on its own, the include directives stay the same (headers would be in /usr/include/maxutil, for example). - I am not advocating many small libraries. But if some larger library is written, say a general purpose statemachine, it would not pollute util/maxutil but go to util/maxsm. Another example: Worker. It is a larger concept, but used so widely in code that it could very well live in maxutil. NOTE: this was previously Review Request #6245.
This commit is contained in:
111
maxutils/maxbase/include/maxbase/eventcount.hh
Normal file
111
maxutils/maxbase/include/maxbase/eventcount.hh
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <maxbase/stopwatch.hh>
|
||||
#include <iosfwd>
|
||||
#include <vector>
|
||||
|
||||
namespace maxbase
|
||||
{
|
||||
/**
|
||||
* @brief Keep a count of an events for a time period from "now" into the past.
|
||||
*
|
||||
* Events are stored, or distinguished, with timestamps of a given granularity.
|
||||
* For example, if the granularity is set to 1s, each time an event is reported the current
|
||||
* time is rounded down to the nearest whole second. All events that round down to the same
|
||||
* second share a single entry in the EventCount. Granularity==0 causes all events (timestamps)
|
||||
* to be stored in their own entry, which could use large amounts of memory.
|
||||
*
|
||||
*/
|
||||
class EventCount
|
||||
{
|
||||
public:
|
||||
EventCount(const EventCount&) = delete;
|
||||
EventCount& operator=(const EventCount&) = delete;
|
||||
explicit EventCount(const std::string& event_id, Duration time_window,
|
||||
Duration granularity = Duration(std::chrono::milliseconds(10)));
|
||||
EventCount(EventCount&&); // can't be defaulted in gcc 4.4
|
||||
EventCount& operator=(EventCount&&); // can't be defaulted in gcc 4.4
|
||||
|
||||
const std::string& event_id() const
|
||||
{
|
||||
return m_event_id;
|
||||
}
|
||||
Duration time_window() const
|
||||
{
|
||||
return m_time_window;
|
||||
}
|
||||
void dump(std::ostream& os) const;
|
||||
int count() const;
|
||||
void increment();
|
||||
|
||||
// these defs need not be public once lambdas are available
|
||||
struct Timestamp
|
||||
{
|
||||
TimePoint time_point;
|
||||
int count;
|
||||
Timestamp(TimePoint p, int c) : time_point(p), count(c) {}
|
||||
};
|
||||
private:
|
||||
void purge() const; // remove out of window stats
|
||||
|
||||
std::string m_event_id;
|
||||
Duration m_time_window;
|
||||
Duration::rep m_granularity;
|
||||
mutable std::vector<Timestamp> m_timestamps;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const EventCount& stats);
|
||||
|
||||
// Time series statistics for a Session (a collection of related EventCount).
|
||||
class SessionCount
|
||||
{
|
||||
public:
|
||||
SessionCount(const SessionCount&) = delete;
|
||||
SessionCount& operator=(const SessionCount&) = delete;
|
||||
SessionCount(const std::string& sess_id, Duration time_window,
|
||||
Duration granularity = Duration(std::chrono::milliseconds(10)));
|
||||
SessionCount(SessionCount &&); // can't be defaulted in gcc 4.4
|
||||
SessionCount& operator=(SessionCount&&); // can't be defaulted in gcc 4.4
|
||||
|
||||
const std::string& session_id() const
|
||||
{
|
||||
return m_sess_id;
|
||||
}
|
||||
Duration time_window() const
|
||||
{
|
||||
return m_time_window;
|
||||
}
|
||||
const std::vector<EventCount>& event_counts() const;
|
||||
void dump(std::ostream& os) const;
|
||||
bool empty() const; // no stats
|
||||
|
||||
void increment(const std::string& event_id);
|
||||
private:
|
||||
void purge() const; // remove out of window stats
|
||||
|
||||
std::string m_sess_id;
|
||||
Duration m_time_window;
|
||||
Duration m_granularity;
|
||||
mutable int m_cleanup_countdown;
|
||||
mutable std::vector<EventCount> m_event_counts;
|
||||
};
|
||||
|
||||
// conveniece. Any real formatted output should go elsewhere.
|
||||
std::ostream& operator<<(std::ostream& os, const SessionCount& stats);
|
||||
void dump(std::ostream& os, const std::vector<SessionCount>& sessions);
|
||||
void dumpTotals(std::ostream& os, const std::vector<SessionCount> &sessions);
|
||||
|
||||
} // maxbase
|
61
maxutils/maxbase/include/maxbase/stopwatch.hh
Normal file
61
maxutils/maxbase/include/maxbase/stopwatch.hh
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
namespace maxbase
|
||||
{
|
||||
|
||||
#if __cplusplus >= 201103
|
||||
typedef std::chrono::steady_clock Clock;
|
||||
#else
|
||||
typedef std::chrono::system_clock Clock;
|
||||
#endif
|
||||
|
||||
struct Duration : public Clock::duration // for ADL
|
||||
{
|
||||
// gcc 4.4 does not inherit constructors, so this is a bit limited.
|
||||
Duration() = default;
|
||||
Duration(long long l) : Clock::duration(l) {}
|
||||
Duration(Clock::duration d) : Clock::duration(d) {}
|
||||
};
|
||||
|
||||
typedef std::chrono::time_point<Clock, Duration> TimePoint;
|
||||
|
||||
class StopWatch
|
||||
{
|
||||
public:
|
||||
// Starts the stopwatch, which is always running.
|
||||
StopWatch();
|
||||
// Get elapsed time.
|
||||
Duration lap() const;
|
||||
// Get elapsed time, restart StopWatch.
|
||||
Duration restart();
|
||||
private:
|
||||
TimePoint m_start;
|
||||
};
|
||||
|
||||
// Returns the value as a double and string adjusted to a suffix like ms for milliseconds.
|
||||
std::pair<double, std::string> dur_to_human_readable(Duration dur);
|
||||
|
||||
// Human readable output. No standard library for it yet.
|
||||
std::ostream& operator<<(std::ostream&, Duration dur);
|
||||
|
||||
// TimePoint
|
||||
std::string time_point_to_string(TimePoint tp, const std::string& fmt = "%F %T");
|
||||
std::ostream& operator<<(std::ostream&, TimePoint tp);
|
||||
|
||||
} // maxbase
|
Reference in New Issue
Block a user