mirror of
https://github.com/matrix-construct/construct
synced 2024-10-01 21:28:53 +02:00
ircd:Ⓜ️:rooms: Consolidate / refine the rooms iteration interface.
This commit is contained in:
parent
25680a8ed2
commit
0fa4bdcff7
6 changed files with 134 additions and 138 deletions
|
@ -16,28 +16,13 @@
|
||||||
///
|
///
|
||||||
namespace ircd::m::rooms
|
namespace ircd::m::rooms
|
||||||
{
|
{
|
||||||
// All rooms known to IRCd
|
struct each_opts;
|
||||||
bool for_each(const string_view &room_id_lb, const room::id::closure_bool &);
|
|
||||||
bool for_each(const room::id::closure_bool &);
|
|
||||||
void for_each(const room::id::closure &);
|
|
||||||
bool for_each(const room::closure_bool &);
|
|
||||||
void for_each(const room::closure &);
|
|
||||||
|
|
||||||
// All rooms for a user (alias to interface in user::)
|
|
||||||
bool for_each(const user &, const string_view &membership, const user::rooms::closure_bool &);
|
|
||||||
void for_each(const user &, const string_view &membership, const user::rooms::closure &);
|
|
||||||
bool for_each(const user &, const user::rooms::closure_bool &);
|
|
||||||
void for_each(const user &, const user::rooms::closure &);
|
|
||||||
|
|
||||||
// All public rooms only; key is either a server hostname or room_id.
|
|
||||||
// - for server hostname: iterates known rooms from that server.
|
|
||||||
// - for room_id: starts iteration from that (or closest) room_id
|
|
||||||
// which can be used as a since/pagination token.
|
|
||||||
bool for_each_public(const string_view &key, const room::id::closure_bool &);
|
|
||||||
bool for_each_public(const room::id::closure_bool &);
|
|
||||||
|
|
||||||
size_t count_public(const string_view &server = {});
|
|
||||||
bool is_public(const room::id &);
|
bool is_public(const room::id &);
|
||||||
|
size_t count_public(const string_view &server = {});
|
||||||
|
|
||||||
|
bool for_each(const each_opts &);
|
||||||
|
template<class... args> bool for_each(args&&...);
|
||||||
|
|
||||||
// Linkage to utils that build a publicrooms summary from room state.
|
// Linkage to utils that build a publicrooms summary from room state.
|
||||||
void summary_chunk(const m::room &, json::stack::object &chunk);
|
void summary_chunk(const m::room &, json::stack::object &chunk);
|
||||||
|
@ -46,3 +31,79 @@ namespace ircd::m::rooms
|
||||||
event::id::buf summary_set(const m::room &);
|
event::id::buf summary_set(const m::room &);
|
||||||
event::id::buf summary_del(const m::room &);
|
event::id::buf summary_del(const m::room &);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Arguments structure to rooms::for_each(). This reduces the API surface to
|
||||||
|
/// handle a rich set of ways to iterate over the rooms. Several convenience
|
||||||
|
/// constructors based on common usage are provided; note that these are not
|
||||||
|
/// the only options patterns.
|
||||||
|
struct ircd::m::rooms::each_opts
|
||||||
|
{
|
||||||
|
/// If set: select rooms for this user.
|
||||||
|
m::user user;
|
||||||
|
|
||||||
|
/// If user is set, and this is set: select the membership that user
|
||||||
|
/// has in the room.
|
||||||
|
string_view membership;
|
||||||
|
|
||||||
|
/// If set, seek to this room_id or lower-bound to the closest room_id.
|
||||||
|
string_view key;
|
||||||
|
|
||||||
|
/// All public rooms only; key may be a server hostname or room_id.
|
||||||
|
/// - for server hostname: iterates known rooms from that server.
|
||||||
|
/// - for room_id: starts iteration from that (or closest) room_id
|
||||||
|
/// which can be used as a since/pagination token.
|
||||||
|
bool public_rooms {false};
|
||||||
|
|
||||||
|
/// Principal closure for results; invoked synchronously during the call;
|
||||||
|
/// for-each protocol: return true to continue, false to break.
|
||||||
|
room::id::closure_bool closure;
|
||||||
|
|
||||||
|
/// Alternative closure when selecting a user.
|
||||||
|
user::rooms::closure_bool user_closure;
|
||||||
|
|
||||||
|
each_opts(room::id::closure_bool);
|
||||||
|
each_opts(const string_view &key, room::id::closure_bool);
|
||||||
|
each_opts(const m::user &user, user::rooms::closure_bool);
|
||||||
|
each_opts(const m::user &user, const string_view &membership, user::rooms::closure_bool);
|
||||||
|
each_opts() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
ircd::m::rooms::each_opts::each_opts(room::id::closure_bool closure)
|
||||||
|
:closure{std::move(closure)}
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline
|
||||||
|
ircd::m::rooms::each_opts::each_opts(const string_view &key,
|
||||||
|
room::id::closure_bool closure)
|
||||||
|
:key{key}
|
||||||
|
,closure{std::move(closure)}
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline
|
||||||
|
ircd::m::rooms::each_opts::each_opts(const m::user &user,
|
||||||
|
user::rooms::closure_bool user_closure)
|
||||||
|
:user{user}
|
||||||
|
,user_closure{std::move(user_closure)}
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline
|
||||||
|
ircd::m::rooms::each_opts::each_opts(const m::user &user,
|
||||||
|
const string_view &membership,
|
||||||
|
user::rooms::closure_bool user_closure)
|
||||||
|
:user{user}
|
||||||
|
,membership{membership}
|
||||||
|
,user_closure{std::move(user_closure)}
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<class... args>
|
||||||
|
bool
|
||||||
|
ircd::m::rooms::for_each(args&&... a)
|
||||||
|
{
|
||||||
|
const each_opts opts
|
||||||
|
{
|
||||||
|
std::forward<args>(a)...
|
||||||
|
};
|
||||||
|
|
||||||
|
return for_each(opts);
|
||||||
|
}
|
||||||
|
|
105
ircd/m.cc
105
ircd/m.cc
|
@ -3020,38 +3020,17 @@ ircd::m::rooms::summary_chunk(const m::room &room,
|
||||||
return function(room, chunk);
|
return function(room, chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ircd::m::rooms::for_each(const user &user,
|
|
||||||
const user::rooms::closure &closure)
|
|
||||||
{
|
|
||||||
const m::user::rooms rooms{user};
|
|
||||||
rooms.for_each(closure);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ircd::m::rooms::for_each(const user &user,
|
ircd::m::rooms::for_each(const each_opts &opts)
|
||||||
const user::rooms::closure_bool &closure)
|
|
||||||
{
|
{
|
||||||
const m::user::rooms rooms{user};
|
using prototype = bool (const each_opts &);
|
||||||
return rooms.for_each(closure);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
static mods::import<prototype> call
|
||||||
ircd::m::rooms::for_each(const user &user,
|
|
||||||
const string_view &membership,
|
|
||||||
const user::rooms::closure &closure)
|
|
||||||
{
|
{
|
||||||
const m::user::rooms rooms{user};
|
"m_rooms", "ircd::m::rooms::for_each"
|
||||||
rooms.for_each(membership, closure);
|
};
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
return call(opts);
|
||||||
ircd::m::rooms::for_each(const user &user,
|
|
||||||
const string_view &membership,
|
|
||||||
const user::rooms::closure_bool &closure)
|
|
||||||
{
|
|
||||||
const m::user::rooms rooms{user};
|
|
||||||
return rooms.for_each(membership, closure);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -3080,78 +3059,6 @@ ircd::m::rooms::count_public(const string_view &server)
|
||||||
return function(server);
|
return function(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
ircd::m::rooms::for_each_public(const room::id::closure_bool &closure)
|
|
||||||
{
|
|
||||||
return for_each_public(string_view{}, closure);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ircd::m::rooms::for_each_public(const string_view &key,
|
|
||||||
const room::id::closure_bool &closure)
|
|
||||||
{
|
|
||||||
using prototype = bool (const string_view &, const room::id::closure_bool &);
|
|
||||||
|
|
||||||
static mods::import<prototype> function
|
|
||||||
{
|
|
||||||
"m_rooms", "_for_each_public"
|
|
||||||
};
|
|
||||||
|
|
||||||
return function(key, closure);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ircd::m::rooms::for_each(const room::closure &closure)
|
|
||||||
{
|
|
||||||
for_each(room::closure_bool{[&closure]
|
|
||||||
(const room &room)
|
|
||||||
{
|
|
||||||
closure(room);
|
|
||||||
return true;
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ircd::m::rooms::for_each(const room::closure_bool &closure)
|
|
||||||
{
|
|
||||||
return for_each(room::id::closure_bool{[&closure]
|
|
||||||
(const m::room::id &room_id)
|
|
||||||
{
|
|
||||||
return closure(room_id);
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ircd::m::rooms::for_each(const room::id::closure &closure)
|
|
||||||
{
|
|
||||||
for_each(string_view{}, [&closure]
|
|
||||||
(const m::room::id &room_id)
|
|
||||||
{
|
|
||||||
closure(room_id);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ircd::m::rooms::for_each(const room::id::closure_bool &closure)
|
|
||||||
{
|
|
||||||
return for_each(string_view{}, closure);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ircd::m::rooms::for_each(const string_view &room_id_lb,
|
|
||||||
const room::id::closure_bool &closure)
|
|
||||||
{
|
|
||||||
using prototype = bool (const string_view &, const room::id::closure_bool &);
|
|
||||||
|
|
||||||
static mods::import<prototype> call
|
|
||||||
{
|
|
||||||
"m_rooms", "ircd::m::rooms::for_each"
|
|
||||||
};
|
|
||||||
|
|
||||||
return call(room_id_lb, closure);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// m/users.h
|
// m/users.h
|
||||||
|
|
|
@ -122,8 +122,10 @@ get__publicrooms(client &client,
|
||||||
my_host()
|
my_host()
|
||||||
};
|
};
|
||||||
|
|
||||||
m::rooms::for_each_public(key, [&]
|
m::rooms::each_opts opts;
|
||||||
(const m::room::id &room_id)
|
opts.public_rooms = true;
|
||||||
|
opts.key = key;
|
||||||
|
opts.closure = [&](const m::room::id &room_id)
|
||||||
{
|
{
|
||||||
json::stack::object obj{chunk};
|
json::stack::object obj{chunk};
|
||||||
m::rooms::summary_chunk(room_id, obj);
|
m::rooms::summary_chunk(room_id, obj);
|
||||||
|
@ -133,7 +135,9 @@ get__publicrooms(client &client,
|
||||||
|
|
||||||
next_batch_buf = room_id;
|
next_batch_buf = room_id;
|
||||||
return ++count < limit;
|
return ++count < limit;
|
||||||
});
|
};
|
||||||
|
|
||||||
|
m::rooms::for_each(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
json::stack::member
|
json::stack::member
|
||||||
|
|
|
@ -6913,11 +6913,12 @@ console_cmd__eval__file(opt &out, const string_view &line)
|
||||||
bool
|
bool
|
||||||
console_cmd__rooms(opt &out, const string_view &line)
|
console_cmd__rooms(opt &out, const string_view &line)
|
||||||
{
|
{
|
||||||
m::rooms::for_each(m::room::id::closure{[&out]
|
m::rooms::for_each([&out]
|
||||||
(const m::room::id &room_id)
|
(const m::room::id &room_id)
|
||||||
{
|
{
|
||||||
out << room_id << std::endl;
|
out << room_id << std::endl;
|
||||||
}});
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -6940,13 +6941,17 @@ console_cmd__rooms__public(opt &out, const string_view &line)
|
||||||
param.at("limit", 32L)
|
param.at("limit", 32L)
|
||||||
};
|
};
|
||||||
|
|
||||||
m::rooms::for_each_public(key, [&limit, &out]
|
m::rooms::each_opts opts;
|
||||||
|
opts.public_rooms = true;
|
||||||
|
opts.key = key;
|
||||||
|
opts.closure = [&limit, &out]
|
||||||
(const m::room::id &room_id) -> bool
|
(const m::room::id &room_id) -> bool
|
||||||
{
|
{
|
||||||
out << room_id << std::endl;
|
out << room_id << std::endl;
|
||||||
return --limit > 0;
|
return --limit > 0;
|
||||||
});
|
};
|
||||||
|
|
||||||
|
m::rooms::for_each(opts);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8146,7 +8151,7 @@ console_cmd__room__state__rebuild__present(opt &out, const string_view &line)
|
||||||
|
|
||||||
if(room_id == "*")
|
if(room_id == "*")
|
||||||
{
|
{
|
||||||
m::rooms::for_each(m::room::id::closure{[&out]
|
m::rooms::for_each([&out]
|
||||||
(const m::room::id &room_id)
|
(const m::room::id &room_id)
|
||||||
{
|
{
|
||||||
const m::room room{room_id};
|
const m::room room{room_id};
|
||||||
|
@ -8157,7 +8162,8 @@ console_cmd__room__state__rebuild__present(opt &out, const string_view &line)
|
||||||
};
|
};
|
||||||
|
|
||||||
out << "done " << room_id << " " << count << std::endl;
|
out << "done " << room_id << " " << count << std::endl;
|
||||||
}});
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,14 +105,18 @@ handle_get(client &client,
|
||||||
since?: my_host()
|
since?: my_host()
|
||||||
};
|
};
|
||||||
|
|
||||||
m::rooms::for_each_public(key, [&]
|
m::rooms::each_opts opts;
|
||||||
(const m::room::id &room_id)
|
opts.public_rooms = true;
|
||||||
|
opts.key = key;
|
||||||
|
opts.closure = [&](const m::room::id &room_id)
|
||||||
{
|
{
|
||||||
json::stack::object obj{chunk};
|
json::stack::object obj{chunk};
|
||||||
m::rooms::summary_chunk(room_id, obj);
|
m::rooms::summary_chunk(room_id, obj);
|
||||||
next_batch_buf = room_id;
|
next_batch_buf = room_id;
|
||||||
return ++count < limit;
|
return ++count < limit;
|
||||||
});
|
};
|
||||||
|
|
||||||
|
m::rooms::for_each(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
json::stack::member
|
json::stack::member
|
||||||
|
|
|
@ -65,21 +65,35 @@ ircd::m::rooms::create_public_room(const m::event &,
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IRCD_MODULE_EXPORT
|
IRCD_MODULE_EXPORT
|
||||||
ircd::m::rooms::for_each(const string_view &room_id_lb,
|
ircd::m::rooms::for_each(const each_opts &opts)
|
||||||
const room::id::closure_bool &closure)
|
|
||||||
{
|
{
|
||||||
|
if(opts.user.user_id)
|
||||||
|
{
|
||||||
|
const m::user::rooms rooms{opts.user};
|
||||||
|
return rooms.for_each(opts.membership, m::user::rooms::closure_bool{[&opts]
|
||||||
|
(const m::room &room, const string_view &membership)
|
||||||
|
{
|
||||||
|
return opts.user_closure?
|
||||||
|
opts.user_closure(room, membership):
|
||||||
|
opts.closure(room.room_id);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(opts.public_rooms)
|
||||||
|
return _for_each_public(opts.key, opts.closure);
|
||||||
|
|
||||||
const room::state state
|
const room::state state
|
||||||
{
|
{
|
||||||
my_room
|
my_room
|
||||||
};
|
};
|
||||||
|
|
||||||
const room::state::keys_bool keys{[&closure]
|
const room::state::keys_bool keys{[&opts]
|
||||||
(const string_view &room_id) -> bool
|
(const string_view &room_id) -> bool
|
||||||
{
|
{
|
||||||
return closure(room_id);
|
return opts.closure(room_id);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
return state.for_each("ircd.room", room_id_lb, keys);
|
return state.for_each("ircd.room", opts.key, keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -102,7 +116,7 @@ ircd::m::rooms::_count_public(const string_view &server)
|
||||||
return true;
|
return true;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
for_each_public(server, count);
|
_for_each_public(server, count);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue