0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-29 18:22:50 +01:00

modules/client/sync/rooms/state: Simplify and optimize member event fetching at phase=0.

This commit is contained in:
Jason Volk 2019-09-18 14:13:41 -07:00
parent 2603953809
commit da6ae72b69

View file

@ -416,21 +416,9 @@ bool
ircd::m::sync::room_state_phased_member_events(data &data,
json::stack::array &array)
{
static const auto count{20}, bufsz{32}, limit{20};
size_t i(0), ret(0);
std::array<char[bufsz], count> buf;
std::array<string_view, count> last;
const auto already
static const size_t &count
{
[&last, &ret](const string_view &sender) -> bool
{
return std::any_of(begin(last), begin(last)+ret, [&sender]
(const auto &last)
{
return startswith(sender, last);
});
}
20
};
m::room::events it
@ -438,25 +426,42 @@ ircd::m::sync::room_state_phased_member_events(data &data,
*data.room
};
for(; it && ret < count && i < limit; --it, ++i)
m::get(std::nothrow, it.event_idx(), "sender", [&]
// Prefetch the senders of the recent room events
size_t i(0), prefetched(0);
std::array<event::idx, count> event_idx;
for(; it && i < event_idx.size(); --it, ++i)
{
event_idx[i] = it.event_idx();
prefetched += m::prefetch(event_idx[i], "sender");
}
// Transform the senders into member event::idx's and prefetch events
std::transform(begin(event_idx), begin(event_idx) + i, begin(event_idx), [&data]
(const m::event::idx &event_idx)
{
const event::idx &member_idx
{
m::query(std::nothrow, event_idx, "sender", [&data]
(const string_view &sender)
{
if(already(sender))
return;
const auto sender_idx
{
data.room->get(std::nothrow, "m.room.member", sender)
return data.room->get(std::nothrow, "m.room.member", sender);
})
};
if(!sender_idx)
return;
m::prefetch(member_idx);
return member_idx;
});
// check if this is an m.room.member event in the timeline.
if(sender_idx == it.event_idx())
return;
// Eliminate duplicate member event::idx
std::sort(begin(event_idx), begin(event_idx) + i);
const auto end(std::unique(begin(event_idx), begin(event_idx) + i));
assert(std::distance(begin(event_idx), end) > 0 || i == 0);
// Fetch and stream those member events to client
bool ret{false};
std::for_each(begin(event_idx), end, [&data, &array, &ret]
(const event::idx &sender_idx)
{
const m::event::fetch event
{
sender_idx, std::nothrow
@ -465,9 +470,7 @@ ircd::m::sync::room_state_phased_member_events(data &data,
if(!event.valid)
return;
last.at(ret) = strlcpy(buf.at(ret), sender);
room_state_append(data, array, event, sender_idx, false);
++ret;
ret |= room_state_append(data, array, event, sender_idx, false);
});
return ret;