0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 07:23:53 +01:00

ircd:Ⓜ️:dbs: Add event_sender metadata column.

This commit is contained in:
Jason Volk 2019-04-16 13:41:55 -07:00
parent 31bbc6b1b4
commit 8148dc6502
2 changed files with 234 additions and 0 deletions

View file

@ -35,6 +35,7 @@ namespace ircd::m::dbs
extern db::column event_idx; // event_id => event_idx
extern db::column event_json; // event_idx => full json
extern db::index event_refs; // event_idx | ref_type, event_idx
extern db::index event_sender; // host | local, event_idx
extern db::index room_head; // room_id | event_id => event_idx
extern db::index room_events; // room_id | depth, event_idx => node_id
extern db::index room_joined; // room_id | origin, member => event_idx
@ -50,6 +51,11 @@ namespace ircd::m::dbs
std::tuple<ref, event::idx> event_refs_key(const string_view &amalgam);
string_view reflect(const ref &);
constexpr size_t EVENT_SENDER_KEY_MAX_SIZE {id::MAX_SIZE + 1 + 8};
string_view event_sender_key(const mutable_buffer &out, const string_view &origin, const string_view &localpart = {}, const event::idx & = 0);
string_view event_sender_key(const mutable_buffer &out, const id::user &, const event::idx &);
std::tuple<string_view, event::idx> event_sender_key(const string_view &amalgam);
constexpr size_t ROOM_HEAD_KEY_MAX_SIZE {id::MAX_SIZE + 1 + id::MAX_SIZE};
string_view room_head_key(const mutable_buffer &out, const id::room &, const id::event &);
string_view room_head_key(const string_view &amalgam);
@ -135,6 +141,9 @@ struct ircd::m::dbs::write_opts
/// Whether the event removes the prev_events it references from the
/// room_head. This defaults to true and should almost always be true.
bool room_refs {true};
/// Whether to update the event_sender index.
bool event_sender {true};
};
/// Types of references indexed by event_refs. This is a single byte integer,
@ -250,6 +259,14 @@ namespace ircd::m::dbs::desc
extern const db::comparator events__event_refs__cmp;
extern const db::descriptor events__event_refs;
// events sender
extern conf::item<size_t> events__event_sender__block__size;
extern conf::item<size_t> events__event_sender__meta_block__size;
extern conf::item<size_t> events__event_sender__cache__size;
extern conf::item<size_t> events__event_sender__cache_comp__size;
extern const db::prefix_transform events__event_sender__pfx;
extern const db::descriptor events__event_sender;
// room head mapping sequence
extern conf::item<size_t> events__room_head__block__size;
extern conf::item<size_t> events__room_head__meta_block__size;
@ -304,6 +321,7 @@ namespace ircd::m::dbs
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_event_sender(db::txn &, const event &, const write_opts &);
void _index_event_refs_m_room_redaction(db::txn &, const event &, const write_opts &);
void _index_event_refs_m_receipt_m_read(db::txn &, const event &, const write_opts &);
void _index_event_refs_m_relates_m_reply(db::txn &, const event &, const write_opts &);

View file

@ -36,6 +36,11 @@ decltype(ircd::m::dbs::event_refs)
ircd::m::dbs::event_refs
{};
/// Linkage for a reference to the event_sender column.
decltype(ircd::m::dbs::event_sender)
ircd::m::dbs::event_sender
{};
/// Linkage for a reference to the room_head column
decltype(ircd::m::dbs::room_head)
ircd::m::dbs::room_head
@ -140,6 +145,7 @@ ircd::m::dbs::init::init(std::string dbopts)
event_idx = db::column{*events, desc::events__event_idx.name};
event_json = db::column{*events, desc::events__event_json.name};
event_refs = db::index{*events, desc::events__event_refs.name};
event_sender = db::index{*events, desc::events__event_sender.name};
room_head = db::index{*events, desc::events__room_head.name};
room_events = db::index{*events, desc::events__room_events.name};
room_joined = db::index{*events, desc::events__room_joined.name};
@ -326,6 +332,9 @@ ircd::m::dbs::_index_event(db::txn &txn,
if(opts.event_refs.any())
_index_event_refs(txn, event, opts);
if(opts.event_sender)
_index_event_sender(txn, event, opts);
}
void
@ -721,6 +730,30 @@ ircd::m::dbs::_index_event_refs_m_room_redaction(db::txn &txn,
};
}
void
ircd::m::dbs::_index_event_sender(db::txn &txn,
const event &event,
const write_opts &opts)
{
assert(opts.event_sender);
assert(opts.event_idx);
assert(json::get<"sender"_>(event));
thread_local char buf[EVENT_SENDER_KEY_MAX_SIZE];
const string_view &key
{
event_sender_key(buf, at<"sender"_>(event), opts.event_idx)
};
db::txn::append
{
txn, dbs::event_sender,
{
opts.op, key, string_view{}
}
};
}
ircd::string_view
ircd::m::dbs::_index_room(db::txn &txn,
const event &event,
@ -1559,6 +1592,185 @@ ircd::m::dbs::desc::events__event_refs
size_t(events__event_refs__meta_block__size),
};
//
// event_sender
//
decltype(ircd::m::dbs::desc::events__event_sender__block__size)
ircd::m::dbs::desc::events__event_sender__block__size
{
{ "name", "ircd.m.dbs.events._event_sender.block.size" },
{ "default", 512L },
};
decltype(ircd::m::dbs::desc::events__event_sender__meta_block__size)
ircd::m::dbs::desc::events__event_sender__meta_block__size
{
{ "name", "ircd.m.dbs.events._event_sender.meta_block.size" },
{ "default", 4096L },
};
decltype(ircd::m::dbs::desc::events__event_sender__cache__size)
ircd::m::dbs::desc::events__event_sender__cache__size
{
{
{ "name", "ircd.m.dbs.events._event_sender.cache.size" },
{ "default", long(16_MiB) },
}, []
{
const size_t &value{events__event_sender__cache__size};
db::capacity(db::cache(event_sender), value);
}
};
decltype(ircd::m::dbs::desc::events__event_sender__cache_comp__size)
ircd::m::dbs::desc::events__event_sender__cache_comp__size
{
{
{ "name", "ircd.m.dbs.events._event_sender.cache_comp.size" },
{ "default", long(0_MiB) },
}, []
{
const size_t &value{events__event_sender__cache_comp__size};
db::capacity(db::cache_compressed(event_sender), value);
}
};
ircd::string_view
ircd::m::dbs::event_sender_key(const mutable_buffer &out,
const user::id &user_id,
const event::idx &event_idx)
{
return event_sender_key(out, user_id.host(), user_id.local(), event_idx);
}
ircd::string_view
ircd::m::dbs::event_sender_key(const mutable_buffer &out_,
const string_view &origin,
const string_view &localpart,
const event::idx &event_idx)
{
assert(size(out_) >= EVENT_SENDER_KEY_MAX_SIZE);
assert(!event_idx || localpart);
assert(!localpart || startswith(localpart, '@'));
mutable_buffer out{out_};
consume(out, copy(out, origin));
consume(out, copy(out, localpart));
if(localpart && event_idx)
{
consume(out, copy(out, "\0"_sv));
consume(out, copy(out, byte_view<string_view>(event_idx)));
}
return { data(out_), data(out) };
}
std::tuple<ircd::string_view, ircd::m::event::idx>
ircd::m::dbs::event_sender_key(const string_view &amalgam)
{
const auto &parts
{
split(amalgam, '\0')
};
assert(!empty(parts.first) && !empty(parts.second));
assert(startswith(parts.first, '@'));
return
{
parts.first,
byte_view<event::idx>(parts.second),
};
}
const ircd::db::prefix_transform
ircd::m::dbs::desc::events__event_sender__pfx
{
"_event_sender",
[](const string_view &key)
{
return has(key, '@');
},
[](const string_view &key)
{
const auto &parts
{
split(key, '@')
};
return parts.first;
}
};
const ircd::db::descriptor
ircd::m::dbs::desc::events__event_sender
{
// name
"_event_sender",
// explanation
R"(Index of senders to their events.
origin | localpart, event_idx => --
The senders of events are indexes by this column. This allows for all
events from a sender to be iterated. Additionally, all events from a
server and all known servers can be iterated from this column.
They key is made from a user mxid and an event_id, where the mxid is
part-swapped so the origin comes first, and the @localpart comes after.
Lookups can be performed for an origin or a full user_mxid.
The prefix transform is in effect; the prefix domain is the origin. We
can efficiently iterate all events from an origin. We can slightly less
efficiently iterate all users from an origin, as well as iterate all
origins known.
Note that the indexer of this column ignores the actual "origin" field
of an event. Only the "sender" data is used here.
)",
// typing (key, value)
{
typeid(string_view), typeid(string_view)
},
// options
{},
// comparator
{},
// prefix transform
events__event_sender__pfx,
// drop column
false,
// cache size
bool(events_cache_enable)? -1 : 0, //uses conf item
// cache size for compressed assets
bool(events_cache_comp_enable)? -1 : 0,
// bloom filter bits
0,
// expect queries hit
false,
// block size
size_t(events__event_sender__block__size),
// meta_block size
size_t(events__event_sender__meta_block__size),
};
//
// room_head
//
@ -3746,6 +3958,10 @@ ircd::m::dbs::desc::events
// Reverse mapping of the event reference graph.
events__event_refs,
// origin | sender, event_idx
// Mapping of senders to event_idx's they are the sender of.
events__event_sender,
// (room_id, (depth, event_idx)) => (state_root)
// Sequence of all events for a room, ever.
events__room_events,