From 11df089f3000bb8e402583b26a636897f4c58d9d Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Thu, 17 May 2018 19:29:44 -0700 Subject: [PATCH] modules/s_state: Preliminary tree rebuild from forward iteration; console cmd. --- modules/console.cc | 33 ++++++++++++++++++++ modules/s_state.cc | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/modules/console.cc b/modules/console.cc index 6b9f8761e..6ccbfeb41 100644 --- a/modules/console.cc +++ b/modules/console.cc @@ -3195,6 +3195,39 @@ console_cmd__room__state__rebuild__present(opt &out, const string_view &line) return true; } +bool +console_cmd__room__state__rebuild__history(opt &out, const string_view &line) +{ + const params param{line, " ", + { + "room_id" + }}; + + const auto &room_id + { + m::room_id(param.at(0)) + }; + + const m::room room + { + room_id + }; + + using prototype = size_t (const m::room &); + static m::import state__rebuild_history + { + "s_state", "state__rebuild_history" + }; + + const size_t count + { + state__rebuild_history(room) + }; + + out << "done " << count << std::endl; + return true; +} + bool console_cmd__room__count(opt &out, const string_view &line) { diff --git a/modules/s_state.cc b/modules/s_state.cc index 9deb8205d..db3bcbb13 100644 --- a/modules/s_state.cc +++ b/modules/s_state.cc @@ -64,3 +64,80 @@ state__rebuild_present(const m::room &room) txn(); return ret; } + +extern "C" size_t +state__rebuild_history(const m::room &room) +{ + size_t ret{0}; + const m::room::state state + { + room + }; + + const auto create_id + { + state.get("m.room.create") + }; + + m::room::messages it + { + room, create_id + }; + + if(!it) + return ret; + + db::txn txn + { + *m::dbs::events + }; + + uint r(0); + char root[2][64] {0}; + m::dbs::write_opts opts; + opts.root_in = root[++r % 2]; + opts.root_out = root[++r % 2]; + opts.present = false; + opts.history = true; + opts.head = false; + opts.refs = false; + + int64_t depth{0}; + for(; it; ++it) + { + const m::event &event{*it}; + opts.idx = it.event_idx(); + if(at<"depth"_>(event) == depth + 1) + ++depth; + + if(at<"depth"_>(event) != depth) + throw ircd::error + { + "Incomplete room history: gap between %ld and %ld [%s]", + depth, + at<"depth"_>(event), + string_view{at<"event_id"_>(event)} + }; + + if(at<"type"_>(event) == "m.room.redaction") + { + opts.root_in = m::dbs::_index_redact(txn, event, opts); + opts.root_out = root[++r % 2]; + txn(); + txn.clear(); + } + else if(defined(json::get<"state_key"_>(event))) + { + opts.root_in = m::dbs::_index_state(txn, event, opts); + opts.root_out = root[++r % 2]; + txn(); + txn.clear(); + } + else m::dbs::_index_ephem(txn, event, opts); + + ++ret; + } + + txn(); + return ret; +}