From 0241f2b9a109d3a395f7cdfc844b4924c0ef1aa7 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Wed, 11 Sep 2019 10:03:10 -0700 Subject: [PATCH] ircd::m::room::members: Add host argument to interface stack for more efficient queries. --- include/ircd/m/room/members.h | 6 +- ircd/m_room.cc | 127 ++++++++++++++++++++++++---------- modules/console.cc | 41 +++++++++-- 3 files changed, 129 insertions(+), 45 deletions(-) diff --git a/include/ircd/m/room/members.h b/include/ircd/m/room/members.h index fc7fdae1b..1ab2e2c31 100644 --- a/include/ircd/m/room/members.h +++ b/include/ircd/m/room/members.h @@ -26,17 +26,21 @@ struct ircd::m::room::members m::room room; - bool for_each_join_present(const closure &) const; + bool for_each_join_present(const string_view &host, const closure &) const; public: + bool for_each(const string_view &membership, const string_view &host, const closure &) const; + bool for_each(const string_view &membership, const string_view &host, const closure_idx &) const; bool for_each(const string_view &membership, const closure &) const; bool for_each(const string_view &membership, const closure_idx &) const; bool for_each(const closure &) const; bool for_each(const closure_idx &) const; + bool empty(const string_view &membership, const string_view &host) const; bool empty(const string_view &membership) const; bool empty() const; + size_t count(const string_view &membership, const string_view &host) const; size_t count(const string_view &membership) const; size_t count() const; diff --git a/ircd/m_room.cc b/ircd/m_room.cc index 3dc2be1f2..d131e872c 100644 --- a/ircd/m_room.cc +++ b/ircd/m_room.cc @@ -2990,14 +2990,23 @@ bool ircd::m::room::members::empty() const { - return empty(string_view{}); + return empty(string_view{}, string_view{}); } bool ircd::m::room::members::empty(const string_view &membership) const { - return for_each(membership, closure{[](const auto &) + return empty(membership, string_view{}); +} + +bool +ircd::m::room::members::empty(const string_view &membership, + const string_view &host) +const +{ + return for_each(membership, host, closure{[] + (const user::id &user_id) { return false; }}); @@ -3007,16 +3016,24 @@ size_t ircd::m::room::members::count() const { - return count(string_view{}); + return count(string_view{}, string_view{}); } size_t ircd::m::room::members::count(const string_view &membership) const +{ + return count(membership, string_view{}); +} + +size_t +ircd::m::room::members::count(const string_view &membership, + const string_view &host) +const { size_t ret{0}; - this->for_each(membership, room::members::closure{[&ret] - (const id::user &) + for_each(membership, host, closure{[&ret] + (const user::id &user_id) { ++ret; return true; @@ -3041,6 +3058,51 @@ const bool ircd::m::room::members::for_each(const string_view &membership, + const closure &closure) +const +{ + return for_each(membership, string_view{}, closure); +} + +bool +ircd::m::room::members::for_each(const string_view &membership, + const closure_idx &closure) +const +{ + return for_each(membership, string_view{}, closure); +} + +bool +ircd::m::room::members::for_each(const string_view &membership, + const string_view &host, + const closure &closure) +const +{ + const m::room::state state + { + room + }; + + const bool present + { + state.present() + }; + + // joined members optimization. Only possible when seeking + // membership="join" on the present state of the room. + if(membership == "join" && present) + return for_each_join_present(host, closure); + + return this->for_each(membership, host, [&closure] + (const auto &user_id, const auto &event_idx) + { + return closure(user_id); + }); +} + +bool +ircd::m::room::members::for_each(const string_view &membership, + const string_view &host, const closure_idx &closure) const { @@ -3057,7 +3119,7 @@ const // joined members optimization. Only possible when seeking // membership="join" on the present state of the room. if(membership == "join" && present) - return for_each_join_present([&closure, &state] + return for_each_join_present(host, [&closure, &state] (const id::user &user_id) { const auto &event_idx @@ -3084,44 +3146,26 @@ const return true; }); - return state.for_each("m.room.member", [this, &membership, &closure] + return state.for_each("m.room.member", [this, &host, &membership, &closure] (const string_view &type, const string_view &state_key, const event::idx &event_idx) { + const m::user::id &user_id + { + state_key + }; + + if(host && user_id.host() != host) + return true; + return !membership || this->membership(event_idx, membership)? - closure(state_key, event_idx): + closure(user_id, event_idx): true; }); } bool -ircd::m::room::members::for_each(const string_view &membership, - const closure &closure) -const -{ - const m::room::state state - { - room - }; - - const bool present - { - state.present() - }; - - // joined members optimization. Only possible when seeking - // membership="join" on the present state of the room. - if(membership == "join" && present) - return for_each_join_present(closure); - - return this->for_each(membership, [&closure] - (const auto &user_id, const auto &event_idx) - { - return closure(user_id); - }); -} - -bool -ircd::m::room::members::for_each_join_present(const closure &closure) +ircd::m::room::members::for_each_join_present(const string_view &host, + const closure &closure) const { db::domain &index @@ -3129,9 +3173,15 @@ const dbs::room_joined }; + char keybuf[dbs::ROOM_JOINED_KEY_MAX_SIZE]; + const string_view &key + { + dbs::room_joined_key(keybuf, room.room_id, host) + }; + auto it { - index.begin(room.room_id) + index.begin(key) }; for(; bool(it); ++it) @@ -3141,6 +3191,9 @@ const dbs::room_joined_key(it->first) }; + if(host && origin != host) + break; + if(!closure(user_id)) return false; } diff --git a/modules/console.cc b/modules/console.cc index 549f1ec52..576259b50 100644 --- a/modules/console.cc +++ b/modules/console.cc @@ -7792,13 +7792,33 @@ console_cmd__room__top(opt &out, const string_view &line) char version_buf[32], display_buf[256]; out << "display name: " << m::display_name(display_buf, room_id) << std::endl; + out << "creator: " << m::creator(room_id) << std::endl; out << "version: " << m::version(version_buf, room_id) << std::endl; - out << "joined: " << m::room::members{room_id}.count("join") << std::endl; - out << "remote joined: " << std::boolalpha << m::remote_joined(room_id) << std::endl; - out << "local joined: " << std::boolalpha << m::local_joined(room_id) << std::endl; + out << "internal: " << m::internal(room_id) << std::endl; out << "local only: " << std::boolalpha << m::local_only(room_id) << std::endl; + out << "local joined: " << std::boolalpha << m::local_joined(room_id) << std::endl; + out << "remote joined: " << std::boolalpha << m::remote_joined(room_id) << std::endl; out << std::endl; + const m::room::members members(room_id); + out << "invite: " << std::setw(7) << members.count("invite") + << std::endl + << "invite local: " << std::setw(7) << members.count("invite", my_host()) + << std::endl + << "join: " << std::setw(7) << members.count("join") + << std::endl + << "join local: " << std::setw(7) << members.count("join", my_host()) + << std::endl + << "leave: " << std::setw(7) << members.count("leave") + << std::endl + << "leave local: " << std::setw(7) << members.count("leave", my_host()) + << std::endl + << "ban: " << std::setw(7) << members.count("ban") + << std::endl + << "ban local: " << std::setw(7) << members.count("ban", my_host()) + << std::endl + << std::endl; + out << "servers: " << m::room::origins{room_id}.count() << std::endl; out << "servers up: " << m::room::origins{room_id}.count_online() << std::endl; out << "servers err: " << m::room::origins{room_id}.count_error() << std::endl; @@ -8566,7 +8586,7 @@ console_cmd__room__members(opt &out, const string_view &line) { const params param{line, " ", { - "room_id", "[membership]" + "room_id", "[membership]" "[host]" }}; const auto &room_id @@ -8576,7 +8596,14 @@ console_cmd__room__members(opt &out, const string_view &line) const string_view &membership { - param[1] + param[1] != "\"\""? + param[1]: + string_view{} + }; + + const string_view &host + { + param[2] }; const m::room room @@ -8591,7 +8618,7 @@ console_cmd__room__members(opt &out, const string_view &line) if(membership) { - members.for_each(membership, [&out, &membership] + members.for_each(membership, host, [&out, &membership] (const m::user::id &user_id) { out << std::setw(8) << std::left << membership @@ -8603,7 +8630,7 @@ console_cmd__room__members(opt &out, const string_view &line) return true; } - members.for_each(membership, [&out] + members.for_each(membership, host, [&out] (const m::user::id &user_id, const m::event::idx &event_idx) { char buf[32];