Flow 2.0.0
Flow project: Full implementation reference.
Classes | Namespaces | Macros | Functions
stat_set.hpp File Reference
#include "flow/util/stat/stat_fwd.hpp"
#include "flow/util/string_view.hpp"
#include "flow/util/util_fwd.hpp"
#include <boost/core/noncopyable.hpp>
#include <ostream>
#include <atomic>
#include <cassert>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

Go to the source code of this file.

Classes

struct  flow::util::stat::Stat_set_printable< Stat_set >
 Thin proxy wrapping a const reference to a Stat_set, enabling ostream << stat::print(my_stats) syntax. More...
 
class  flow::util::stat::Stat_name
 Specialized class that (at a light weight) represents a printable Stat_set-member name, or fragment thereof, by storing concatenated sub-fragments in rope-like fashion, so that certain relatively expensive yet rarely needed operations (given that stat-member names are used only for things like pretty-printing) are executed only when actually needed. More...
 

Namespaces

namespace  flow
 Catch-all namespace for the Flow project: A collection of various production-quality modules written in modern C++17, originally by ygoldfel.
 
namespace  flow::util
 Flow module containing miscellaneous general-use facilities that don't fit into any other Flow module.
 
namespace  flow::util::stat
 Sub-module of flow::util providing lightweight facilities for working with simple structs of stat counters/gauges/etc.
 

Macros

#define FLOW_UTIL_STAT_DECLARE(ARG_m_stat, ARG_stat_type)
 Declares an individual Stat_set-stat-member to be tracked in flow::util::stat::stats_*() APIs, except for stats with Stat_type::S_HI_WMARK. More...
 
#define FLOW_UTIL_STAT_DECLARE_HI_WMARK(ARG_m_stat, ARG_m_gauged_stat)
 Declares an individual Stat_set-stat-member of Stat_type::S_HI_WMARK to be tracked in flow::util::stat::stats_*() APIs. More...
 

Functions

template<typename T >
const T & flow::util::stat::load (const T &val)
 Default load(stats.m_val) that simply return stats.m_val. More...
 
template<typename T >
T flow::util::stat::load (const std::atomic< T > &val)
 load(stats.m_val) that loads a copy of the value stored inside an atomic<T> stats.m_val. More...
 
template<typename T >
void flow::util::stat::store (T *target_val, const boost::type_identity_t< T > &val)
 Default store(&target_stats.m_val, val) that simply assigns *target_val = val. More...
 
template<typename T >
void flow::util::stat::store (std::atomic< T > *target_val, boost::type_identity_t< T > val)
 store(&target_stats.m_val, val) that stores a copy of val into an atomic<T> target_stats.m_val. More...
 
template<typename T >
void flow::util::stat::fetch_add (T *target_val, const boost::type_identity_t< T > &addend_val)
 Default fetch_add(&target_stats.m_val, addend_val) that simply applies *target_val += addend_val. More...
 
template<typename T >
T flow::util::stat::fetch_add (std::atomic< T > *target_val, boost::type_identity_t< T > addend_val)
 fetch_add(&target_stats.m_val, addend_val) that increments by addend_val value inside atomic<T> target_stats.m_val and returns the pre-change value. More...
 
template<typename T >
void flow::util::stat::fetch_sub (T *target_val, const boost::type_identity_t< T > &subtrahend_val)
 Default fetch_sub(&target_stats.m_val, _val) that simply applies *target_val -= subtrahend_val. More...
 
template<typename T >
T flow::util::stat::fetch_sub (std::atomic< T > *target_val, boost::type_identity_t< T > subtrahend_val)
 fetch_sub(&target_stats.m_val, subtrahend_val) that decrements by subtrahend_val value inside atomic<T> target_stats.m_val and returns the pre-change value. More...
 
template<typename T >
T flow::util::stat::exchange (std::atomic< T > *target_val, boost::type_identity_t< T > val)
 Equivalent to target_val->exchange(val, memory_order_relaxed); sets *target_val to val and returns the pre-change value. More...
 
template<typename T >
void flow::util::stat::update_hi_wmark (T *target_val, const boost::type_identity_t< T > &val)
 Default update_hi_wmark(&target_stats.m_val, val) that updates *target_val to val if and only if the latter exceeds the former. More...
 
template<typename T >
void flow::util::stat::update_hi_wmark (std::atomic< T > *target_val, boost::type_identity_t< T > val)
 update_hi_wmark(&target_stats.m_val, val) that stores copy of val value inside atomic<T> target_stats.m_val if and only if the latter is less-than the former. More...
 
template<typename T >
void flow::util::stat::reset (T *target_val, const T &fresh_val)
 Executes store(*target_val, load(fresh_val)). More...
 
template<typename Stat_set >
void flow::util::stat::stats_to_ostream (std::ostream &os, const Stat_set &stats)
 Outputs a human-readable representation of all declared stats in stats to the given ostream. More...
 
template<typename Stat_set >
Stat_set_printable< Stat_set > flow::util::stat::print (const Stat_set &stats)
 Returns a lightweight proxy object that, when streamed via operator<<, pretty-prints the given Stat_set using stats_to_ostream(). More...
 
template<typename Stat_set , typename... Ctor_args>
std::vector< std::string > flow::util::stat::stats_field_names (Ctor_args &&... ctor_args)
 Returns the names of all declared stats of the given Stat_set type, in declaration order: the same names, in the same order, as in stats_to_ostream() output. More...
 
template<typename Stat_set >
std::ostream & flow::util::stat::operator<< (std::ostream &os, const Stat_set_printable< Stat_set > &printable)
 Prints string representation of the given printable.m_stats to the given ostream via stats_to_ostream(). More...
 
template<typename Stat_set >
void flow::util::stat::stats_reset (Stat_set *target_stats, const Stat_set &fresh_stats)
 With the help of a freshly-initialized Stat_set, resets the target Stat_set so as to immediately begin a fresh measurement period. More...
 
template<typename Stat_set >
void flow::util::stat::stats_assign (Stat_set *target_stats, const Stat_set &src_stats)
 Given a source Stat_set, makes the target Stat_set equal to the former. More...
 
template<typename Stat_set >
void flow::util::stat::stats_aggregate_one (Stat_set *target_stats, const Stat_set &src_stats)
 Aggregates the values from src_stats into *target_stats, in-place. More...
 
template<typename Stat_set , typename It >
void flow::util::stat::stats_aggregate (Stat_set *target_stats, const It &src_stats_begin, const It &src_stats_end)
 Aggregates N source Stat_sets – drawn from the iterator range [src_stats_begin, src_stats_end) – into *target_stats. More...
 
template<typename Stat_set , typename It >
void flow::util::stat::stats_sum (Stat_set *target_stats, const It &src_stats_begin, const It &src_stats_end)
 Equivalent to stats_aggregate() as-if every stat, regardless of its actual stat::Stat_type, is an ACCUMULATOR; that is simply computes the sum via += or equivalent. More...
 
template<typename Stat_set , typename It >
void flow::util::stat::stats_aggregate_shards (Stat_set *target_stats, const It &src_stats_begin, const It &src_stats_end, const Stat_set *fresh_stats_from_0_shards)
 Sharded-stats consumption: Aggregates N source Stat_sets, interpreted as shards of the aggregated whole – drawn from the iterator range [src_stats_begin, src_stats_end) – into *target_stats. More...
 
template<typename Stat_set , typename It >
void flow::util::stat::stats_reset_shard_aggregate (Stat_set *target_stats, const It &src_stats_begin, const It &src_stats_end, const Stat_set &fresh_stats_from_0_shards)
 Reset-stats companion to stats_aggregate_shards(); together the two functions provide support for the (TL-)sharded stat-collection pattern. More...
 
template<typename Stat_set >
void flow::util::stat::stats_since_reset_state (Stat_set *target_stats, Stat_set *reset_state)
 Intended for situations where the source of stat readings – including ACCUMULATORs and not just GAUGEs – is not by continuous sampling but rather by querying a data source (such as a library with its own stats outputs), this obtains a view of *target_stats (also placed back into *target_stats destructively) relative to a past reference point, *reset_state. More...
 
template<typename Stat_set >
void flow::util::stat::stats_mark_reset_state (Stat_set *target_stats)
 Sets each HI_WMARK-declared stat-member in *target_stats to its gauged-stat's current value in *target_stats; required for stats_since_reset_state() algorithm; may be useful otherwise as well. More...
 

Macro Definition Documentation

◆ FLOW_UTIL_STAT_DECLARE

#define FLOW_UTIL_STAT_DECLARE (   ARG_m_stat,
  ARG_stat_type 
)
Value:
( \
using Member_ptr_type = decltype(&target_stats->ARG_m_stat); \
constexpr auto FLOW_UTIL_STAT_DECLARE_stat_type = Stat_type::S_##ARG_stat_type; \
static_assert(FLOW_UTIL_STAT_DECLARE_stat_type != Stat_type::S_HI_WMARK, \
"To declare HI_WMARK stat please use FLOW_UTIL_STAT_DECLARE_HI_WMARK()."); \
visitor(src_stats ? &src_stats->ARG_m_stat : nullptr, \
target_stats ? &target_stats->ARG_m_stat : nullptr, \
static_cast<Member_ptr_type>(nullptr), \
std::integral_constant<Stat_type, FLOW_UTIL_STAT_DECLARE_stat_type>{}, \
::flow::util::stat::Stat_name{name_prefix, #ARG_m_stat, \
::flow::util::stat::Stat_name::Fragment_kind::S_MEMBER_ID}); \
)
Specialized class that (at a light weight) represents a printable Stat_set-member name,...
Definition: stat_set.hpp:239
Stat_type
Describes an individual member of a Stat_set, as decided by the user (you) via FLOW_UTIL_STAT_DECLARE...
Definition: stat_fwd.hpp:732
#define FLOW_UTIL_SEMICOLON_SAFE(ARG_func_macro_definition)
Use this to create a semicolon-safe version of a "void" functional macro definition consisting of at ...
Definition: util_fwd.hpp:1372

Declares an individual Stat_set-stat-member to be tracked in flow::util::stat::stats_*() APIs, except for stats with Stat_type::S_HI_WMARK.

Intended for use inside a declare_stats() function body.

See also
FLOW_UTIL_STAT_DECLARE_HI_WMARK() which is used to declare HI_WMARK-type stats.

Advanced info

This is of interest, we suspect, only if you want to perhaps write your own stats_*()-like function for some custom needs; for example see the doc header for stats_sum() with some relevant discussion.

The macro expands to a call to visitor(...) (as passed-to declare_stats()) for the given data member. visitor() shall expect the following args with the following requirements and semantics. In each case T is the type of the Stat_set member being processed.

  1. const T* src_val: The member of an immutable source const Stat_set* src_stats – src_stats->ARG_m_stat – or null if such is not necessary for the stats_*() op that's invoking declare_stats(), in which case src_stats shall be null to indicate this.
  2. T* target_val: The member of a mutable target Stat_set* target_stats – target_stats->ARG_m_stat – or null if such is not necessary for the stats_*() op that's invoking declare_stats(), in which case target_stats shall be null to indicate this.
  3. nullptr: Ignored here. See FLOW_UTIL_STAT_DECLARE_HI_WMARK().
  4. auto stat_type_tag: The type (accumulator, gauge, etc.) of the member encoded in such a way as to be able to determine said type at compile-time via if constexpr(...stat_type_tag...). It may be ignored if unneeded by the op that's invoking declare_stats(). With this macro this can be any type except HI_WMARK.
  5. const Stat_name& name: The printable name of the member (with name_prefix in front). It is computed only on request – name.str(), name.to_ostream(os), et al – so if unneeded by the op that's invoking declare_stats(), then ignoring it costs nothing. Do not keep it past the visitor() call; see Stat_name.

When writing the visitor() lambda passed to a stats_*() op, start with the signature implied by that list; then for readability consider replacing each ignored arg with auto&& (to avoid clutter and unused-arg warnings or [[maybe_unused]]).

Parameters
ARG_m_statThe data member to declare, written exactly as the member identifier (e.g., m_msg_count or m_rcv.m_n_transmitted).
ARG_stat_typeThe X in "Stat_type::S_X" indicating the kind of stat the data member tracks. Note the Stat_type::S_ fragment is to be omitted.

Definition at line 74 of file stat_set.hpp.

◆ FLOW_UTIL_STAT_DECLARE_HI_WMARK

#define FLOW_UTIL_STAT_DECLARE_HI_WMARK (   ARG_m_stat,
  ARG_m_gauged_stat 
)
Value:
( \
static_assert(std::is_same_v<decltype(&target_stats->ARG_m_stat), \
decltype(&target_stats->ARG_m_gauged_stat)>, \
"The HI_WMARK stat must be the same C++ type as the GAUGEd stat."); \
visitor(src_stats ? &src_stats->ARG_m_stat : nullptr, \
target_stats ? &target_stats->ARG_m_stat : nullptr, \
target_stats ? &target_stats->ARG_m_gauged_stat : nullptr, \
std::integral_constant<Stat_type, Stat_type::S_HI_WMARK>{}, \
::flow::util::stat::Stat_name{name_prefix, #ARG_m_stat, \
::flow::util::stat::Stat_name::Fragment_kind::S_MEMBER_ID}); \
)

Declares an individual Stat_set-stat-member of Stat_type::S_HI_WMARK to be tracked in flow::util::stat::stats_*() APIs.

Intended for use inside a declare_stats() function body.

See also
FLOW_UTIL_STAT_DECLARE() which is used to declare non-HI_WMARK-type stats.

Conventions (recommended)

Convention (order): FLOW_UTIL_STAT_DECLARE() for ARG_m_gauged_stat should immediately precede this FLOW_UTIL_STAT_DECLARE_HI_WMARK() for ARG_m_stat.

Convention (naming): Name the member <gauged_thing>_hi_wmark; e.g., m_n_open_pools is tracked by m_n_open_pools_hi_wmark.

Advanced info

This is of interest, we suspect, only if you want to perhaps write your own stats_*()-like function for some custom needs; for example see the doc header for stats_sum() with some relevant discussion.

Expands to a call to visitor(...) for the given data member. visitor() shall expect the following args with the following requirements and semantics. In each case T is the type of the Stat_set member being processed.

  1. const T* src_val: See FLOW_UTIL_STAT_DECLARE().
  2. T* target_val: See FLOW_UTIL_STAT_DECLARE().
  3. const T* hi_wmark_gauged_target_val: Member of a mutable target Stat_set* target_stats – target_stats->ARG_m_gauged_stat – or null if such is not necessary for the stats_*() op that's invoking declare_stats(), in which case target_stats shall be null to indicate this.
  4. auto stat_type_tag: See FLOW_UTIL_STAT_DECLARE().
  5. const Stat_name& name: See FLOW_UTIL_STAT_DECLARE().

When writing the visitor() lambda... (same as FLOW_UTIL_STAT_DECLARE() doc header says).

Parameters
ARG_m_statThe HI_WMARK-type data member to declare, written exactly as the member identifier (e.g., m_msg_count or m_rcv.m_n_transmitted).
ARG_m_gauged_statThe GAUGE-type data member that is being tracked by the high-water-mark ARG_m_stat.

Definition at line 126 of file stat_set.hpp.