diff --git a/include/ircd/m/room.h b/include/ircd/m/room.h index b669368ee..ab763123f 100644 --- a/include/ircd/m/room.h +++ b/include/ircd/m/room.h @@ -198,12 +198,16 @@ struct ircd::m::room::state struct tuple; struct opts; + using keys = std::function; + using keys_bool = std::function; + room::id room_id; event::id::buf event_id; m::state::id_buffer root_id_buf; m::state::id root_id; // Iterate the state; for_each protocol + void for_each(const string_view &type, const keys &) const; void for_each(const string_view &type, const event::id::closure &) const; void for_each(const string_view &type, const event::closure &) const; void for_each(const event::id::closure &) const; @@ -212,6 +216,7 @@ struct ircd::m::room::state // Iterate the state; test protocol bool test(const string_view &type, const string_view &lower_bound, const event::id::closure_bool &view) const; bool test(const string_view &type, const string_view &lower_bound, const event::closure_bool &view) const; + bool test(const string_view &type, const keys_bool &view) const; bool test(const string_view &type, const event::id::closure_bool &view) const; bool test(const string_view &type, const event::closure_bool &view) const; bool test(const event::id::closure_bool &view) const; diff --git a/ircd/m/room.cc b/ircd/m/room.cc index a1364bda5..3f4499a75 100644 --- a/ircd/m/room.cc +++ b/ircd/m/room.cc @@ -630,6 +630,44 @@ const return false; } +bool +ircd::m::room::state::test(const string_view &type, + const keys_bool &closure) +const +{ + if(root_id) + return m::state::test(root_id, type, [&closure] + (const json::array &key, const string_view &event_id) + { + assert(size(key) >= 2); + return closure(unquote(key.at(1))); + }); + + char keybuf[768]; + const auto &key + { + dbs::room_state_key(keybuf, room_id, type) + }; + + auto &column{dbs::room_state}; + for(auto it{column.begin(key)}; bool(it); ++it) + { + const auto part + { + dbs::room_state_key(it->first) + }; + + if(std::get<0>(part) == type) + { + if(closure(std::get<1>(part))) + return true; + } + else break; + } + + return false; +} + bool ircd::m::room::state::test(const string_view &type, const string_view &state_key_lb, @@ -748,6 +786,40 @@ const break; } +void +ircd::m::room::state::for_each(const string_view &type, + const keys &closure) +const +{ + if(root_id) + return m::state::for_each(root_id, type, [&closure] + (const json::array &key, const string_view &event_id) + { + assert(size(key) >= 2); + closure(unquote(key.at(1))); + }); + + char keybuf[768]; + const auto &key + { + dbs::room_state_key(keybuf, room_id, type) + }; + + auto &column{dbs::room_state}; + for(auto it{column.begin(key)}; bool(it); ++it) + { + const auto part + { + dbs::room_state_key(it->first) + }; + + if(std::get<0>(part) == type) + closure(std::get<1>(part)); + else + break; + } +} + // // room::members //