0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-09-26 18:38:52 +02:00

ircd:Ⓜ️:room::head: Improve/cleanup generator related.

This commit is contained in:
Jason Volk 2019-12-10 11:07:44 -08:00
parent 5c74bfbd7f
commit 275f5aa3cd

View file

@ -8,12 +8,18 @@
// copyright notice and this permission notice is present in all copies. The // copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file. // full license for this software is available in the LICENSE file.
namespace ircd::m
{
static void append_v1(json::stack::array &, const event::id &);
static void append_v3(json::stack::array &, const event::id &);
}
IRCD_MODULE_EXPORT IRCD_MODULE_EXPORT
ircd::m::room::head::generate::generate(const mutable_buffer &buf, ircd::m::room::head::generate::generate(const mutable_buffer &buf,
const m::room::head &head, const m::room::head &head,
const opts &opts) const opts &opts)
{ {
if(!head.room) if(empty(buf))
return; return;
json::stack out{buf}; json::stack out{buf};
@ -42,37 +48,23 @@ ircd::m::room::head::generate::generate(json::stack::array &out,
if(!head.room) if(!head.room)
return; return;
const m::event::id::closure &v1_ref{[&out] // Query the room version unless hinted in the opts
(const auto &event_id)
{
json::stack::array prev{out};
prev.append(event_id);
{
json::stack::object nilly{prev};
json::stack::member willy
{
nilly, "", ""
};
}
}};
const m::event::id::closure &v3_ref{[&out]
(const auto &event_id)
{
out.append(event_id);
}};
char versionbuf[32]; char versionbuf[32];
const auto version const auto version
{ {
m::version(versionbuf, head.room, std::nothrow) m::version(versionbuf, head.room, std::nothrow)
}; };
// The output format depends on the room version; we select an output
// function for the format here so we can abstractly call append().
const auto &append const auto &append
{ {
version == "1" || version == "2"? v1_ref : v3_ref version == "1" || version == "2"?
append_v1:
append_v3
}; };
// When the top_head option is given we query for that here
const auto top_head const auto top_head
{ {
opts.need_top_head? opts.need_top_head?
@ -80,82 +72,81 @@ ircd::m::room::head::generate::generate(json::stack::array &out,
std::tuple<m::id::event::buf, int64_t, m::event::idx>{} std::tuple<m::id::event::buf, int64_t, m::event::idx>{}
}; };
m::event::fetch event; // Iterate the room head; starts with oldest events
size_t limit{opts.limit};
bool need_top_head{opts.need_top_head}; bool need_top_head{opts.need_top_head};
bool need_my_head{opts.need_my_head}; bool need_my_head{opts.need_my_head};
head.for_each([&](const m::event::idx &event_idx, const m::event::id &event_id) ssize_t limit(opts.limit);
head.for_each([&]
(const event::idx &event_idx, const event::id &event_id)
{ {
if(!seek(event, event_idx, event_id, std::nothrow)) // When using the need_my_head option, if we hit a head which
return true; // originated from this server we mark that is no longer needed.
if(need_my_head && event::my(event_idx))
need_my_head = false;
if(need_top_head) // If we hit the top_head during the loop we can mark that satisfied.
if(event.event_id == std::get<0>(top_head)) if(need_top_head && event_id == std::get<0>(top_head))
need_top_head = false; need_top_head = false;
const auto _append{[&]() -> bool // Two reference slots are reserved to fulfill these features; the
// loop will iterate without appending anything else.
const ssize_t remain
{ {
if(need_my_head && my(event)) limit - need_my_head - need_top_head
need_my_head = false; };
append(event_id); // Skip/continue the loop if all that remains are reserved slots.
this->depth[0] = std::min(json::get<"depth"_>(event), this->depth[0]); if(remain <= 0)
this->depth[1] = std::max(json::get<"depth"_>(event), this->depth[1]); return true;
return --limit - need_top_head - need_my_head > 0;
}};
if(limit - need_top_head - need_my_head > 0) // Add this head reference to result to output.
append(out, event_id);
// Determine the depth for metrics
const int64_t depth
{ {
if(need_my_head && my(event)) event_id == std::get<0>(top_head)?
need_my_head = false; std::get<int64_t>(top_head):
m::get<int64_t>(event_idx, "depth")
};
return _append(); // Indicate if this depth is highest or lowest of the set.
} this->depth[0] = std::min(depth, this->depth[0]);
this->depth[1] = std::max(depth, this->depth[1]);
if(!need_my_head) // Continue loop until we're out of slots.
return false; return --limit > 0;
if(my(event))
return _append();
else
return limit > 0;
}); });
// If the iteration did not provide us with the top_head and the opts
// require it, we add that here.
if(need_top_head) if(need_top_head)
{ {
assert(limit > 0); assert(limit > 0);
append(std::get<0>(top_head)); append(out, std::get<0>(top_head));
this->depth[1] = std::get<1>(top_head); this->depth[1] = std::get<1>(top_head);
need_top_head = false;
--limit; --limit;
} }
if(!need_my_head || limit <= 0) // If the iteration did not provide us with any heads from this origin
return; // and the opts require it, we find and add that here.
if(need_my_head)
for(m::room::events it{head.room}; it; --it) for(m::room::events it{head.room}; it; --it)
{ {
const bool my_sender if(!event::my(it.event_idx()))
{
m::query<bool>(std::nothrow, event::idx{it}, "sender", false, []
(const m::user::id &user_id)
{
return m::my(user_id);
})
};
if(!my_sender)
continue; continue;
const auto event_id const auto event_id
{ {
m::event_id(event::idx{it}, std::nothrow) m::event_id(it.event_idx(), std::nothrow)
}; };
if(!event_id) if(unlikely(!event_id))
continue; continue;
assert(limit > 0); assert(limit > 0);
append(event_id); append(out, event_id);
const int64_t &depth(it.depth()); const int64_t &depth(it.depth());
this->depth[0] = std::min(depth, this->depth[0]); this->depth[0] = std::min(depth, this->depth[0]);
this->depth[1] = std::max(depth, this->depth[1]); this->depth[1] = std::max(depth, this->depth[1]);
@ -163,6 +154,39 @@ ircd::m::room::head::generate::generate(json::stack::array &out,
--limit; --limit;
break; break;
} }
assert(limit >= 0);
}
void
ircd::m::append_v1(json::stack::array &out,
const event::id &event_id)
{
json::stack::array prev
{
out
};
// [0]
prev.append(event_id);
// [1]
json::stack::object nilly
{
prev
};
json::stack::member
{
nilly, "", ""
};
}
void
ircd::m::append_v3(json::stack::array &out,
const event::id &event_id)
{
out.append(event_id);
} }
size_t size_t