// Matrix Construct // // Copyright (C) Matrix Construct Developers, Authors & Contributors // Copyright (C) 2016-2019 Jason Volk // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. decltype(ircd::stats::NAME_MAX_LEN) ircd::stats::NAME_MAX_LEN { 127 }; decltype(ircd::stats::items) ircd::stats::items {}; std::ostream & ircd::stats::operator<<(std::ostream &s, const item &item_) { thread_local char tmp[256]; s << string(tmp, item_); return s; } ircd::string_view ircd::stats::string(const mutable_buffer &buf, const item &item_) { if(item_.type == typeid(uint64_t *)) { const auto &item { dynamic_cast &>(item_) }; assert(item.val); return fmt::sprintf { buf, "%lu", *item.val }; } else if(item_.type == typeid(uint32_t *)) { const auto &item { dynamic_cast &>(item_) }; assert(item.val); return fmt::sprintf { buf, "%u", *item.val }; } else if(item_.type == typeid(uint16_t *)) { const auto &item { dynamic_cast &>(item_) }; assert(item.val); return fmt::sprintf { buf, "%u", *item.val }; } else throw error { "Unsupported value type '%s'", item_.type.name(), }; } // // item // // // item::item // ircd::stats::item::item(const std::type_index &type, const json::members &opts) :type { type } ,feature { opts } { const json::string name { this->operator[]("name") }; if(!name) throw error { "Stats item must have a 'name' string feature" }; if(name.size() > NAME_MAX_LEN) throw error { "Stats item '%s' name length:%zu exceeds max:%zu", name, name.size(), NAME_MAX_LEN }; if(!items.emplace(name, this).second) throw error { "Stats item named '%s' already exists", name }; } ircd::stats::item::~item() noexcept { const json::string name { this->operator[]("name") }; if(name) { const auto it { items.find(name) }; assert(data(it->first) == data(name)); items.erase(it); } } ircd::string_view ircd::stats::item::operator[](const string_view &key) const noexcept { const json::object feature { this->feature }; return feature[key]; } // // pointer-to-value items // // // item // ircd::stats::item::item(uint64_t *const &val, const json::members &feature) :item { typeid(uint64_t *), feature } ,val { val } { } // // item // ircd::stats::item::item(uint32_t *const &val, const json::members &feature) :item { typeid(uint32_t *), feature } ,val { val } { } // // item // ircd::stats::item::item(uint16_t *const &val, const json::members &feature) :item { typeid(uint16_t *), feature } ,val { val } { } // // value-carrying items // // // item // ircd::stats::item::item(const json::members &feature) :item { std::addressof(this->val), feature } ,val { 0UL } { } // // item // ircd::stats::item::item(const json::members &feature) :item { std::addressof(this->val), feature } ,val { 0U } { } // // item // ircd::stats::item::item(const json::members &feature) :item { std::addressof(this->val), feature } ,val { 0U } { }