From 1bdf52b7bb1d2416022ffdd0105dfcdcad1578c2 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Wed, 26 Feb 2020 18:17:10 -0800 Subject: [PATCH] ircd::m::events: Add preliminary interface to _event_state w/ console cmd. --- include/ircd/m/events.h | 10 ++++++ matrix/events.cc | 67 +++++++++++++++++++++++++++++++++++++++++ modules/console.cc | 40 ++++++++++++++++++++++++ 3 files changed, 117 insertions(+) diff --git a/include/ircd/m/events.h b/include/ircd/m/events.h index 3a737c7f6..fd9f79cbc 100644 --- a/include/ircd/m/events.h +++ b/include/ircd/m/events.h @@ -74,6 +74,16 @@ namespace ircd::m::events::origin bool for_each_in(const string_view &, const sender::closure &); } +/// Interface to the state_key index of all events known to this server. +namespace ircd::m::events::state +{ + using tuple = dbs::event_state_tuple; + using closure = std::function; + + bool for_each(const tuple &, const closure &); + bool for_each(const closure &); +} + /// Range to start (inclusive) and stop (exclusive). If start is greater than /// stop a reverse iteration will occur. -1 (or unsigned max value) can be used /// to start or stop at the end. 0 can be used to start or stop at the beginning. diff --git a/matrix/events.cc b/matrix/events.cc index d93fecfa9..4920b664f 100644 --- a/matrix/events.cc +++ b/matrix/events.cc @@ -350,6 +350,73 @@ ircd::m::events::for_each(const range &range, return true; } +// +// events::state +// + +bool +IRCD_MODULE_EXPORT +ircd::m::events::state::for_each(const closure &closure) +{ + static const tuple none + { + {}, {}, {}, -1L, 0UL + }; + + return state::for_each(none, [&closure] + (const tuple &key) -> bool + { + return closure(key); + }); +} + +bool +IRCD_MODULE_EXPORT +ircd::m::events::state::for_each(const tuple &query, + const closure &closure) +{ + db::column &column + { + dbs::event_state + }; + + char buf[dbs::EVENT_STATE_KEY_MAX_SIZE]; + const string_view query_key + { + dbs::event_state_key(buf, query) + }; + + for(auto it(column.lower_bound(query_key)); bool(it); ++it) + { + const auto key + { + dbs::event_state_key(it->first) + }; + + const auto &[state_key, type, room_id, depth, event_idx] + { + key + }; + + const bool tab[] + { + !std::get<0>(query) || std::get<0>(query) == std::get<0>(key), + !std::get<1>(query) || std::get<1>(query) == std::get<1>(key), + !std::get<2>(query) || std::get<2>(query) == std::get<2>(key), + std::get<3>(query) <= 0 || std::get<3>(query) == std::get<3>(key), + std::get<4>(query) == 0 || std::get<4>(query) == std::get<4>(key), + }; + + if(!std::all_of(begin(tab), end(tab), identity())) + break; + + if(!closure(key)) + return false; + } + + return true; +} + // // events::type // diff --git a/modules/console.cc b/modules/console.cc index 14086b4f3..0225c2253 100644 --- a/modules/console.cc +++ b/modules/console.cc @@ -6981,6 +6981,46 @@ console_cmd__events__origin(opt &out, const string_view &line) return true; } +bool +console_cmd__events__state(opt &out, const string_view &line) +{ + const params param{line, " ", + { + "state_key", "type", "room_id", "depth", "idx" + }}; + + const m::events::state::tuple key + { + param["state_key"], + param["type"], + param.at("room_id", m::room::id{}), + param.at("depth", -1L), + param.at("idx", 0UL), + }; + + size_t i(0); + m::events::state::for_each(key, [&out, &i] + (const auto &tuple) + { + const auto &[state_key, type, room_id, depth, event_idx] + { + tuple + }; + + out + << std::right << std::setw(6) << (i++) << " " + << std::left << std::setw(48) << room_id << " " + << std::right << std::setw(8) << depth << " [ " + << std::right << std::setw(48) << type << " | " + << std::left << std::setw(48) << state_key << " ] " + << std::left << std::setw(10) << event_idx << " " + << std::endl; + return true; + }); + + return true; +} + conf::item events_dump_buffer_size {