#pragma once #include #include #include #include #include #include #include #include namespace vptyp { static constexpr std::string_view configErrorMsg = "Bruh, incorrect configuration"; class Logger { // helper class for handling worker thread class Worker; using map_type = std::unordered_map>; public: virtual ~Logger(); Logger(); explicit Logger(std::ostream& out); Logger(Logger&) = delete; Logger(Logger&&) = delete; Logger& operator=(Logger&) = delete; Logger& operator=(Logger&&) = delete; /// @return success or not (already configured) bool configure(const std::vector& d); template >> void add(const std::string& field, Metric metric) { auto locked = active.load(std::memory_order_acquire); // auto locked = active; auto it = locked->find(field); if (it == locked->end()) { throw configErrorMsg; // additional 30ns on bench ? } it->second = metric; } bool isConfigured() { return configured == CONFIGURED; } private: friend Worker; enum Configuration { NOT_CONFIGURED, CONFIG_IN_PROGRESS, CONFIGURED }; std::atomic configured{NOT_CONFIGURED}; std::unique_ptr worker; std::shared_ptr m1, m2; std::atomic> active; // impl may use mutex! // std::shared_ptr active; // data race without atomic on swap // operation }; } // namespace vptyp