ircd:Ⓜ️ Simplify room::events interface; separate event::fetch.

This commit is contained in:
Jason Volk 2023-02-17 19:49:23 -08:00
parent 23c8a6c5cb
commit f301d6641c
16 changed files with 173 additions and 152 deletions

View File

@ -21,20 +21,30 @@
/// ///
struct ircd::m::room::events struct ircd::m::room::events
{ {
using depth_range = std::pair<uint64_t, uint64_t>;
using entry = std::tuple<uint64_t, event::idx>;
static conf::item<ssize_t> viewport_size; static conf::item<ssize_t> viewport_size;
m::room room; m::room room;
db::domain::const_iterator it; db::domain::const_iterator it;
event::fetch _event; mutable entry _entry;
public: public:
explicit operator bool() const { return bool(it); } explicit operator bool() const;
bool operator!() const { return !it; } bool operator!() const;
// Fetch the actual event data at the iterator's position
const entry *operator->() const;
const entry &operator*() const;
// Observers from the current valid iterator // Observers from the current valid iterator
uint64_t depth() const;
event::idx event_idx() const; event::idx event_idx() const;
explicit operator event::idx() const; uint64_t depth() const;
// Move the iterator
auto &operator++();
auto &operator--();
// Perform a new lookup / iterator // Perform a new lookup / iterator
bool seek_idx(const event::idx &, const bool &lower_bound = false); bool seek_idx(const event::idx &, const bool &lower_bound = false);
@ -44,16 +54,6 @@ struct ircd::m::room::events
// Prefetch a new iterator lookup (async) // Prefetch a new iterator lookup (async)
bool preseek(const uint64_t &depth = -1); bool preseek(const uint64_t &depth = -1);
// Move the iterator
auto &operator++() { return --it; }
auto &operator--() { return ++it; }
// Fetch the actual event data at the iterator's position
const m::event &fetch(std::nothrow_t, bool *valid = nullptr);
const m::event &fetch();
const m::event &operator*() { return fetch(std::nothrow); }
const m::event *operator->() { return &operator*(); }
// Prefetch the actual event data at the iterator's position (async) // Prefetch the actual event data at the iterator's position (async)
bool prefetch(const string_view &event_prop); bool prefetch(const string_view &event_prop);
bool prefetch(); // uses supplied fetch::opts. bool prefetch(); // uses supplied fetch::opts.
@ -61,17 +61,17 @@ struct ircd::m::room::events
// Seeks to closest event in the room by depth; room.event_id ignored. // Seeks to closest event in the room by depth; room.event_id ignored.
events(const m::room &, events(const m::room &,
const uint64_t &depth, const uint64_t &depth,
const event::fetch::opts *const & = nullptr); const event::fetch::opts * = nullptr);
// Seeks to event_id; null iteration when not found; seekless when empty. // Seeks to event_id; null iteration when not found; seekless when empty.
events(const m::room &, events(const m::room &,
const event::id &, const event::id &,
const event::fetch::opts *const & = nullptr); const event::fetch::opts * = nullptr);
// Seeks to latest event in the room unless room.event_id given. Null // Seeks to latest event in the room unless room.event_id given. Null
// iteration when given and not found. // iteration when given and not found.
events(const m::room &, events(const m::room &,
const event::fetch::opts *const & = nullptr); const event::fetch::opts * = nullptr);
events() = default; events() = default;
events(const events &) = delete; events(const events &) = delete;
@ -81,7 +81,6 @@ struct ircd::m::room::events
static bool preseek(const m::room &, const uint64_t &depth = -1); static bool preseek(const m::room &, const uint64_t &depth = -1);
// Prefetch the actual room event data for a range; or most recent. // Prefetch the actual room event data for a range; or most recent.
using depth_range = std::pair<uint64_t, uint64_t>;
static size_t prefetch(const m::room &, const depth_range &); static size_t prefetch(const m::room &, const depth_range &);
static size_t prefetch_viewport(const m::room &); static size_t prefetch_viewport(const m::room &);
@ -90,3 +89,51 @@ struct ircd::m::room::events
static size_t count(const m::room &, const event::idx_range &); static size_t count(const m::room &, const event::idx_range &);
static size_t count(const event::idx_range &); static size_t count(const event::idx_range &);
}; };
inline auto &
ircd::m::room::events::operator++()
{
return --it;
}
inline auto &
ircd::m::room::events::operator--()
{
return ++it;
}
inline uint64_t
ircd::m::room::events::depth()
const
{
return std::get<0>(operator*());
}
inline ircd::m::event::idx
ircd::m::room::events::event_idx()
const
{
return std::get<1>(operator*());
}
inline
const ircd::m::room::events::entry &
ircd::m::room::events::operator*()
const
{
return *(operator->());
}
inline bool
ircd::m::room::events::operator!()
const
{
return !it;
}
inline ircd::m::room::events::operator
bool()
const
{
return bool(it);
}

View File

@ -367,16 +367,14 @@ ircd::m::media::file::read(const m::room &room,
encoding_bytes(0), encoding_bytes(0),
events_fetched(0), events_fetched(0),
events_prefetched(0); events_prefetched(0);
m::event::fetch event;
for(; it; ++it) try for(; it; ++it) try
{ {
for(; epf && events_prefetched < events_fetched + events_prefetch; ++epf) for(; epf && events_prefetched < events_fetched + events_prefetch; ++epf)
events_prefetched += epf.prefetch(); events_prefetched += epf.prefetch();
seek(event, it.event_idx());
++events_fetched; ++events_fetched;
const m::event &event
{
*it
};
if(json::get<"type"_>(event) != "ircd.file.block.b64") if(json::get<"type"_>(event) != "ircd.file.block.b64")
continue; continue;

View File

@ -15,10 +15,6 @@ ircd::m::room::events::viewport_size
{ "default", 96L }, { "default", 96L },
}; };
//
// room::events
//
size_t size_t
ircd::m::room::events::count(const m::event::idx_range &range) ircd::m::room::events::count(const m::event::idx_range &range)
{ {
@ -137,18 +133,14 @@ ircd::m::room::events::preseek(const m::room &room,
// //
ircd::m::room::events::events(const m::room &room, ircd::m::room::events::events(const m::room &room,
const event::fetch::opts *const &fopts) const event::fetch::opts *const fopts)
:room{room} :room{room}
,_event
{
fopts?
*fopts:
room.fopts?
*room.fopts:
event::fetch::default_opts
}
{ {
assert(room.room_id); assert(room.room_id);
if(fopts)
this->room.fopts = fopts;
const bool found const bool found
{ {
room.event_id? room.event_id?
@ -161,18 +153,14 @@ ircd::m::room::events::events(const m::room &room,
ircd::m::room::events::events(const m::room &room, ircd::m::room::events::events(const m::room &room,
const event::id &event_id, const event::id &event_id,
const event::fetch::opts *const &fopts) const event::fetch::opts *const fopts)
:room{room} :room{room}
,_event
{
fopts?
*fopts:
room.fopts?
*room.fopts:
event::fetch::default_opts
}
{ {
assert(room.room_id); assert(room.room_id);
if(fopts)
this->room.fopts = fopts;
const bool found const bool found
{ {
seek(event_id) seek(event_id)
@ -183,19 +171,14 @@ ircd::m::room::events::events(const m::room &room,
ircd::m::room::events::events(const m::room &room, ircd::m::room::events::events(const m::room &room,
const uint64_t &depth, const uint64_t &depth,
const event::fetch::opts *const &fopts) const event::fetch::opts *const fopts)
:room{room} :room{room}
,_event
{
fopts?
*fopts:
room.fopts?
*room.fopts:
event::fetch::default_opts
}
{ {
assert(room.room_id); assert(room.room_id);
if(fopts)
this->room.fopts = fopts;
// As a special convenience for the ctor only, if the depth=0 and // As a special convenience for the ctor only, if the depth=0 and
// nothing is found another attempt is made for depth=1 for synapse // nothing is found another attempt is made for depth=1 for synapse
// rooms which start at depth=1. // rooms which start at depth=1.
@ -206,8 +189,14 @@ ircd::m::room::events::events(const m::room &room,
bool bool
ircd::m::room::events::prefetch() ircd::m::room::events::prefetch()
{ {
assert(_event.fopts); const auto &fopts
return m::prefetch(event_idx(), *_event.fopts); {
room.fopts?
*room.fopts:
event::fetch::default_opts
};
return m::prefetch(event_idx(), fopts);
} }
bool bool
@ -216,28 +205,6 @@ ircd::m::room::events::prefetch(const string_view &event_prop)
return m::prefetch(event_idx(), event_prop); return m::prefetch(event_idx(), event_prop);
} }
const ircd::m::event &
ircd::m::room::events::fetch()
{
m::seek(_event, event_idx());
return _event;
}
const ircd::m::event &
ircd::m::room::events::fetch(std::nothrow_t,
bool *const valid_)
{
const bool valid
{
m::seek(std::nothrow, _event, event_idx())
};
if(valid_)
*valid_ = valid;
return _event;
}
bool bool
ircd::m::room::events::preseek(const uint64_t &depth) ircd::m::room::events::preseek(const uint64_t &depth)
{ {
@ -307,35 +274,11 @@ ircd::m::room::events::seek_idx(const event::idx &event_idx,
return true; return true;
} }
ircd::m::room::events::operator const ircd::m::room::events::entry *
ircd::m::event::idx() ircd::m::room::events::operator->()
const
{
return event_idx();
}
ircd::m::event::idx
ircd::m::room::events::event_idx()
const const
{ {
assert(bool(*this)); assert(bool(*this));
const auto part _entry = dbs::room_events_key(it->first);
{ return &_entry;
dbs::room_events_key(it->first)
};
return std::get<1>(part);
}
uint64_t
ircd::m::room::events::depth()
const
{
assert(bool(*this));
const auto part
{
dbs::room_events_key(it->first)
};
return std::get<0>(part);
} }

View File

@ -291,9 +291,9 @@ ircd::m::room::head::reset(const head &head)
return ret; return ret;
// Replacement will be the single new head // Replacement will be the single new head
const m::event replacement const m::event::fetch replacement
{ {
*it it.event_idx()
}; };
db::txn txn db::txn txn
@ -368,11 +368,17 @@ ircd::m::room::head::rebuild(const head &head)
*m::dbs::events *m::dbs::events
}; };
m::dbs::opts opts; m::dbs::opts opts
opts.op = db::op::SET; {
.op = db::op::SET,
};
m::event::fetch event;
for(; it; ++it) for(; it; ++it)
{ {
const m::event &event{*it}; if(!seek(std::nothrow, event, it.event_idx()))
continue;
opts.event_idx = it.event_idx(); opts.event_idx = it.event_idx();
opts.appendix.reset(); opts.appendix.reset();
opts.appendix.set(dbs::appendix::ROOM_HEAD); opts.appendix.set(dbs::appendix::ROOM_HEAD);

View File

@ -31,11 +31,13 @@ ircd::m::room::horizon::rebuild()
room room
}; };
m::event::fetch event;
for(; it; --it) for(; it; --it)
{ {
const m::event &event{*it}; if(!seek(std::nothrow, event, it.event_idx()))
const event::prev prev_events{event}; continue;
const event::prev prev_events{event};
opts.event_idx = it.event_idx(); opts.event_idx = it.event_idx();
m::for_each(prev_events, [&] m::for_each(prev_events, [&]
(const m::event::id &event_id) (const m::event::id &event_id)

View File

@ -82,28 +82,33 @@ ircd::m::room::missing::_each(m::room::events &it,
const closure &closure) const closure &closure)
const const
{ {
const m::event event const auto &[depth, event_idx]
{ {
*it *it
}; };
const m::event::fetch event
{
std::nothrow, event_idx
};
const event::prev prev const event::prev prev
{ {
event event
}; };
event::idx idx_buf[event::prev::MAX]; event::idx idx_buf[event::prev::MAX];
const auto idx const auto prev_idx
{ {
prev.idxs(idx_buf) prev.idxs(idx_buf)
}; };
for(size_t i(0); i < idx.size(); ++i) for(size_t i(0); i < prev_idx.size(); ++i)
{ {
if(idx[i]) if(prev_idx[i])
continue; continue;
if(!closure(prev.prev_event(i), it.depth(), it.event_idx())) if(!closure(prev.prev_event(i), depth, event_idx))
return false; return false;
} }

View File

@ -114,18 +114,13 @@ ircd::m::room::purge::timeline()
room, opts.depth.second room, opts.depth.second
}; };
m::event::fetch event;
for(; it && it.depth() >= opts.depth.first; --it) for(; it && it.depth() >= opts.depth.first; --it)
{ {
if(!match(it.depth(), it.event_idx())) if(!match(it.depth(), it.event_idx()))
continue; continue;
bool valid; if(unlikely(!seek(std::nothrow, event, it.event_idx())))
const event &event
{
it.fetch(std::nothrow, &valid)
};
if(unlikely(!valid))
continue; continue;
if(!match(it.event_idx(), event)) if(!match(it.event_idx(), event))

View File

@ -212,6 +212,7 @@ ircd::m::room::state::space::rebuild::rebuild(const room::id &room_id)
!m::internal(room_id) !m::internal(room_id)
}; };
m::event::fetch event;
size_t state_count(0), messages_count(0), state_deleted(0); size_t state_count(0), messages_count(0), state_deleted(0);
for(; it; ++it, ++messages_count) try for(; it; ++it, ++messages_count) try
{ {
@ -223,8 +224,10 @@ ircd::m::room::state::space::rebuild::rebuild(const room::id &room_id)
if(!state::is(std::nothrow, event_idx)) if(!state::is(std::nothrow, event_idx))
continue; continue;
if(!seek(std::nothrow, event, event_idx))
continue;
++state_count; ++state_count;
const m::event &event{*it};
const auto &[pass_static, reason_static] const auto &[pass_static, reason_static]
{ {
check_auth? check_auth?

View File

@ -333,13 +333,16 @@ get_events_from(client &client,
}; };
size_t i(0), j(0); size_t i(0), j(0);
m::event::fetch event;
for(; it && i < size_t(events_limit); --it, ++i) for(; it && i < size_t(events_limit); --it, ++i)
{ {
const m::event &event{*it}; const auto &event_idx(it.event_idx());
if(!seek(std::nothrow, event, event_idx))
continue;
if(!visible(event, request.user_id)) if(!visible(event, request.user_id))
continue; continue;
const auto &event_idx(it.event_idx());
j += append_event(chunk, event, event_idx, room_depth, user_room); j += append_event(chunk, event, event_idx, room_depth, user_room);
} }

View File

@ -554,6 +554,7 @@ initialsync_room_timeline_events(client &client,
m::event::idx event_idx{0}; m::event::idx event_idx{0};
m::event::id::buf event_id; m::event::id::buf event_id;
m::room::events it{room}; m::room::events it{room};
m::event::fetch event;
for(; it && i < 10; --it, ++i) for(; it && i < 10; --it, ++i)
{ {
event_idx = it.event_idx(); event_idx = it.event_idx();
@ -565,7 +566,8 @@ initialsync_room_timeline_events(client &client,
if(i > 0) if(i > 0)
for(; it && i > -1; ++it, --i) for(; it && i > -1; ++it, --i)
out.append(*it); if(seek(std::nothrow, event, it.event_idx()))
out.append(event);
return event_id; return event_id;
} }

View File

@ -164,14 +164,17 @@ get__context(client &client,
if(before) if(before)
--before; --before;
m::event::fetch event;
for(size_t i(0); i < limit && before; --before, ++i) for(size_t i(0); i < limit && before; --before, ++i)
{ {
const m::event &event{*before}; const auto event_idx(before.event_idx());
if(!seek(std::nothrow, event, event_idx))
continue;
start = event.event_id; start = event.event_id;
if(!visible(event, request.user_id)) if(!visible(event, request.user_id))
continue; continue;
const auto event_idx(before.event_idx());
counts.before += m::event::append counts.before += m::event::append
{ {
array, event, array, event,
@ -215,14 +218,17 @@ get__context(client &client,
if(after) if(after)
++after; ++after;
m::event::fetch event;
for(size_t i(0); i < limit && after; ++after, ++i) for(size_t i(0); i < limit && after; ++after, ++i)
{ {
const m::event &event{*after}; const auto event_idx(after.event_idx());
if(!seek(std::nothrow, event, event_idx))
continue;
end = event.event_id; end = event.event_id;
if(!visible(event, request.user_id)) if(!visible(event, request.user_id))
continue; continue;
const auto event_idx(after.event_idx());
counts.after += m::event::append counts.after += m::event::append
{ {
array, event, array, event,

View File

@ -245,10 +245,13 @@ get__initialsync_local(client &client,
messages, "chunk" messages, "chunk"
}; };
m::event::fetch event;
for(; it; ++it) for(; it; ++it)
{ {
const auto &event_idx(it.event_idx()); const auto &event_idx(it.event_idx());
const m::event &event(*it); if(!seek(std::nothrow, event, event_idx))
continue;
if(!visible(event, user.user_id)) if(!visible(event, user.user_id))
continue; continue;

View File

@ -131,18 +131,17 @@ get__messages(client &client,
room room
}; };
m::event::fetch event;
for(; it; page.dir == 'b'? --it : ++it) for(; it; page.dir == 'b'? --it : ++it)
{ {
const m::event &event const auto &event_idx(it.event_idx());
{ if(!seek(std::nothrow, event, event_idx))
*it continue;
};
end = event.event_id; end = event.event_id;
if(hit >= page.limit || miss >= size_t(max_filter_miss)) if(hit >= page.limit || miss >= size_t(max_filter_miss))
break; break;
const m::event::idx event_idx{it};
const bool ok const bool ok
{ {
(empty(filter_json) || match(filter, event)) (empty(filter_json) || match(filter, event))

View File

@ -382,9 +382,10 @@ ircd::m::sync::_room_timeline_polylog_events(data &data,
if(i > 1 && it) if(i > 1 && it)
--i, ++it; --i, ++it;
m::event::fetch event;
for(; i >= 0 && it; --i, ++it) for(; i >= 0 && it; --i, ++it)
{ {
const auto event_idx const auto &event_idx
{ {
it.event_idx() it.event_idx()
}; };
@ -392,9 +393,12 @@ ircd::m::sync::_room_timeline_polylog_events(data &data,
if(event_idx == batch_idx) if(event_idx == batch_idx)
continue; continue;
if(!seek(std::nothrow, event, event_idx))
continue;
ret |= m::event::append ret |= m::event::append
{ {
array, *it, array, event,
{ {
.event_idx = &event_idx, .event_idx = &event_idx,
.client_txnid = &data.client_txnid, .client_txnid = &data.client_txnid,

View File

@ -11196,12 +11196,11 @@ console_cmd__room__count(opt &out, const string_view &line)
if(param[1]) if(param[1])
{ {
size_t count{0}; size_t count{0};
m::event::fetch event;
m::room::events it{room}; m::room::events it{room};
for(; it && limit; --it, --limit) for(; it && limit; --it, --limit)
{ if(seek(std::nothrow, event, it.event_idx()))
const m::event &event{*it}; count += match(filter, event);
count += match(filter, event);
}
out << count << std::endl; out << count << std::endl;
return true; return true;
@ -11256,10 +11255,17 @@ console_cmd__room__events(opt &out, const string_view &line)
room, uint64_t(depth >= 0? depth : -1) room, uint64_t(depth >= 0? depth : -1)
}; };
m::event::fetch event;
for(; it && limit > 0; order == 'b'? --it : ++it, --limit) for(; it && limit > 0; order == 'b'? --it : ++it, --limit)
out << std::left << std::setw(10) << it.event_idx() << " " {
<< pretty_oneline(*it) if(!seek(std::nothrow, event, it.event_idx()))
<< std::endl; continue;
out
<< std::left << std::setw(10) << it.event_idx() << " "
<< pretty_oneline(event)
<< std::endl;
}
return true; return true;
} }

View File

@ -123,12 +123,11 @@ get__backfill(client &client,
}; };
size_t count{0}; size_t count{0};
m::event::fetch event;
for(; it && count < limit; ++count, --it) for(; it && count < limit; ++count, --it)
{ {
const m::event &event if(!seek(std::nothrow, event, it.event_idx()))
{ continue;
*it
};
assert(event.event_id); assert(event.event_id);
if(!visible(event, request.node_id)) if(!visible(event, request.node_id))