mirror of
https://github.com/matrix-construct/construct
synced 2024-11-17 15:30:52 +01:00
ircd:Ⓜ️:dbs: Add event_sender metadata column.
This commit is contained in:
parent
31bbc6b1b4
commit
8148dc6502
2 changed files with 234 additions and 0 deletions
|
@ -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 &);
|
||||
|
|
216
ircd/m_dbs.cc
216
ircd/m_dbs.cc
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue