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
|
// 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
|
||||||
|
|
Loading…
Reference in a new issue