diff --git a/include/ircd/m/event/refs.h b/include/ircd/m/event/refs.h index aa0602091..5b63ccb1d 100644 --- a/include/ircd/m/event/refs.h +++ b/include/ircd/m/event/refs.h @@ -11,15 +11,25 @@ #pragma once #define HAVE_IRCD_M_EVENT_REFS_H +namespace ircd::m::dbs +{ + enum class ref :uint8_t; +} + struct ircd::m::event::refs { event::idx idx; public: - using closure_bool = event::closure_idx_bool; + using closure_bool = std::function; + bool for_each(const dbs::ref &type, const closure_bool &) const; bool for_each(const closure_bool &) const; + + bool has(const dbs::ref &type, const event::idx &) const noexcept; bool has(const event::idx &) const noexcept; + + size_t count(const dbs::ref &type) const noexcept; size_t count() const noexcept; refs(const event::idx &idx) noexcept; diff --git a/ircd/m_event.cc b/ircd/m_event.cc index 645aed738..6b118bdce 100644 --- a/ircd/m_event.cc +++ b/ircd/m_event.cc @@ -1390,37 +1390,14 @@ ircd::m::event::auth::refs::for_each(const string_view &type, const { assert(idx); - thread_local char buf[dbs::EVENT_REFS_KEY_MAX_SIZE]; - const string_view key + const event::refs erefs { - dbs::event_refs_key(buf, idx, dbs::ref::AUTH, 0) + idx }; - auto it + return erefs.for_each(dbs::ref::AUTH, [this, &type, &closure] + (const event::idx &ref, const dbs::ref &) { - dbs::event_refs.begin(key) - }; - - for(; it; ++it) - { - const auto parts - { - dbs::event_refs_key(it->first) - }; - - const auto &ref_type - { - std::get<0>(parts) - }; - - const auto &ref - { - std::get<1>(parts) - }; - - if(ref_type != dbs::ref::AUTH) - break; - bool match; const auto matcher { @@ -1433,18 +1410,18 @@ const if(type) { if(!m::get(std::nothrow, ref, "type", matcher)) - continue; + return true; if(!match) - continue; + return true; } assert(idx != ref); if(!closure(ref)) return false; - } - return true; + return true; + }); } // @@ -1515,10 +1492,18 @@ ircd::m::event::refs::rebuild() size_t ircd::m::event::refs::count() const noexcept +{ + return count(dbs::ref(-1)); +} + +size_t +ircd::m::event::refs::count(const dbs::ref &type) +const noexcept { assert(idx); size_t ret(0); - for_each([&ret](const auto &) + for_each(type, [&ret] + (const event::idx &ref, const dbs::ref &) { ++ret; return true; @@ -1531,7 +1516,16 @@ bool ircd::m::event::refs::has(const event::idx &idx) const noexcept { - return !for_each([&idx](const event::idx &ref) + return has(dbs::ref(-1), idx); +} + +bool +ircd::m::event::refs::has(const dbs::ref &type, + const event::idx &idx) +const noexcept +{ + return !for_each(type, [&idx] + (const event::idx &ref, const dbs::ref &) { return ref != idx; // true to continue, false to break }); @@ -1540,12 +1534,27 @@ const noexcept bool ircd::m::event::refs::for_each(const closure_bool &closure) const +{ + return for_each(dbs::ref(-1), closure); +} + +bool +ircd::m::event::refs::for_each(const dbs::ref &type, + const closure_bool &closure) +const { assert(idx); thread_local char buf[dbs::EVENT_REFS_KEY_MAX_SIZE]; + + // Allow -1 to iterate through all types by starting + // the iteration at type value 0 and then ignoring the + // type as a loop continue condition. + const bool all_type(type == dbs::ref(uint8_t(-1))); + const auto &_type{all_type? dbs::ref::PREV : type}; + assert(uint8_t(dbs::ref::PREV) == 0); const string_view key { - dbs::event_refs_key(buf, idx, dbs::ref::PREV, 0) + dbs::event_refs_key(buf, idx, _type, 0) }; auto it @@ -1565,7 +1574,7 @@ const std::get<0>(parts) }; - if(type != dbs::ref::PREV) + if(!all_type && type != _type) break; const auto &ref @@ -1574,7 +1583,7 @@ const }; assert(idx != ref); - if(!closure(ref)) + if(!closure(ref, type)) return false; } diff --git a/modules/console.cc b/modules/console.cc index 326c3f82f..488a082a5 100644 --- a/modules/console.cc +++ b/modules/console.cc @@ -5625,34 +5625,19 @@ console_cmd__event(opt &out, const string_view &line) out << "- UNAUTHORIZED: " << failmsg << std::endl; if(m::event::auth::is_power_event(event)) - { out << "+ POWER EVENT" << std::endl; - const m::event::auth::refs &refs{event_idx}; - const auto refcnt(refs.count()); - if(refcnt) - { - out << std::endl; - out << "+ AUTH REFERENCED " << refcnt << std::endl; - refs.for_each([&out](const m::event::idx &idx) - { - const m::event::fetch event{idx}; - out << " " << idx << " " << pretty_oneline(event) << std::endl; - return true; - }); - } - } - const m::event::refs &refs{event_idx}; const auto refcnt(refs.count()); if(refcnt) { out << std::endl; out << "+ REFERENCED " << refs.count() << std::endl; - refs.for_each([&out](const m::event::idx &idx) + refs.for_each([&out] + (const m::event::idx &idx, const auto &type) { const m::event::fetch event{idx}; - out << " " << idx << " " << pretty_oneline(event) << std::endl; + out << " " << reflect(type) << " " << idx << " " << pretty_oneline(event) << std::endl; return true; }); } @@ -5947,6 +5932,58 @@ console_cmd__event__refs__rebuild(opt &out, const string_view &line) bool console_cmd__event__refs(opt &out, const string_view &line) { + const params param{line, " ", + { + "event_id", "type" + }}; + + const m::event::id &event_id + { + param.at("event_id") + }; + + const m::event::refs refs + { + index(event_id) + }; + + const string_view &typestr + { + param.at("type") + }; + + m::dbs::ref type + { + empty(typestr)? + m::dbs::ref(-1): + m::dbs::ref(0) + + }; + + if(!empty(typestr)) + for(; uint8_t(type) < sizeof(m::dbs::ref) * 8; type = m::dbs::ref(uint8_t(type) + 1)) + if(reflect(type) == typestr) + break; + + refs.for_each(type, [&out] + (const auto &idx, const auto &type) + { + const m::event::fetch event + { + idx, std::nothrow + }; + + if(!event.valid) + return true; + + out << idx + << " " << m::event_id(idx) + << " " << reflect(type) + << std::endl; + + return true; + }); + return true; } @@ -5968,7 +6005,8 @@ console_cmd__event__refs__prev(opt &out, const string_view &line) index(event_id) }; - refs.for_each([&out](const m::event::idx &idx) + refs.for_each(m::dbs::ref::PREV, [&out] + (const auto &idx, const auto &type) { const m::event::fetch event { @@ -5980,6 +6018,7 @@ console_cmd__event__refs__prev(opt &out, const string_view &line) out << idx << " " << m::event_id(idx) + << " " << reflect(type) << std::endl; return true;