mirror of
https://github.com/matrix-construct/construct
synced 2024-10-04 06:38:58 +02:00
ircd:Ⓜ️:events: Optimize query pattern for sender iterations.
This commit is contained in:
parent
e58434705e
commit
6a8a7451d9
1 changed files with 41 additions and 27 deletions
|
@ -399,10 +399,14 @@ ircd::m::events::for_each_type(const string_view &prefix,
|
||||||
if(type == last)
|
if(type == last)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(!startswith(type, prefix))
|
if(prefix && !startswith(type, prefix))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
last = { lastbuf, copy(lastbuf, type) };
|
last =
|
||||||
|
{
|
||||||
|
lastbuf, copy(lastbuf, type)
|
||||||
|
};
|
||||||
|
|
||||||
if(!closure(type))
|
if(!closure(type))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -419,11 +423,9 @@ ircd::m::events::for_each_sender(const closure_sender_name_bool &closure)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IRCD_MODULE_EXPORT
|
IRCD_MODULE_EXPORT
|
||||||
ircd::m::events::for_each_sender(const string_view &hostlb,
|
ircd::m::events::for_each_sender(const string_view &prefix_,
|
||||||
const closure_sender_name_bool &closure)
|
const closure_sender_name_bool &closure)
|
||||||
{
|
{
|
||||||
assert(!startswith(hostlb, '@'));
|
|
||||||
|
|
||||||
db::column &column
|
db::column &column
|
||||||
{
|
{
|
||||||
dbs::event_sender
|
dbs::event_sender
|
||||||
|
@ -434,36 +436,41 @@ ircd::m::events::for_each_sender(const string_view &hostlb,
|
||||||
dbs::desc::events__event_sender__pfx
|
dbs::desc::events__event_sender__pfx
|
||||||
};
|
};
|
||||||
|
|
||||||
user::id::buf last;
|
// We MUST query the column with a key starting with '@' here. For a more
|
||||||
string_view last_local, last_host;
|
// convenient API, if the user did not supply an '@' we prefix it for them.
|
||||||
for(auto it(column.lower_bound(hostlb)); bool(it); ++it)
|
char prebuf[id::user::buf::SIZE] {"@"};
|
||||||
|
const string_view prefix
|
||||||
{
|
{
|
||||||
const string_view &host
|
!startswith(prefix_, '@')?
|
||||||
|
strlcat{prebuf, prefix_}:
|
||||||
|
prefix_
|
||||||
|
};
|
||||||
|
|
||||||
|
m::user::id::buf last;
|
||||||
|
for(auto it(column.lower_bound(prefix)); bool(it); ++it)
|
||||||
|
{
|
||||||
|
// Check if this is an '@' key; otherwise it's in the origin
|
||||||
|
// keyspace (sharing this column) which we don't want here.
|
||||||
|
if(!m::dbs::is_event_sender_key(it->first))
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Apply the domain prefixer, since we're iterating as a db::column
|
||||||
|
// rather than db::domain.
|
||||||
|
const m::user::id &user_id
|
||||||
{
|
{
|
||||||
prefixer.get(it->first)
|
prefixer.get(it->first)
|
||||||
};
|
};
|
||||||
|
|
||||||
if(!startswith(host, hostlb))
|
if(user_id == last)
|
||||||
break;
|
|
||||||
|
|
||||||
const auto &[localpart, event_idx]
|
|
||||||
{
|
|
||||||
dbs::event_sender_key(it->first.substr(size(host)))
|
|
||||||
};
|
|
||||||
|
|
||||||
if(last && host == last_host && localpart == last_local)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
last = m::user::id::buf
|
if(!startswith(user_id, prefix))
|
||||||
{
|
break;
|
||||||
localpart, host
|
|
||||||
};
|
|
||||||
|
|
||||||
if(!closure(last))
|
if(!closure(user_id))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
last_local = last.local();
|
last = user_id;
|
||||||
last_host = last.host();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -481,8 +488,6 @@ IRCD_MODULE_EXPORT
|
||||||
ircd::m::events::for_each_origin(const string_view &prefix,
|
ircd::m::events::for_each_origin(const string_view &prefix,
|
||||||
const closure_origin_name_bool &closure)
|
const closure_origin_name_bool &closure)
|
||||||
{
|
{
|
||||||
assert(!startswith(hostlb, '@'));
|
|
||||||
|
|
||||||
db::column &column
|
db::column &column
|
||||||
{
|
{
|
||||||
dbs::event_sender
|
dbs::event_sender
|
||||||
|
@ -493,10 +498,19 @@ ircd::m::events::for_each_origin(const string_view &prefix,
|
||||||
dbs::desc::events__event_sender__pfx
|
dbs::desc::events__event_sender__pfx
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if(unlikely(startswith(prefix, '@')))
|
||||||
|
throw panic
|
||||||
|
{
|
||||||
|
"Prefix argument should be a hostname. It must not start with '@'"
|
||||||
|
};
|
||||||
|
|
||||||
string_view last;
|
string_view last;
|
||||||
char buf[rfc3986::DOMAIN_BUFSIZE];
|
char buf[rfc3986::DOMAIN_BUFSIZE];
|
||||||
for(auto it(column.lower_bound(prefix)); bool(it); ++it)
|
for(auto it(column.lower_bound(prefix)); bool(it); ++it)
|
||||||
{
|
{
|
||||||
|
if(!m::dbs::is_event_sender_origin_key(it->first))
|
||||||
|
break;
|
||||||
|
|
||||||
const string_view &host
|
const string_view &host
|
||||||
{
|
{
|
||||||
prefixer.get(it->first)
|
prefixer.get(it->first)
|
||||||
|
|
Loading…
Reference in a new issue