From 3a4817354e80970117d3e4dbd36d5cd3c7ea8fb9 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Tue, 21 Aug 2018 08:37:06 -0700 Subject: [PATCH] ircd::m: Add room state types iteration. --- include/ircd/m/room.h | 3 ++ ircd/m/room.cc | 73 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/include/ircd/m/room.h b/include/ircd/m/room.h index e7c85515b..a483e3ef9 100644 --- a/include/ircd/m/room.h +++ b/include/ircd/m/room.h @@ -238,6 +238,7 @@ struct ircd::m::room::state struct opts; using keys = std::function; + using types = std::function; using keys_bool = std::function; room::id room_id; @@ -249,6 +250,7 @@ struct ircd::m::room::state bool present() const; // Iterate the state; for_each protocol + bool for_each(const types &) const; void for_each(const string_view &type, const keys &) const; void for_each(const string_view &type, const event::closure_idx &) const; void for_each(const string_view &type, const event::id::closure &) const; @@ -258,6 +260,7 @@ struct ircd::m::room::state void for_each(const event::closure &) const; // Iterate the state; test protocol + bool test(const types &) const; bool test(const string_view &type, const string_view &lower_bound, const event::closure_idx_bool &view) const; 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; diff --git a/ircd/m/room.cc b/ircd/m/room.cc index 1c9ca3db9..98b990a1c 100644 --- a/ircd/m/room.cc +++ b/ircd/m/room.cc @@ -1174,6 +1174,17 @@ const return false; } +bool +ircd::m::room::state::test(const types &closure) +const +{ + return !for_each(types{[&closure] + (const string_view &type) + { + return !closure(type); + }}); +} + void ircd::m::room::state::for_each(const event::closure &closure) const @@ -1322,6 +1333,68 @@ const } } +bool +ircd::m::room::state::for_each(const types &closure) +const +{ + string_view last; + char lastbuf[256]; //TODO: type maxlen + if(!present()) + { + m::state::for_each(root_id, [&closure, &last, &lastbuf] + (const json::array &key, const string_view &) + { + assert(size(key) >= 2); + const auto type + { + unquote(key.at(0)) + }; + + if(type == last) + return true; + + last = strlcpy(lastbuf, type); + return closure(type); + }); + + return true; + } + + char keybuf[dbs::ROOM_STATE_KEY_MAX_SIZE]; + const auto &key + { + dbs::room_state_key(keybuf, room_id, string_view{}) + }; + + db::gopts opts + { + this->fopts? this->fopts->gopts : db::gopts{} + }; + + auto &column{dbs::room_state}; + for(auto it{column.begin(key, opts)}; bool(it); ++it) + { + const auto part + { + dbs::room_state_key(it->first) + }; + + const auto &type + { + std::get<0>(part) + }; + + if(type == last) + continue; + + last = strlcpy(lastbuf, type); + if(!closure(type)) + return false; + } + + return true; +} + bool ircd::m::room::state::present() const