#include #include #include namespace psemek::journal { struct journal::impl { struct table { event_metadata metadata; mutable std::vector events; }; struct table_hash { std::uint64_t operator()(std::string const & name) const noexcept { return std::hash{}(name); } std::uint64_t operator()(table const & table) const noexcept { return std::hash{}(table.metadata.name); } }; struct table_equal { bool operator()(std::string const & name1, table const & table2) const noexcept { return name1 == table2.metadata.name; } bool operator()(table const & table1, table const & table2) const noexcept { return table1.metadata.name == table2.metadata.name; } }; bool enabled = true; util::hash_set tables; void log_event(event const & event) { if (!enabled) return; auto table_it = tables.find(event.metadata.name); if (table_it == tables.end()) table_it = tables.insert(table{event.metadata, {}}).first; table_it->events.push_back(event.data); } std::vector> select() { if (!enabled) return {}; std::vector> result; for (auto const & table : tables) for (auto const & event : table.events) result.push_back({&table.metadata, &event}); std::sort(result.begin(), result.end(), [](auto const & e1, auto const & e2){ return e1.second->time < e2.second->time; }); return result; } }; journal::journal() : pimpl_(make_impl()) {} journal::~journal() = default; bool journal::enabled() const { return impl().enabled; } void journal::set_enabled(bool enabled) { impl().enabled = enabled; } void journal::log_event(event const & event) { impl().log_event(event); } std::vector> journal::select() { return impl().select(); } }