Skip to content

Commit

Permalink
With all the publisher stuff in place
Browse files Browse the repository at this point in the history
  • Loading branch information
kmaragon committed Aug 10, 2018
1 parent 71f449d commit 4756fc9
Show file tree
Hide file tree
Showing 45 changed files with 1,438 additions and 339 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage")
link_libraries(gcov)
endif()

add_subdirectory(src)
add_subdirectory(cxxmetrics)
add_subdirectory(test)
4 changes: 3 additions & 1 deletion src/CMakeLists.txt → cxxmetrics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ set(HEADERS
metric_value.hpp
metrics_registry.hpp
pool.hpp
publisher.hpp
publisher_impl.hpp
ringbuf.hpp
simple_reservoir.hpp
skiplist.hpp
Expand All @@ -41,7 +43,7 @@ set(HEADERS
)

add_library(cxxmetrics INTERFACE)
target_include_directories(cxxmetrics INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
target_include_directories(cxxmetrics INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/../")
target_sources_local(cxxmetrics INTERFACE ${HEADERS})
target_link_libraries(cxxmetrics INTERFACE atomic CONAN_PKG::ctti)

Expand Down
File renamed without changes.
File renamed without changes.
67 changes: 34 additions & 33 deletions src/ewma.hpp → cxxmetrics/ewma.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,20 @@ class ewma
using clock_diff = typename clock_traits<TClockGet>::clock_diff;

private:
TClockGet clk_;
static long double alpha_;

TClockGet clk_;
std::atomic<TValue> rate_;
clock_point last_;
std::atomic<TValue> pending_;

static constexpr double get_alpha()
{
return 1 - exp((TInterval * -1.0l) / (TWindow * 1.0l));
return 1 - exp((TInterval * -1.0l) / (TWindow * 2.0l));
}

void tick(const clock_point &at) noexcept;
template<bool TWrite = true>
TValue tick(const clock_point &at) noexcept;

public:
ewma(const TClockGet &clock = TClockGet()) noexcept;
Expand Down Expand Up @@ -139,20 +141,16 @@ void ewma<TClockGet, TWindow, TInterval, TValue>::mark(TMark amount) noexcept
if (now < last_)
return;

// See if we crossed the interval threshold. If so we need to tick
if (last_ != clock_point{})
if (last_ == clock_point{})
{
if ((now - last_) >= period(TInterval))
tick(now);
atomic_add(pending_, amount);
tick(now);
}
else
{
// the clock hasn't started yet - add the item to pending and attempt to tick
atomic_add(pending_, amount);
tick(now);
atomic_add(pending_, amount);
}

}

template<typename TClockGet, period::value TWindow, period::value TInterval, typename TValue>
Expand All @@ -165,49 +163,47 @@ template<typename TClockGet, period::value TWindow, period::value TInterval, typ
TValue ewma<TClockGet, TWindow, TInterval, TValue>::rate() noexcept
{
auto now = clk_();

// See if we crossed the interval threshold. If so we need to tick
if (last_ != clock_point{} && now > last_ && (now - last_) >= period(TInterval))
tick(now);

return rate_.load();
return tick(now);
}

template<typename TClockGet, period::value TWindow, period::value TInterval, typename TValue>
TValue ewma<TClockGet, TWindow, TInterval, TValue>::rate() const noexcept
{
auto rate = rate_.load();
if (rate < 0)
return 0;

return rate;
auto now = clk_();
// the const_cast is safe with the false template parameter
return const_cast<ewma*>(this)->tick<false>(now);
}

template<typename TClockGet, period::value TWindow, period::value TInterval, typename TValue>
void ewma<TClockGet, TWindow, TInterval, TValue>::tick(const clock_point &at) noexcept
template<bool TWrite>
TValue ewma<TClockGet, TWindow, TInterval, TValue>::tick(const clock_point &at) noexcept
{
int missed_intervals;
clock_point last;

auto pending = pending_.load();
last = last_;

auto pending = pending_.load();
auto nrate = rate_.load();
last = last_;
if (last == clock_point{})
{
// one thread sets the last timestamp
if (!pending_.compare_exchange_strong(pending, 0))
return; // someone else ticked from under us
// use constexpr if with 17
if (TWrite)
{
// one thread sets the last timestamp
if (!pending_.compare_exchange_strong(pending, 0))
return pending; // someone else ticked from under us

if (rate_.compare_exchange_weak(nrate, pending))
last_ = at;
if (rate_.compare_exchange_weak(nrate, pending))
last_ = at;
}

return;
return pending;
}

// make sure that last_ didn't catch up with us
if ((at - last) < period(TInterval))
return;
if ((at < last) || (at - last) < period(TInterval))
return nrate;

// apply the pending value to our current rate
// if someone else already snagged the pending value, start over
Expand All @@ -234,12 +230,17 @@ void ewma<TClockGet, TWindow, TInterval, TValue>::tick(const clock_point &at) no
rate = rate + (alpha_ * -rate);
}

if (!TWrite)
return rate;

if (!pending_.compare_exchange_strong(pending, 0))
return; // someone else already either ticked or added a pending value
return rate; // someone else already either ticked or added a pending value

rate_.store(rate);
if (last_ < at)
last_ = at;

return rate;
}

template<typename TClockGet, period::value TWindow, period::value TInterval, typename TValue>
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/gauge.hpp → cxxmetrics/gauge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ struct default_metric_builder<cxxmetrics::gauge<TGaugeType *, TAggregation>>
cxxmetrics::gauge<TGaugeType*, TAggregation> operator()() const
{
static TGaugeType *r = nullptr;
return cxxmetrics::gauge<TGaugeType, TAggregation>(r);
return cxxmetrics::gauge<TGaugeType*, TAggregation>(r);
}
};

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
144 changes: 144 additions & 0 deletions cxxmetrics/meta.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#ifndef CXXMETRICS_META_HPP
#define CXXMETRICS_META_HPP

namespace cxxmetrics
{

namespace templates
{

using sortable_template_type = unsigned long long;

template <sortable_template_type ... TElems>
struct sortable_template_collection;

template<typename ...T>
struct static_concat;

template<sortable_template_type ... TLeft, sortable_template_type ... TRight, typename ... TTail>
struct static_concat<sortable_template_collection<TLeft...>, sortable_template_collection<TRight...>, TTail...>
{
using type = typename static_concat<sortable_template_collection<TLeft..., TRight...>, TTail...>::type;
};

template<sortable_template_type ... TColl>
struct static_concat<sortable_template_collection<TColl...>>
{
using type = sortable_template_collection<TColl...>;
};

template<bool, typename TTrue, typename TFalse>
struct static_if_else;

template<typename TTrue, typename TFalse>
struct static_if_else<true, TTrue, TFalse>
{
using type = TTrue;
};

template<typename TTrue, typename TFalse>
struct static_if_else<false, TTrue, TFalse>
{
using type = TFalse;
};

template<sortable_template_type TLeft, sortable_template_type TRight>
struct is_less
{
static constexpr bool value = (TLeft < TRight);
};

template<sortable_template_type TLeft, sortable_template_type TRight>
struct is_greater
{
static constexpr bool value = (TLeft > TRight);
};

template<sortable_template_type TLeft, sortable_template_type TRight>
struct are_equal
{
static constexpr bool value = (TLeft == TRight);
};

template<typename TData>
struct static_partition;

template<sortable_template_type TPivot, sortable_template_type THead, sortable_template_type ...TData>
struct static_partition<sortable_template_collection<TPivot, THead, TData...>>
{
private:
using left_ = typename static_partition<sortable_template_collection<TPivot, TData...>>::left;
using middle_ = typename static_partition<sortable_template_collection<TPivot, TData...>>::middle;
using right_ = typename static_partition<sortable_template_collection<TPivot, TData...>>::right;
public:
using left = typename static_if_else<is_less<THead, TPivot>::value, typename static_concat<sortable_template_collection<THead>, left_>::type, left_>::type;
using middle = typename static_if_else<are_equal<THead, TPivot>::value, typename static_concat<sortable_template_collection<THead>, middle_>::type, middle_>::type;
using right = typename static_if_else<is_greater<THead, TPivot>::value, typename static_concat<sortable_template_collection<THead>, right_>::type, right_>::type;
};

template<sortable_template_type TPivot>
struct static_partition<sortable_template_collection<TPivot>>
{
using left = sortable_template_collection<>;
using middle = sortable_template_collection<TPivot>;
using right = sortable_template_collection<>;
};

template<typename TData>
struct static_sorter;

template<sortable_template_type...TData>
struct static_sorter<sortable_template_collection<TData...>>
{
private:
using partitioned_ = static_partition<sortable_template_collection<TData...>>;

using left_ = typename static_sorter<typename partitioned_::left>::type;
using middle_ = typename partitioned_::middle;
using right_ = typename static_sorter<typename partitioned_::right>::type;
public:
using type = typename static_concat<left_, middle_, right_>::type;
};

template<>
struct static_sorter<sortable_template_collection<>>
{
using type = sortable_template_collection<>;
};

template<typename TData>
struct static_uniq;

template<sortable_template_type TFirst, sortable_template_type TSecond, sortable_template_type ...TTail>
struct static_uniq<sortable_template_collection<TFirst, TSecond, TTail...>>
{
using type = typename static_if_else<are_equal<TFirst, TSecond>::value, typename static_uniq<sortable_template_collection<TFirst, TTail...>>::type, typename static_concat<sortable_template_collection<TFirst>, typename static_uniq<sortable_template_collection<TSecond, TTail...>>::type>::type>::type;
};

template<sortable_template_type TFirst>
struct static_uniq<sortable_template_collection<TFirst>>
{
using type = sortable_template_collection<TFirst>;
};

template<>
struct static_uniq<sortable_template_collection<>>
{
using type = sortable_template_collection<>;
};

template<sortable_template_type ... durations>
struct sort_unique
{
private:
using list_ = sortable_template_collection<durations...>;
using sorted_ = typename static_sorter<list_>::type;
public:
using type = typename static_uniq<sorted_>::type;
};

} // templates

} // cxxmetrics

#endif //CXXMETRICS_META_HPP
2 changes: 1 addition & 1 deletion src/meter.hpp → cxxmetrics/meter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ template<period::value TInterval, typename TWindows>
class meter_builder;

template<period::value TInterval, period::value ...TWindows>
class meter_builder<TInterval, templates::duration_collection<TWindows...>> : public meter<TInterval, TWindows...>
class meter_builder<TInterval, templates::sortable_template_collection<TWindows...>> : public meter<TInterval, TWindows...>
{
public:
meter_builder() = default;
Expand Down
File renamed without changes.
6 changes: 3 additions & 3 deletions src/metric_path.hpp → cxxmetrics/metric_path.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class metric_path
}
};

std::string metric_path::join(const std::string &delim) const
inline std::string metric_path::join(const std::string &delim) const
{
if (paths_.empty())
return "";
Expand All @@ -100,7 +100,7 @@ std::string metric_path::join(const std::string &delim) const
return result;
}

bool metric_path::operator==(const cxxmetrics::metric_path &other) const
inline bool metric_path::operator==(const cxxmetrics::metric_path &other) const
{
if (paths_.size() != other.paths_.size())
return false;
Expand All @@ -114,7 +114,7 @@ bool metric_path::operator==(const cxxmetrics::metric_path &other) const
return true;
}

bool metric_path::operator!=(const cxxmetrics::metric_path &other) const
inline bool metric_path::operator!=(const cxxmetrics::metric_path &other) const
{
return !(operator==(other));
}
Expand Down
File renamed without changes.
Loading

0 comments on commit 4756fc9

Please sign in to comment.