0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2025-01-20 19:41:55 +01:00

ircd:Ⓜ️:users: Improve users iteration w/ optimized events:: interface.

This commit is contained in:
Jason Volk 2019-08-19 19:06:14 -07:00
parent 6a8a7451d9
commit 26058e86ce

View file

@ -61,9 +61,36 @@ IRCD_MODULE_EXPORT
ircd::m::users::for_each(const opts &opts, ircd::m::users::for_each(const opts &opts,
const user::closure_bool &closure) const user::closure_bool &closure)
{ {
// Note: if opts.hostpart is given then for_each_host() will close over // Branch to a better query for hosts when there's no localpart given.
// that host, so no branch is needed here. if(opts.hostpart && (!opts.localpart || opts.localpart == "@"))
return for_each_host(opts, closure); return for_each_host(opts, closure);
bool ret{true};
events::for_each_sender(opts.localpart, [&opts, &ret, &closure]
(const id::user &sender)
{
if(opts.localpart && !opts.localpart_prefix)
if(sender.local() != opts.localpart)
return false;
if(opts.localpart && opts.localpart_prefix)
if(!startswith(sender.local(), opts.localpart))
return false;
if(opts.hostpart && !opts.hostpart_prefix)
if(sender.host() != opts.hostpart)
return true;
if(opts.hostpart && opts.hostpart_prefix)
if(!startswith(sender.host(), opts.hostpart))
return true;
// Call the user with match.a
ret = closure(sender);
return ret;
});
return ret;
} }
bool bool
@ -74,15 +101,17 @@ ircd::m::users::for_each_host(const opts &opts,
events::for_each_origin(opts.hostpart, [&ret, &opts, &closure] events::for_each_origin(opts.hostpart, [&ret, &opts, &closure]
(const string_view &origin) (const string_view &origin)
{ {
// The events:: iteration interface works with prefixes; if our
// user wants to iterate users on exactly a single server, we test
// for an exact match here and can break from the loop if no match.
if(opts.hostpart && !opts.hostpart_prefix) if(opts.hostpart && !opts.hostpart_prefix)
if(origin != opts.hostpart) if(origin != opts.hostpart)
return false; return false;
if(opts.hostpart && opts.hostpart_prefix)
if(!startswith(origin, opts.hostpart))
return false;
auto _opts(opts); auto _opts(opts);
_opts.hostpart = origin; _opts.hostpart = origin;
_opts.hostpart_prefix = false;
ret = for_each_in_host(_opts, closure); ret = for_each_in_host(_opts, closure);
return ret; return ret;
}); });
@ -94,32 +123,33 @@ bool
ircd::m::users::for_each_in_host(const opts &opts, ircd::m::users::for_each_in_host(const opts &opts,
const user::closure_bool &closure) const user::closure_bool &closure)
{ {
assert(opts.hostpart);
bool ret{true}; bool ret{true};
events::for_each_sender(opts.hostpart, [&opts, &ret, &closure] m::user::id::buf last;
(const id::user &sender) events::for_each_in_origin(opts.hostpart, [&opts, &ret, &closure, &last]
(const id::user &sender, const auto &event_idx)
{ {
// The events:: iteration interface only tests if the sender's if(sender == last)
// hostpart startswith our queried hostpart; we want an exact return true;
// match here, otherwise our loop can finish.
if(opts.hostpart && !opts.hostpart_prefix)
if(sender.host() != opts.hostpart) if(sender.host() != opts.hostpart)
return false; return false;
// Skip this entry if the user wants a prefix match on the localpart if(opts.hostpart && opts.hostpart_prefix)
// and this mxid doesn't match. if(!startswith(sender.host(), opts.hostpart))
return false;
if(opts.localpart && opts.localpart_prefix) if(opts.localpart && opts.localpart_prefix)
if(!startswith(sender.local(), opts.localpart)) if(!startswith(sender.local(), opts.localpart))
return true; return true;
// Skip this entry if the user wants an exact match on the localpart
// and this mxid doesn't match.
if(opts.localpart && !opts.localpart_prefix) if(opts.localpart && !opts.localpart_prefix)
if(sender.local() != opts.localpart) if(sender.local() != opts.localpart)
return true; return true;
// Call the user with match. // Call the user with match.
ret = closure(sender); ret = closure(sender);
last = sender;
return ret; return ret;
}); });
@ -133,6 +163,7 @@ ircd::m::users::opts::opts(const string_view &query)
{ {
localpart = split(query, ':').first; localpart = split(query, ':').first;
hostpart = split(query, ':').second; hostpart = split(query, ':').second;
hostpart_prefix = !has(hostpart, '.');
return; return;
} }
@ -146,9 +177,10 @@ ircd::m::users::opts::opts(const string_view &query)
if(startswith(query, ':')) if(startswith(query, ':'))
{ {
hostpart = lstrip(query, ':'); hostpart = lstrip(query, ':');
hostpart_prefix = !has(hostpart, '.');
return; return;
} }
hostpart = query; localpart = query;
hostpart_prefix = true; localpart_prefix = true;
} }