diff --git a/include/ircd/m/room/state.h b/include/ircd/m/room/state.h index 36c925990..6a1cc727b 100644 --- a/include/ircd/m/room/state.h +++ b/include/ircd/m/room/state.h @@ -28,6 +28,8 @@ struct ircd::m::room::state using keys_bool = std::function; using types = std::function; using types_bool = std::function; + using closure = std::function; + using closure_bool = std::function; IRCD_STRONG_TYPEDEF(string_view, type_prefix) static conf::item disable_history; @@ -50,15 +52,18 @@ struct ircd::m::room::state bool for_each(const string_view &type, const keys_bool &view) const; void for_each(const string_view &type, const keys &) const; bool for_each(const string_view &type, const string_view &lower_bound, const keys_bool &view) const; + bool for_each(const string_view &type, const string_view &lower_bound, const closure_bool &view) const; bool for_each(const string_view &type, const string_view &lower_bound, const event::closure_idx_bool &view) const; bool for_each(const string_view &type, const string_view &lower_bound, const event::id::closure_bool &view) const; bool for_each(const string_view &type, const string_view &lower_bound, const event::closure_bool &view) const; + bool for_each(const string_view &type, const closure_bool &view) const; bool for_each(const string_view &type, const event::closure_idx_bool &view) const; void for_each(const string_view &type, const event::closure_idx &) const; bool for_each(const string_view &type, const event::id::closure_bool &view) const; void for_each(const string_view &type, const event::id::closure &) const; bool for_each(const string_view &type, const event::closure_bool &view) const; void for_each(const string_view &type, const event::closure &) const; + bool for_each(const closure_bool &view) const; bool for_each(const event::closure_idx_bool &view) const; void for_each(const event::closure_idx &) const; bool for_each(const event::id::closure_bool &view) const; diff --git a/ircd/m_room.cc b/ircd/m_room.cc index 86469c42e..81deae633 100644 --- a/ircd/m_room.cc +++ b/ircd/m_room.cc @@ -1269,6 +1269,38 @@ const return true; } +bool +ircd::m::room::state::for_each(const closure_bool &closure) +const +{ + if(!present()) + return m::state::for_each(root_id, m::state::iter_bool_closure{[&closure] + (const json::array &key, const string_view &event_id) + { + const auto idx(index(m::event::id(unquote(event_id)), std::nothrow)); + return closure(key.at(0), key.at(1), idx); + }}); + + db::gopts opts + { + this->fopts? this->fopts->gopts : db::gopts{} + }; + + if(!opts.readahead) + opts.readahead = size_t(readahead_size); + + auto &column{dbs::room_state}; + for(auto it{column.begin(room_id, opts)}; bool(it); ++it) + { + const byte_view idx(it->second); + const auto key(dbs::room_state_key(it->first)); + if(!closure(std::get<0>(key), std::get<1>(key), idx)) + return false; + } + + return true; +} + void ircd::m::room::state::for_each(const string_view &type, const event::closure &closure) @@ -1338,6 +1370,16 @@ const for_each(closure); } +bool +ircd::m::room::state::for_each(const string_view &type, + const closure_bool &closure) +const +{ + return type? + for_each(type, string_view{}, closure): + for_each(closure); +} + bool ircd::m::room::state::for_each(const string_view &type, const string_view &state_key_lb, @@ -1392,12 +1434,26 @@ ircd::m::room::state::for_each(const string_view &type, const string_view &state_key_lb, const event::closure_idx_bool &closure) const +{ + return for_each(type, state_key_lb, closure_bool{[&closure] + (const string_view &type, const string_view &state_key, const event::idx &event_idx) + { + return closure(event_idx); + }}); +} + +bool +ircd::m::room::state::for_each(const string_view &type, + const string_view &state_key_lb, + const closure_bool &closure) +const { if(!present()) return m::state::for_each(root_id, type, state_key_lb, [&closure] (const json::array &key, const string_view &event_id) { - return closure(index(m::event::id(unquote(event_id)), std::nothrow)); + const auto idx(index(m::event::id(unquote(event_id)), std::nothrow)); + return closure(key.at(0), key.at(1), idx); }); char keybuf[dbs::ROOM_STATE_KEY_MAX_SIZE]; @@ -1416,12 +1472,19 @@ const auto &column{dbs::room_state}; for(auto it{column.begin(key, opts)}; bool(it); ++it) - if(std::get<0>(dbs::room_state_key(it->first)) == type) + { + const auto key { - if(!closure(byte_view(it->second))) - return false; - } - else break; + dbs::room_state_key(it->first) + }; + + if(std::get<0>(key) != type) + break; + + const byte_view idx(it->second); + if(!closure(std::get<0>(key), std::get<1>(key), idx)) + return false; + } return true; } @@ -1483,12 +1546,11 @@ const dbs::room_state_key(it->first) }; - if(std::get<0>(key) == type) - { - if(!closure(std::get<1>(key))) - return false; - } - else break; + if(std::get<0>(key) != type) + break; + + if(!closure(std::get<1>(key))) + return false; } return true;