mirror of
https://github.com/matrix-construct/construct
synced 2024-11-25 16:22:35 +01:00
ircd:Ⓜ️:dbs: Simplify indexers / interface.
This commit is contained in:
parent
92b5862b86
commit
304c6df468
4 changed files with 192 additions and 473 deletions
|
@ -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 &);
|
||||
|
|
396
ircd/m_dbs.cc
396
ircd/m_dbs.cc
|
@ -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)
|
||||
|
|
157
ircd/m_room.cc
157
ircd/m_room.cc
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue