0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

ircd:Ⓜ️:dbs: Simplify indexers / interface.

This commit is contained in:
Jason Volk 2019-05-13 12:12:23 -07:00
parent 92b5862b86
commit 304c6df468
4 changed files with 192 additions and 473 deletions

View file

@ -28,7 +28,7 @@ namespace ircd::m::dbs
extern std::shared_ptr<db::database> events;
// [SET (txn)] Basic write suite
string_view write(db::txn &, const event &, const write_opts &);
void write(db::txn &, const event &, const write_opts &);
}
/// Database description
@ -51,7 +51,7 @@ namespace ircd::m::dbs::appendix
#include "event_type.h" // type | event_idx
#include "event_sender.h" // hostpart | localpart, event_idx
#include "room_head.h" // room_id | event_id => event_idx
#include "room_events.h" // room_id | depth, event_idx => node_id
#include "room_events.h" // room_id | depth, event_idx
#include "room_joined.h" // room_id | origin, member => event_idx
#include "room_state.h" // room_id | type, state_key => event_idx
#include "room_state_space.h" // room_id | type, state_key, depth, event_idx
@ -72,13 +72,6 @@ struct ircd::m::dbs::write_opts
/// be zero for blacklisting, but the blacklist option must be set.
uint64_t event_idx {0};
/// The state btree root to perform the update on.
string_view root_in;
/// After the update is performed, the new state btree root is returned
/// into this buffer.
mutable_buffer root_out;
/// Fuse panel to toggle transaction elements.
std::bitset<64> appendix {appendix_all};
@ -92,14 +85,6 @@ struct ircd::m::dbs::write_opts
/// event_horizon for this event.
std::bitset<256> horizon_resolve {event_refs_all};
/// Whether the present state table `room_state` should be updated by
/// this operation if appropriate.
bool present {true};
/// Whether the history state btree `state_node` + `room_events` value
/// should be updated by this operation if appropriate.
bool history {false};
/// 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};
@ -136,9 +121,6 @@ struct ircd::m::dbs::write_opts
enum ircd::m::dbs::appendix::index
:std::underlying_type<ircd::m::dbs::appendix::index>::type
{
/// This bit offers coarse control over all the EVENT_ appendices.
EVENT,
/// Involves the event_idx column; translates an event_id to our internal
/// index number. This bit can be dark during re-indexing operations.
EVENT_ID,
@ -174,20 +156,8 @@ enum ircd::m::dbs::appendix::index
/// Involves the event_type column (reverse index on the event type).
EVENT_TYPE,
/// Take branch to handle events with a room_id
ROOM,
/// Take branch to handle room state events.
STATE,
/// Perform state btree manip for room history.
HISTORY,
/// Take branch to handle room redaction events.
REDACT,
/// Take branch to handle other types of events.
OTHER,
/// Involves room_events table.
ROOM_EVENTS,
/// Whether the event should be added to the room_head, indicating that
/// it has not yet been referenced at the time of this write. Defaults
@ -198,17 +168,17 @@ enum ircd::m::dbs::appendix::index
/// room_head. This defaults to true and should almost always be true.
ROOM_HEAD_RESOLVE,
/// Involves room_events table.
ROOM_EVENTS,
/// Involves room_joined table.
ROOM_JOINED,
/// Involves room_state (present state) table.
ROOM_STATE,
/// Involves room_space (all states) table.
ROOM_STATE_SPACE,
/// Involves room_joined table.
ROOM_JOINED,
/// Take branch to handle room redaction events.
ROOM_REDACT,
};
struct ircd::m::dbs::init
@ -220,16 +190,14 @@ struct ircd::m::dbs::init
// Internal interface; not for public. (TODO: renamespace)
namespace ircd::m::dbs
{
void _index__room_state_space(db::txn &, const event &, const write_opts &);
void _index__room_state(db::txn &, const event &, const write_opts &);
void _index__room_events(db::txn &, const event &, const write_opts &, const string_view &);
void _index__room_joined(db::txn &, const event &, const write_opts &);
void _index__room_head_resolve(db::txn &, const event &, const write_opts &);
void _index__room_head(db::txn &, const event &, const write_opts &);
string_view _index_state(db::txn &, const event &, const write_opts &);
string_view _index_redact(db::txn &, const event &, const write_opts &);
string_view _index_other(db::txn &, const event &, const write_opts &);
string_view _index_room(db::txn &, const event &, const write_opts &);
void _index_room_joined(db::txn &, const event &, const write_opts &);
void _index_room_redact(db::txn &, const event &, const write_opts &);
void _index_room_state_space(db::txn &, const event &, const write_opts &);
void _index_room_state(db::txn &, const event &, const write_opts &);
void _index_room_head_resolve(db::txn &, const event &, const write_opts &);
void _index_room_head(db::txn &, const event &, const write_opts &);
void _index_room_events(db::txn &, const event &, const write_opts &);
void _index_room(db::txn &, const event &, const write_opts &);
void _index_event_type(db::txn &, const event &, const write_opts &);
void _index_event_sender(db::txn &, const event &, const write_opts &);
void _index_event_horizon_resolve(db::txn &, const event &, const write_opts &);

View file

@ -215,16 +215,13 @@ namespace ircd::m::dbs
static void blacklist(db::txn &txn, const event::id &, const write_opts &);
}
ircd::string_view
void
ircd::m::dbs::write(db::txn &txn,
const event &event,
const write_opts &opts)
{
if(opts.event_idx == 0 && opts.blacklist)
{
blacklist(txn, at<"event_id"_>(event), opts);
return {};
}
return blacklist(txn, at<"event_id"_>(event), opts);
if(unlikely(opts.event_idx == 0))
throw panic
@ -232,14 +229,9 @@ ircd::m::dbs::write(db::txn &txn,
"Cannot write to database: no index specified for event."
};
if(opts.appendix.test(appendix::EVENT))
_index_event(txn, event, opts);
if(opts.appendix.test(appendix::ROOM))
if(json::get<"room_id"_>(event))
return _index_room(txn, event, opts);
return {};
_index_event(txn, event, opts);
if(json::get<"room_id"_>(event))
_index_room(txn, event, opts);
}
void
@ -492,7 +484,7 @@ ircd::m::dbs::_index_event_refs_prev(db::txn &txn,
{
txn, dbs::event_refs,
{
opts.op, key, string_view{}
opts.op, key
}
};
}
@ -548,7 +540,7 @@ ircd::m::dbs::_index_event_refs_auth(db::txn &txn,
{
txn, dbs::event_refs,
{
opts.op, key, string_view{}
opts.op, key
}
};
}
@ -563,9 +555,6 @@ ircd::m::dbs::_index_event_refs_state(db::txn &txn,
assert(opts.event_refs.test(uint(ref::NEXT_STATE)) ||
opts.event_refs.test(uint(ref::PREV_STATE)));
if(!opts.present)
return;
if(!json::get<"room_id"_>(event))
return;
@ -614,7 +603,7 @@ ircd::m::dbs::_index_event_refs_state(db::txn &txn,
{
txn, dbs::event_refs,
{
opts.op, key, string_view{}
opts.op, key
}
};
}
@ -630,7 +619,7 @@ ircd::m::dbs::_index_event_refs_state(db::txn &txn,
{
txn, dbs::event_refs,
{
opts.op, key, string_view{}
opts.op, key
}
};
}
@ -691,7 +680,7 @@ ircd::m::dbs::_index_event_refs_m_receipt_m_read(db::txn &txn,
{
txn, dbs::event_refs,
{
opts.op, key, string_view{}
opts.op, key
}
};
}
@ -788,7 +777,7 @@ ircd::m::dbs::_index_event_refs_m_relates_m_reply(db::txn &txn,
{
txn, dbs::event_refs,
{
opts.op, key, string_view{}
opts.op, key
}
};
}
@ -846,7 +835,7 @@ ircd::m::dbs::_index_event_refs_m_room_redaction(db::txn &txn,
{
txn, dbs::event_refs,
{
opts.op, key, string_view{}
opts.op, key
}
};
}
@ -869,7 +858,7 @@ ircd::m::dbs::_index_event_horizon(db::txn &txn,
{
txn, dbs::event_horizon,
{
opts.op, key, string_view{}
opts.op, key
}
};
}
@ -918,7 +907,6 @@ ircd::m::dbs::_index_event_horizon_resolve(db::txn &txn,
_opts.op = opts.op;
_opts.event_idx = event_idx;
_opts.appendix.reset();
_opts.appendix.set(appendix::EVENT);
_opts.appendix.set(appendix::EVENT_REFS);
_opts.event_refs = opts.horizon_resolve;
_opts.interpose = &txn;
@ -963,7 +951,7 @@ ircd::m::dbs::_index_event_sender(db::txn &txn,
{
txn, dbs::event_sender,
{
opts.op, key, string_view{}
opts.op, key
}
};
}
@ -987,169 +975,72 @@ ircd::m::dbs::_index_event_type(db::txn &txn,
{
txn, dbs::event_type,
{
opts.op, key, string_view{}
opts.op, key
}
};
}
ircd::string_view
void
ircd::m::dbs::_index_room(db::txn &txn,
const event &event,
const write_opts &opts)
{
assert(opts.appendix.test(appendix::ROOM));
assert(!empty(json::get<"room_id"_>(event)));
if(opts.appendix.test(appendix::ROOM_EVENTS))
_index_room_events(txn, event, opts);
if(opts.appendix.test(appendix::ROOM_HEAD))
_index__room_head(txn, event, opts);
_index_room_head(txn, event, opts);
if(opts.appendix.test(appendix::ROOM_HEAD_RESOLVE))
_index__room_head_resolve(txn, event, opts);
_index_room_head_resolve(txn, event, opts);
if(opts.appendix.test(appendix::STATE) && defined(json::get<"state_key"_>(event)))
return _index_state(txn, event, opts);
if(defined(json::get<"state_key"_>(event)))
{
if(opts.appendix.test(appendix::ROOM_STATE))
_index_room_state(txn, event, opts);
if(opts.appendix.test(appendix::REDACT) && json::get<"type"_>(event) == "m.room.redaction")
return _index_redact(txn, event, opts);
if(opts.appendix.test(appendix::ROOM_STATE_SPACE))
_index_room_state_space(txn, event, opts);
if(opts.appendix.test(appendix::OTHER))
return _index_other(txn, event, opts);
if(opts.appendix.test(appendix::ROOM_JOINED) && at<"type"_>(event) == "m.room.member")
_index_room_joined(txn, event, opts);
}
return {};
if(opts.appendix.test(appendix::ROOM_REDACT) && json::get<"type"_>(event) == "m.room.redaction")
_index_room_redact(txn, event, opts);
}
ircd::string_view
ircd::m::dbs::_index_state(db::txn &txn,
const event &event,
const write_opts &opts)
try
/// Adds the entry for the room_events column into the txn.
void
ircd::m::dbs::_index_room_events(db::txn &txn,
const event &event,
const write_opts &opts)
{
assert(opts.appendix.test(appendix::STATE));
assert(opts.appendix.test(appendix::ROOM_EVENTS));
const auto &type
thread_local char buf[ROOM_EVENTS_KEY_MAX_SIZE];
const ctx::critical_assertion ca;
const string_view &key
{
at<"type"_>(event)
room_events_key(buf, at<"room_id"_>(event), at<"depth"_>(event), opts.event_idx)
};
const auto &room_id
db::txn::append
{
at<"room_id"_>(event)
};
const string_view &new_root
{
opts.op == db::op::SET &&
opts.appendix.test(appendix::HISTORY) &&
opts.history?
state::insert(txn, opts.root_out, opts.root_in, event):
strlcpy(opts.root_out, opts.root_in)
};
if(opts.appendix.test(appendix::ROOM_EVENTS))
_index__room_events(txn, event, opts, new_root);
if(opts.appendix.test(appendix::ROOM_JOINED))
_index__room_joined(txn, event, opts);
if(opts.appendix.test(appendix::ROOM_STATE))
_index__room_state(txn, event, opts);
if(opts.appendix.test(appendix::ROOM_STATE_SPACE))
_index__room_state_space(txn, event, opts);
return new_root;
}
catch(const std::exception &e)
{
log::error
{
"Failed to update state: %s", e.what()
};
throw;
}
ircd::string_view
ircd::m::dbs::_index_redact(db::txn &txn,
const event &event,
const write_opts &opts)
try
{
assert(opts.appendix.test(appendix::REDACT));
const auto &target_id
{
at<"redacts"_>(event)
};
const m::event::idx target_idx
{
find_event_idx(target_id, opts)
};
if(unlikely(!target_idx))
log::error
txn, room_events,
{
"Redaction from '%s' missing redaction target '%s'",
at<"event_id"_>(event),
target_id
};
const m::event::fetch target
{
target_idx, std::nothrow
};
const string_view new_root
{
target.valid &&
defined(json::get<"state_key"_>(target)) &&
opts.appendix.test(appendix::HISTORY) &&
opts.history?
//state::remove(txn, state_root_out, state_root_in, target):
strlcpy(opts.root_out, opts.root_in):
strlcpy(opts.root_out, opts.root_in)
};
if(opts.appendix.test(appendix::ROOM_EVENTS))
_index__room_events(txn, event, opts, opts.root_in);
if(opts.appendix.test(appendix::ROOM_STATE))
if(target.valid && defined(json::get<"state_key"_>(target)))
{
auto _opts(opts);
_opts.op = db::op::DELETE;
_index__room_state(txn, target, _opts);
opts.op, // db::op
key, // key,
}
return new_root;
}
catch(const std::exception &e)
{
log::error
{
"Failed to update state from redaction: %s", e.what()
};
throw;
}
ircd::string_view
ircd::m::dbs::_index_other(db::txn &txn,
const event &event,
const write_opts &opts)
{
assert(opts.appendix.test(appendix::OTHER));
if(opts.appendix.test(appendix::ROOM_EVENTS))
_index__room_events(txn, event, opts, opts.root_in);
return strlcpy(opts.root_out, opts.root_in);
}
void
ircd::m::dbs::_index__room_head(db::txn &txn,
const event &event,
const write_opts &opts)
ircd::m::dbs::_index_room_head(db::txn &txn,
const event &event,
const write_opts &opts)
{
const ctx::critical_assertion ca;
thread_local char buf[ROOM_HEAD_KEY_MAX_SIZE];
@ -1173,9 +1064,9 @@ ircd::m::dbs::_index__room_head(db::txn &txn,
}
void
ircd::m::dbs::_index__room_head_resolve(db::txn &txn,
const event &event,
const write_opts &opts)
ircd::m::dbs::_index_room_head_resolve(db::txn &txn,
const event &event,
const write_opts &opts)
{
assert(opts.appendix.test(appendix::ROOM_HEAD_RESOLVE));
@ -1212,47 +1103,128 @@ ircd::m::dbs::_index__room_head_resolve(db::txn &txn,
}
}
/// Adds the entry for the room_events column into the txn.
/// You need find/create the right state_root before this.
void
ircd::m::dbs::_index__room_events(db::txn &txn,
const event &event,
const write_opts &opts,
const string_view &new_root)
ircd::m::dbs::_index_room_state(db::txn &txn,
const event &event,
const write_opts &opts)
{
assert(opts.appendix.test(appendix::ROOM_EVENTS));
assert(opts.appendix.test(appendix::ROOM_STATE));
thread_local char buf[ROOM_EVENTS_KEY_MAX_SIZE];
const ctx::critical_assertion ca;
thread_local char buf[ROOM_STATE_KEY_MAX_SIZE];
const string_view &key
{
room_events_key(buf, at<"room_id"_>(event), at<"depth"_>(event), opts.event_idx)
room_state_key(buf, at<"room_id"_>(event), at<"type"_>(event), at<"state_key"_>(event))
};
const string_view val
{
byte_view<string_view>(opts.event_idx)
};
db::txn::append
{
txn, room_events,
txn, room_state,
{
opts.op, // db::op
key, // key
new_root // val
opts.op,
key,
value_required(opts.op)? val : string_view{},
}
};
}
void
ircd::m::dbs::_index_room_state_space(db::txn &txn,
const event &event,
const write_opts &opts)
{
assert(opts.appendix.test(appendix::ROOM_STATE_SPACE));
const ctx::critical_assertion ca;
thread_local char buf[ROOM_STATE_SPACE_KEY_MAX_SIZE];
const string_view &key
{
room_state_space_key(buf, at<"room_id"_>(event), at<"type"_>(event), at<"state_key"_>(event), at<"depth"_>(event), opts.event_idx)
};
db::txn::append
{
txn, room_state_space,
{
opts.op,
key,
}
};
}
void
ircd::m::dbs::_index_room_redact(db::txn &txn,
const event &event,
const write_opts &opts)
{
assert(opts.appendix.test(appendix::ROOM_REDACT));
assert(json::get<"type"_>(event) == "m.room.redaction");
const auto &target_id
{
at<"redacts"_>(event)
};
const m::event::idx target_idx
{
find_event_idx(target_id, opts)
};
if(unlikely(!target_idx))
log::error
{
"Redaction from '%s' missing redaction target '%s'",
at<"event_id"_>(event),
target_id
};
char state_key_buf[event::STATE_KEY_MAX_SIZE];
const string_view &state_key
{
m::get(std::nothrow, target_idx, "state_key", state_key_buf)
};
if(!state_key)
return;
char type_buf[event::TYPE_MAX_SIZE];
const string_view &type
{
m::get(std::nothrow, target_idx, "type", type_buf)
};
assert(!empty(type));
const ctx::critical_assertion ca;
thread_local char buf[ROOM_STATE_SPACE_KEY_MAX_SIZE];
const string_view &key
{
room_state_key(buf, at<"room_id"_>(event), type, state_key)
};
db::txn::append
{
txn, room_state,
{
db::op::DELETE,
key,
}
};
}
/// Adds the entry for the room_joined column into the txn.
void
ircd::m::dbs::_index__room_joined(db::txn &txn,
const event &event,
const write_opts &opts)
ircd::m::dbs::_index_room_joined(db::txn &txn,
const event &event,
const write_opts &opts)
{
assert(opts.appendix.test(appendix::ROOM_JOINED));
if(!opts.present)
return;
if(at<"type"_>(event) != "m.room.member")
return;
assert(at<"type"_>(event) == "m.room.member");
thread_local char buf[ROOM_JOINED_KEY_MAX_SIZE];
const ctx::critical_assertion ca;
@ -1298,62 +1270,6 @@ ircd::m::dbs::_index__room_joined(db::txn &txn,
};
}
void
ircd::m::dbs::_index__room_state(db::txn &txn,
const event &event,
const write_opts &opts)
{
assert(opts.appendix.test(appendix::ROOM_STATE));
if(!opts.present)
return;
const ctx::critical_assertion ca;
thread_local char buf[ROOM_STATE_KEY_MAX_SIZE];
const string_view &key
{
room_state_key(buf, at<"room_id"_>(event), at<"type"_>(event), at<"state_key"_>(event))
};
const string_view val
{
byte_view<string_view>(opts.event_idx)
};
db::txn::append
{
txn, room_state,
{
opts.op,
key,
value_required(opts.op)? val : string_view{},
}
};
}
void
ircd::m::dbs::_index__room_state_space(db::txn &txn,
const event &event,
const write_opts &opts)
{
assert(opts.appendix.test(appendix::ROOM_STATE_SPACE));
const ctx::critical_assertion ca;
thread_local char buf[ROOM_STATE_SPACE_KEY_MAX_SIZE];
const string_view &key
{
room_state_space_key(buf, at<"room_id"_>(event), at<"type"_>(event), at<"state_key"_>(event), at<"depth"_>(event), opts.event_idx)
};
db::txn::append
{
txn, room_state_space,
{
opts.op, key, string_view{}
}
};
}
ircd::m::event::idx
ircd::m::dbs::find_event_idx(const event::id &event_id,
const write_opts &wopts)

View file

@ -117,15 +117,12 @@ ircd::m::room::state::force_present(const m::event &event)
json::get<"event_id"_>(event)
};
m::dbs::write_opts opts;
dbs::write_opts opts;
opts.event_idx = m::index(event);
opts.present = true;
opts.history = false;
opts.appendix.reset(dbs::appendix::ROOM_HEAD);
opts.appendix.reset(dbs::appendix::ROOM_HEAD_RESOLVE);
m::dbs::_index__room_state(txn, event, opts);
m::dbs::_index__room_joined(txn, event, opts);
opts.appendix.reset();
opts.appendix.set(dbs::appendix::ROOM_STATE);
opts.appendix.reset(dbs::appendix::ROOM_JOINED);
dbs::write(txn, event, opts);
txn();
return true;
@ -157,13 +154,10 @@ ircd::m::room::state::rebuild_present(const state &state)
const m::event &event{*it};
m::dbs::write_opts opts;
opts.event_idx = event_idx;
opts.present = true;
opts.history = false;
opts.appendix.reset(dbs::appendix::ROOM_HEAD);
opts.appendix.reset(dbs::appendix::ROOM_HEAD_RESOLVE);
m::dbs::_index__room_state(txn, event, opts);
m::dbs::_index__room_joined(txn, event, opts);
opts.appendix.reset();
opts.appendix.set(dbs::appendix::ROOM_STATE);
opts.appendix.set(dbs::appendix::ROOM_JOINED);
dbs::write(txn, event, opts);
++ret;
}
@ -174,132 +168,13 @@ ircd::m::room::state::rebuild_present(const state &state)
size_t
ircd::m::room::state::rebuild_history(const state &state)
{
size_t ret{0};
const auto create_idx
{
state.get("m.room.create")
};
static const m::event::fetch::opts fopts
{
{ db::get::NO_CACHE }
};
const m::room room
{
state.room_id, nullptr, state.fopts
};
m::room::messages it
{
room, create_idx, &fopts
};
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.appendix.reset(dbs::appendix::ROOM_HEAD);
opts.appendix.reset(dbs::appendix::ROOM_HEAD_RESOLVE);
int64_t depth{0};
for(; it; ++it)
{
const m::event &event{*it};
opts.event_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_other(txn, event, opts);
++ret;
}
txn();
return ret;
return 0;
}
//TODO: state btree.
size_t
ircd::m::room::state::clear_history(const state &state)
{
static const db::gopts gopts
{
db::get::NO_CACHE
};
db::txn txn
{
*m::dbs::events
};
auto it
{
m::dbs::room_events.begin(state.room_id, gopts)
};
size_t ret{0};
for(; it; ++it, ret++)
{
const auto pair
{
m::dbs::room_events_key(it->first)
};
const auto &depth{std::get<0>(pair)};
const auto &event_idx{std::get<1>(pair)};
thread_local char buf[m::dbs::ROOM_EVENTS_KEY_MAX_SIZE];
const string_view key
{
m::dbs::room_events_key(buf, state.room_id, depth, event_idx)
};
db::txn::append
{
txn, m::dbs::room_events,
{
db::op::SET,
key
}
};
}
txn();
return ret;
return 0;
}
namespace ircd::m
@ -2997,8 +2872,6 @@ ircd::m::room::state::space::rebuild::rebuild()
dbs::write_opts wopts;
wopts.appendix.reset();
wopts.appendix.set(dbs::appendix::ROOM);
wopts.appendix.set(dbs::appendix::STATE);
wopts.appendix.set(dbs::appendix::ROOM_STATE_SPACE);
event::fetch event;
@ -3604,7 +3477,7 @@ ircd::m::room::head::rebuild(const head &head)
{
const m::event &event{*it};
opts.event_idx = it.event_idx();
m::dbs::_index__room_head(txn, event, opts);
m::dbs::_index_room_head(txn, event, opts);
++ret;
}
@ -3657,14 +3530,14 @@ ircd::m::room::head::reset(const head &head)
}
opts.event_idx = event_idx;
m::dbs::_index__room_head(txn, event, opts);
m::dbs::_index_room_head(txn, event, opts);
++ret;
});
// Finally add the replacement to the txn
opts.op = db::op::SET;
opts.event_idx = it.event_idx();
m::dbs::_index__room_head(txn, replacement, opts);
m::dbs::_index_room_head(txn, replacement, opts);
// Commit txn
txn();
@ -3690,7 +3563,7 @@ ircd::m::room::head::modify(const m::event::id &event_id,
m::dbs::write_opts opts;
opts.op = op;
opts.event_idx = event.event_idx;
m::dbs::_index__room_head(txn, event, opts);
m::dbs::_index_room_head(txn, event, opts);
// Commit txn
txn();

View file

@ -840,51 +840,13 @@ ircd::m::vm::write_append(eval &eval,
// Preliminary write_opts
m::dbs::write_opts wopts(opts.wopts);
m::state::id_buffer new_root_buf;
wopts.root_out = new_root_buf;
wopts.present = opts.present;
wopts.history = opts.history;
wopts.appendix.set(dbs::appendix::ROOM_STATE, opts.present);
wopts.appendix.set(dbs::appendix::ROOM_JOINED, opts.present);
wopts.appendix.set(dbs::appendix::ROOM_STATE_SPACE, opts.history);
wopts.appendix.set(dbs::appendix::ROOM_HEAD, opts.room_head);
wopts.appendix.set(dbs::appendix::ROOM_HEAD_RESOLVE, opts.room_head_resolve);
wopts.json_source = opts.json_source;
wopts.event_idx = eval.sequence;
if(at<"type"_>(event) == "m.room.create")
{
dbs::write(*eval.txn, event, wopts);
return;
}
const bool require_head
{
opts.fetch_state_check || opts.history
};
const id::event::buf head
{
require_head?
m::head(std::nothrow, at<"room_id"_>(event)):
id::event::buf{}
};
if(unlikely(require_head && !head))
throw error
{
fault::STATE, "Required head for room %s not found.",
string_view{at<"room_id"_>(event)}
};
const m::room room
{
at<"room_id"_>(event), head
};
const m::room::state state
{
room
};
wopts.root_in = state.root_id;
dbs::write(*eval.txn, event, wopts);
}