0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-09-28 19:58:53 +02:00

ircd:Ⓜ️:room::timeline: Improve iteration.

This commit is contained in:
Jason Volk 2019-07-22 16:06:22 -07:00
parent cc9ce9c8a5
commit eb38a9ce15
3 changed files with 87 additions and 44 deletions

View file

@ -21,15 +21,18 @@ namespace ircd::m
struct ircd::m::room::timeline struct ircd::m::room::timeline
{ {
struct coord; struct coord;
using closure = std::function<bool (const coord &, const event::idx &)>; using closure = std::function<coord &(coord &, const event::idx &)>;
m::room room; m::room room;
public: public:
static event::idx next(const event::idx &, const int64_t &x = 0);
bool has_past(const event::id &) const; bool has_past(const event::id &) const;
bool has_future(const event::id &) const; bool has_future(const event::id &) const;
bool for_each(const closure &, const coord &branch) const; bool for_each(coord &, const closure &) const;
bool for_each(const closure &) const;
timeline(const m::room &); timeline(const m::room &);
timeline() = default; timeline() = default;

View file

@ -9273,19 +9273,29 @@ console_cmd__room__timeline(opt &out, const string_view &line)
room room
}; };
int64_t last_depth(0); const auto closure{[&out, &room]
const auto closure{[&out, &last_depth] (auto &coord, const auto &event_idx)
(const auto &coord, const auto &event_idx) -> m::room::timeline::coord &
{ {
if(coord.y > m::depth(std::nothrow, room))
return coord;
if(!event_idx)
{
++coord.y;
return coord;
}
const m::event::fetch event const m::event::fetch event
{ {
event_idx, std::nothrow event_idx, std::nothrow
}; };
if(json::get<"depth"_>(event) > last_depth + 1) if(!event.valid)
out << std::endl; {
++coord.x;
last_depth = json::get<"depth"_>(event); return coord;
}
out << "(" out << "("
<< std::left << std::left
@ -9300,14 +9310,17 @@ console_cmd__room__timeline(opt &out, const string_view &line)
<< pretty_oneline(event, false) << pretty_oneline(event, false)
<< std::endl; << std::endl;
return true; ++coord.x;
return coord;
}}; }};
timeline.for_each(closure, m::room::timeline::coord coord
{ {
param.at<int64_t>("x", 0), param.at<long>("x", 0L),
param.at<int64_t>("y", 0) param.at<long>("y", 0L),
}); };
timeline.for_each(coord, closure);
return true; return true;
} }

View file

@ -31,49 +31,48 @@ ircd::m::room::timeline::timeline(const m::room &room)
} }
bool bool
ircd::m::room::timeline::for_each(const closure &closure, ircd::m::room::timeline::for_each(const closure &closure)
const coord &branch)
const const
{ {
m::event::refs refs struct coord coord;
return for_each(coord, closure);
}
bool
ircd::m::room::timeline::for_each(coord &coord,
const closure &closure)
const
{
messages it
{ {
room.event_id? this->room, uint64_t(coord.y)
index(room.event_id):
room::index(room)
}; };
if(!refs.idx) if(!it)
return true; return true;
timeline::coord coord; event::idx next(it.event_idx()); do
if(!closure(coord, refs.idx))
return false;
for(++coord.y; coord.y <= branch.y; ++coord.y, coord.x = 0)
{ {
auto idx(0); const auto last(coord);
refs.for_each(dbs::ref::NEXT, [&coord, &branch, &idx] coord = closure(coord, next);
(const auto &event_idx, const auto &) if(coord.x == last.x && coord.y == last.y)
{
if(coord.x <= branch.x)
idx = event_idx;
if(coord.x < branch.x)
{
++coord.x;
return true;
}
else return false;
});
if(!idx)
return true; return true;
if(!closure(coord, idx)) if(coord.y != last.y)
if(!it.seek(coord.y))
return true;
next = timeline::next(it.event_idx(), coord.x);
if(next == 0 && coord.x == 0)
continue;
if(next == it.event_idx())
return false; return false;
refs.idx = idx; if(next == 0)
coord.x = 0;
} }
while(1);
return true; return true;
} }
@ -93,6 +92,10 @@ const
return true; return true;
} }
//
// static util
//
void void
ircd::m::room::timeline::rebuild(const m::room &room) ircd::m::room::timeline::rebuild(const m::room &room)
{ {
@ -123,3 +126,27 @@ ircd::m::room::timeline::rebuild(const m::room &room)
txn(); txn();
} }
ircd::m::event::idx
ircd::m::room::timeline::next(const event::idx &event_idx,
const int64_t &x)
{
const m::event::refs refs
{
event_idx
};
int64_t _x(0);
event::idx ret(0);
refs.for_each(dbs::ref::NEXT, [&_x, &x, &ret]
(const auto &event_idx, const auto &)
{
if(_x++ < x)
return true;
ret = event_idx;
return false;
});
return ret;
}