From bdc88e6c7e899462fc607fcafff319efe98afb6c Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Fri, 19 Jul 2019 13:56:08 -0700 Subject: [PATCH] imrcd::m::room::members: Add empty() to interface. --- include/ircd/m/room/members.h | 3 ++ ircd/m_room.cc | 58 +++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/include/ircd/m/room/members.h b/include/ircd/m/room/members.h index 31fe49fce..5049b03c4 100644 --- a/include/ircd/m/room/members.h +++ b/include/ircd/m/room/members.h @@ -37,6 +37,9 @@ struct ircd::m::room::members bool for_each(const closure_bool &) const; void for_each(const closure &) const; + bool empty(const string_view &membership) const; + bool empty() 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 2411f6532..c00cc4640 100644 --- a/ircd/m_room.cc +++ b/ircd/m_room.cc @@ -3129,6 +3129,64 @@ ircd::m::room::state::space::rebuild::rebuild() // room::members // +bool +ircd::m::room::members::empty() +const +{ + const room::state state + { + room + }; + + // for_each() returns true when it reaches the end of the iteration. + return state.for_each("m.room.member", state::closure_bool{[] + (const auto &type, const auto &state_key, const auto &event_idx) + { + return false; + }}); +} + +bool +ircd::m::room::members::empty(const string_view &membership) +const +{ + const room::state state + { + room + }; + + // joined members optimization. Only possible when seeking + // membership="join" on the present state of the room. + if(membership == "join" && state.present()) + { + // _for_each() returns true when it reaches the end of the iteration. + const room::origins origins{room}; + return origins._for_each(origins, [] + (const string_view &) + { + // closure returns false to break causing _for_each() to return false. + return false; + }); + } + + // for_each() returns true when it reaches the end of the iteration. + return state.for_each("m.room.member", state::closure_bool{[&membership] + (const auto &type, const auto &state_key, const auto &event_idx) + { + // return false if the query succeeds, breaking the iteration. + return !m::query(std::nothrow, event_idx, "content", [&membership] + (const json::object &content) + { + const json::string &content_membership + { + content["membership"] + }; + + return !membership || content_membership == membership; + }); + }}); +} + size_t ircd::m::room::members::count() const