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:
parent
5c74bfbd7f
commit
275f5aa3cd
1 changed files with 105 additions and 81 deletions
|
@ -8,12 +8,18 @@
|
|||
// copyright notice and this permission notice is present in all copies. The
|
||||
// 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::m::room::head::generate::generate(const mutable_buffer &buf,
|
||||
const m::room::head &head,
|
||||
const opts &opts)
|
||||
{
|
||||
if(!head.room)
|
||||
if(empty(buf))
|
||||
return;
|
||||
|
||||
json::stack out{buf};
|
||||
|
@ -42,37 +48,23 @@ ircd::m::room::head::generate::generate(json::stack::array &out,
|
|||
if(!head.room)
|
||||
return;
|
||||
|
||||
const m::event::id::closure &v1_ref{[&out]
|
||||
(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);
|
||||
}};
|
||||
|
||||
// Query the room version unless hinted in the opts
|
||||
char versionbuf[32];
|
||||
const auto version
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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>{}
|
||||
};
|
||||
|
||||
m::event::fetch event;
|
||||
size_t limit{opts.limit};
|
||||
// Iterate the room head; starts with oldest events
|
||||
bool need_top_head{opts.need_top_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))
|
||||
return true;
|
||||
// When using the need_my_head option, if we hit a head which
|
||||
// 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(event.event_id == std::get<0>(top_head))
|
||||
// If we hit the top_head during the loop we can mark that satisfied.
|
||||
if(need_top_head && event_id == std::get<0>(top_head))
|
||||
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))
|
||||
need_my_head = false;
|
||||
limit - need_my_head - need_top_head
|
||||
};
|
||||
|
||||
append(event_id);
|
||||
this->depth[0] = std::min(json::get<"depth"_>(event), this->depth[0]);
|
||||
this->depth[1] = std::max(json::get<"depth"_>(event), this->depth[1]);
|
||||
return --limit - need_top_head - need_my_head > 0;
|
||||
}};
|
||||
// Skip/continue the loop if all that remains are reserved slots.
|
||||
if(remain <= 0)
|
||||
return true;
|
||||
|
||||
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))
|
||||
need_my_head = false;
|
||||
event_id == std::get<0>(top_head)?
|
||||
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)
|
||||
return false;
|
||||
|
||||
if(my(event))
|
||||
return _append();
|
||||
else
|
||||
return limit > 0;
|
||||
// Continue loop until we're out of slots.
|
||||
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)
|
||||
{
|
||||
assert(limit > 0);
|
||||
append(std::get<0>(top_head));
|
||||
append(out, std::get<0>(top_head));
|
||||
this->depth[1] = std::get<1>(top_head);
|
||||
need_top_head = false;
|
||||
--limit;
|
||||
}
|
||||
|
||||
if(!need_my_head || limit <= 0)
|
||||
return;
|
||||
|
||||
// If the iteration did not provide us with any heads from this origin
|
||||
// and the opts require it, we find and add that here.
|
||||
if(need_my_head)
|
||||
for(m::room::events it{head.room}; it; --it)
|
||||
{
|
||||
const bool my_sender
|
||||
{
|
||||
m::query<bool>(std::nothrow, event::idx{it}, "sender", false, []
|
||||
(const m::user::id &user_id)
|
||||
{
|
||||
return m::my(user_id);
|
||||
})
|
||||
};
|
||||
|
||||
if(!my_sender)
|
||||
if(!event::my(it.event_idx()))
|
||||
continue;
|
||||
|
||||
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;
|
||||
|
||||
assert(limit > 0);
|
||||
append(event_id);
|
||||
append(out, event_id);
|
||||
const int64_t &depth(it.depth());
|
||||
this->depth[0] = std::min(depth, this->depth[0]);
|
||||
this->depth[1] = std::max(depth, this->depth[1]);
|
||||
|
@ -163,6 +154,39 @@ ircd::m::room::head::generate::generate(json::stack::array &out,
|
|||
--limit;
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue