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
{
using depth_range = std::pair<uint64_t, uint64_t>;
using entry = std::tuple<uint64_t, event::idx>;
static conf::item<ssize_t> viewport_size;
m::room room;
db::domain::const_iterator it;
event::fetch _event;
mutable entry _entry;
public:
explicit operator bool() const { return bool(it); }
bool operator!() const { return !it; }
explicit operator bool() const;
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
uint64_t depth() 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
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)
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)
bool prefetch(const string_view &event_prop);
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.
events(const m::room &,
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.
events(const m::room &,
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
// iteration when given and not found.
events(const m::room &,
const event::fetch::opts *const & = nullptr);
const event::fetch::opts * = nullptr);
events() = default;
events(const events &) = delete;
@ -81,7 +81,6 @@ struct ircd::m::room::events
static bool preseek(const m::room &, const uint64_t &depth = -1);
// 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_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 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),
events_fetched(0),
events_prefetched(0);
m::event::fetch event;
for(; it; ++it) try
{
for(; epf && events_prefetched < events_fetched + events_prefetch; ++epf)
events_prefetched += epf.prefetch();
seek(event, it.event_idx());
++events_fetched;
const m::event &event
{
*it
};
if(json::get<"type"_>(event) != "ircd.file.block.b64")
continue;

View File

@ -15,10 +15,6 @@ ircd::m::room::events::viewport_size
{ "default", 96L },
};
//
// room::events
//
size_t
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,
const event::fetch::opts *const &fopts)
const event::fetch::opts *const fopts)
:room{room}
,_event
{
fopts?
*fopts:
room.fopts?
*room.fopts:
event::fetch::default_opts
}
{
assert(room.room_id);
if(fopts)
this->room.fopts = fopts;
const bool found
{
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,
const event::id &event_id,
const event::fetch::opts *const &fopts)
const event::fetch::opts *const fopts)
:room{room}
,_event
{
fopts?
*fopts:
room.fopts?
*room.fopts:
event::fetch::default_opts
}
{
assert(room.room_id);
if(fopts)
this->room.fopts = fopts;
const bool found
{
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,
const uint64_t &depth,
const event::fetch::opts *const &fopts)
const event::fetch::opts *const fopts)
:room{room}
,_event
{
fopts?
*fopts:
room.fopts?
*room.fopts:
event::fetch::default_opts
}
{
assert(room.room_id);
if(fopts)
this->room.fopts = fopts;
// 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
// rooms which start at depth=1.
@ -206,8 +189,14 @@ ircd::m::room::events::events(const m::room &room,
bool
ircd::m::room::events::prefetch()
{
assert(_event.fopts);
return m::prefetch(event_idx(), *_event.fopts);
const auto &fopts
{
room.fopts?
*room.fopts:
event::fetch::default_opts
};
return m::prefetch(event_idx(), fopts);
}
bool
@ -216,28 +205,6 @@ ircd::m::room::events::prefetch(const string_view &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
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;
}
ircd::m::room::events::operator
ircd::m::event::idx()
const
{
return event_idx();
}
ircd::m::event::idx
ircd::m::room::events::event_idx()
const ircd::m::room::events::entry *
ircd::m::room::events::operator->()
const
{
assert(bool(*this));
const auto part
{
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);
_entry = dbs::room_events_key(it->first);
return &_entry;
}

View File

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

View File

@ -31,11 +31,13 @@ ircd::m::room::horizon::rebuild()
room
};
m::event::fetch event;
for(; it; --it)
{
const m::event &event{*it};
const event::prev prev_events{event};
if(!seek(std::nothrow, event, it.event_idx()))
continue;
const event::prev prev_events{event};
opts.event_idx = it.event_idx();
m::for_each(prev_events, [&]
(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
{
const m::event event
const auto &[depth, event_idx]
{
*it
};
const m::event::fetch event
{
std::nothrow, event_idx
};
const event::prev prev
{
event
};
event::idx idx_buf[event::prev::MAX];
const auto idx
const auto prev_idx
{
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;
if(!closure(prev.prev_event(i), it.depth(), it.event_idx()))
if(!closure(prev.prev_event(i), depth, event_idx))
return false;
}

View File

@ -114,18 +114,13 @@ ircd::m::room::purge::timeline()
room, opts.depth.second
};
m::event::fetch event;
for(; it && it.depth() >= opts.depth.first; --it)
{
if(!match(it.depth(), it.event_idx()))
continue;
bool valid;
const event &event
{
it.fetch(std::nothrow, &valid)
};
if(unlikely(!valid))
if(unlikely(!seek(std::nothrow, event, it.event_idx())))
continue;
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::event::fetch event;
size_t state_count(0), messages_count(0), state_deleted(0);
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))
continue;
if(!seek(std::nothrow, event, event_idx))
continue;
++state_count;
const m::event &event{*it};
const auto &[pass_static, reason_static]
{
check_auth?

View File

@ -333,13 +333,16 @@ get_events_from(client &client,
};
size_t i(0), j(0);
m::event::fetch event;
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))
continue;
const auto &event_idx(it.event_idx());
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::id::buf event_id;
m::room::events it{room};
m::event::fetch event;
for(; it && i < 10; --it, ++i)
{
event_idx = it.event_idx();
@ -565,7 +566,8 @@ initialsync_room_timeline_events(client &client,
if(i > 0)
for(; it && i > -1; ++it, --i)
out.append(*it);
if(seek(std::nothrow, event, it.event_idx()))
out.append(event);
return event_id;
}

View File

@ -164,14 +164,17 @@ get__context(client &client,
if(before)
--before;
m::event::fetch event;
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;
if(!visible(event, request.user_id))
continue;
const auto event_idx(before.event_idx());
counts.before += m::event::append
{
array, event,
@ -215,14 +218,17 @@ get__context(client &client,
if(after)
++after;
m::event::fetch event;
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;
if(!visible(event, request.user_id))
continue;
const auto event_idx(after.event_idx());
counts.after += m::event::append
{
array, event,

View File

@ -245,10 +245,13 @@ get__initialsync_local(client &client,
messages, "chunk"
};
m::event::fetch event;
for(; it; ++it)
{
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))
continue;

View File

@ -131,18 +131,17 @@ get__messages(client &client,
room
};
m::event::fetch event;
for(; it; page.dir == 'b'? --it : ++it)
{
const m::event &event
{
*it
};
const auto &event_idx(it.event_idx());
if(!seek(std::nothrow, event, event_idx))
continue;
end = event.event_id;
if(hit >= page.limit || miss >= size_t(max_filter_miss))
break;
const m::event::idx event_idx{it};
const bool ok
{
(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)
--i, ++it;
m::event::fetch event;
for(; i >= 0 && it; --i, ++it)
{
const auto event_idx
const auto &event_idx
{
it.event_idx()
};
@ -392,9 +393,12 @@ ircd::m::sync::_room_timeline_polylog_events(data &data,
if(event_idx == batch_idx)
continue;
if(!seek(std::nothrow, event, event_idx))
continue;
ret |= m::event::append
{
array, *it,
array, event,
{
.event_idx = &event_idx,
.client_txnid = &data.client_txnid,

View File

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

View File

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