From a331bc28822963c19a72af6d39278677b6ebd3d1 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Thu, 9 May 2019 19:03:30 -0700 Subject: [PATCH] ircd::m::dbs: Add interposing system for transaction self-references. --- include/ircd/m/dbs/write_opts.h | 13 ++++++++++++ ircd/m_dbs.cc | 35 ++++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/include/ircd/m/dbs/write_opts.h b/include/ircd/m/dbs/write_opts.h index 17039ec64..73771aec9 100644 --- a/include/ircd/m/dbs/write_opts.h +++ b/include/ircd/m/dbs/write_opts.h @@ -56,4 +56,17 @@ struct ircd::m::dbs::write_opts /// Whether the event.source can be used directly for event_json. Defaults /// to false unless the caller wants to avoid a redundant re-stringify. bool json_source {false}; + + /// Data in this db::txn is used as a primary source in some cases where + /// indexers make a database query. This is useful when the sought data + /// has not even been written to the database, and this may even point to + /// the same db::txn as the result being composed in the first place. By + /// default a database query is made as a fallback after using this. + const db::txn *interpose {nullptr}; + + /// Whether indexers are allowed to make database queries when composing + /// the transaction. note: database queries may yield the ircd::ctx and + /// made indepdently; this is slow and requires external synchronization + /// to not introduce inconsistent data into the txn. + bool allow_queries {true}; }; diff --git a/ircd/m_dbs.cc b/ircd/m_dbs.cc index d59bb4e21..f4ba7750c 100644 --- a/ircd/m_dbs.cc +++ b/ircd/m_dbs.cc @@ -257,6 +257,11 @@ ircd::m::dbs::write(db::txn &txn, // Internal interface // +namespace ircd::m::dbs +{ + static event::idx find_event_idx(const event::id &, const write_opts &); +} + void ircd::m::dbs::_index_event(db::txn &txn, const event &event, @@ -438,7 +443,7 @@ ircd::m::dbs::_index_event_refs_prev(db::txn &txn, const event::idx &prev_idx { - m::index(prev_id, std::nothrow) // query + find_event_idx(prev_id, opts) }; if(opts.appendix.test(appendix::EVENT_HORIZON) && !prev_idx) @@ -496,7 +501,7 @@ ircd::m::dbs::_index_event_refs_auth(db::txn &txn, const event::idx &auth_idx { - m::index(auth_id, std::nothrow) // query + find_event_idx(auth_id, opts) }; if(unlikely(!auth_idx)) @@ -562,7 +567,9 @@ ircd::m::dbs::_index_event_refs_state(db::txn &txn, const event::idx &prev_state_idx { - state.get(std::nothrow, at<"type"_>(event), at<"state_key"_>(event)) // query + opts.allow_queries? + state.get(std::nothrow, at<"type"_>(event), at<"state_key"_>(event)): // query + 0UL }; if(!prev_state_idx) @@ -631,7 +638,7 @@ ircd::m::dbs::_index_event_refs_m_receipt_m_read(db::txn &txn, const event::idx &event_idx { - m::index(event_id, std::nothrow) // query + find_event_idx(event_id, opts) }; if(opts.appendix.test(appendix::EVENT_HORIZON) && !event_idx) @@ -728,7 +735,7 @@ ircd::m::dbs::_index_event_refs_m_relates_m_reply(db::txn &txn, const event::idx &event_idx { - m::index(event_id, std::nothrow) // query + find_event_idx(event_id, opts) }; if(opts.appendix.test(appendix::EVENT_HORIZON) && !event_idx) @@ -786,7 +793,7 @@ ircd::m::dbs::_index_event_refs_m_room_redaction(db::txn &txn, const event::idx &event_idx { - m::index(event_id, std::nothrow) // query + find_event_idx(event_id, opts) }; if(opts.appendix.test(appendix::EVENT_HORIZON) && !event_idx) @@ -1052,7 +1059,7 @@ try const m::event::idx target_idx { - m::index(target_id, std::nothrow) + find_event_idx(target_id, opts) }; if(unlikely(!target_idx)) @@ -1302,6 +1309,20 @@ ircd::m::dbs::_index__room_state(db::txn &txn, }; } +ircd::m::event::idx +ircd::m::dbs::find_event_idx(const event::id &event_id, + const write_opts &wopts) +{ + event::idx ret{0}; + if(wopts.interpose) + ret = wopts.interpose->val(db::op::SET, "_event_idx", event_id, 0UL); + + if(wopts.allow_queries && !ret) + ret = m::index(event_id, std::nothrow); // query + + return ret; +} + ircd::string_view ircd::m::dbs::state_root(const mutable_buffer &out, const event &event)