Reduce allocations for accessing event members

pull/867/head
Nicolas Werner 3 years ago
parent 0f4b482bb3
commit 271b111558
No known key found for this signature in database
GPG Key ID: C8D75E610773F2D9
  1. 24
      src/EventAccessors.cpp
  2. 8
      src/EventAccessors.h
  3. 29
      src/timeline/EventStore.cpp
  4. 2
      src/timeline/EventStore.h
  5. 12
      src/timeline/TimelineModel.cpp

@ -87,7 +87,7 @@ struct CallType
? "video" ? "video"
: "voice"; : "voice";
} }
return std::string(); return "";
} }
}; };
@ -243,15 +243,17 @@ struct EventFilesize
struct EventRelations struct EventRelations
{ {
inline const static mtx::common::Relations empty;
template<class Content> template<class Content>
using related_ev_id_t = decltype(Content::relations); using related_ev_id_t = decltype(Content::relations);
template<class T> template<class T>
mtx::common::Relations operator()(const mtx::events::Event<T> &e) const mtx::common::Relations &operator()(const mtx::events::Event<T> &e)
{ {
if constexpr (is_detected<related_ev_id_t, T>::value) { if constexpr (is_detected<related_ev_id_t, T>::value) {
return e.content.relations; return e.content.relations;
} }
return {}; return empty;
} }
}; };
@ -325,28 +327,28 @@ eventPropHeight(const mtx::events::RoomEvent<T> &e)
} }
} }
std::string const std::string &
mtx::accessors::event_id(const mtx::events::collections::TimelineEvents &event) mtx::accessors::event_id(const mtx::events::collections::TimelineEvents &event)
{ {
return std::visit([](const auto e) { return e.event_id; }, event); return std::visit([](const auto &e) -> const std::string & { return e.event_id; }, event);
} }
std::string const std::string &
mtx::accessors::room_id(const mtx::events::collections::TimelineEvents &event) mtx::accessors::room_id(const mtx::events::collections::TimelineEvents &event)
{ {
return std::visit([](const auto e) { return e.room_id; }, event); return std::visit([](const auto &e) -> const std::string & { return e.room_id; }, event);
} }
std::string const std::string &
mtx::accessors::sender(const mtx::events::collections::TimelineEvents &event) mtx::accessors::sender(const mtx::events::collections::TimelineEvents &event)
{ {
return std::visit([](const auto e) { return e.sender; }, event); return std::visit([](const auto &e) -> const std::string & { return e.sender; }, event);
} }
QDateTime QDateTime
mtx::accessors::origin_server_ts(const mtx::events::collections::TimelineEvents &event) mtx::accessors::origin_server_ts(const mtx::events::collections::TimelineEvents &event)
{ {
return QDateTime::fromMSecsSinceEpoch( return QDateTime::fromMSecsSinceEpoch(
std::visit([](const auto e) { return e.origin_server_ts; }, event)); std::visit([](const auto &e) { return e.origin_server_ts; }, event));
} }
std::string std::string
@ -427,7 +429,7 @@ mtx::accessors::mimetype(const mtx::events::collections::TimelineEvents &event)
{ {
return std::visit(EventMimeType{}, event); return std::visit(EventMimeType{}, event);
} }
mtx::common::Relations const mtx::common::Relations &
mtx::accessors::relations(const mtx::events::collections::TimelineEvents &event) mtx::accessors::relations(const mtx::events::collections::TimelineEvents &event)
{ {
return std::visit(EventRelations{}, event); return std::visit(EventRelations{}, event);

@ -38,13 +38,13 @@ struct detector<Default, std::void_t<Op<Args...>>, Op, Args...>
} }
namespace mtx::accessors { namespace mtx::accessors {
std::string const std::string &
event_id(const mtx::events::collections::TimelineEvents &event); event_id(const mtx::events::collections::TimelineEvents &event);
std::string const std::string &
room_id(const mtx::events::collections::TimelineEvents &event); room_id(const mtx::events::collections::TimelineEvents &event);
std::string const std::string &
sender(const mtx::events::collections::TimelineEvents &event); sender(const mtx::events::collections::TimelineEvents &event);
bool bool
@ -86,7 +86,7 @@ std::string
blurhash(const mtx::events::collections::TimelineEvents &event); blurhash(const mtx::events::collections::TimelineEvents &event);
std::string std::string
mimetype(const mtx::events::collections::TimelineEvents &event); mimetype(const mtx::events::collections::TimelineEvents &event);
mtx::common::Relations const mtx::common::Relations &
relations(const mtx::events::collections::TimelineEvents &event); relations(const mtx::events::collections::TimelineEvents &event);
void void
set_relations(mtx::events::collections::TimelineEvents &event, mtx::common::Relations relations); set_relations(mtx::events::collections::TimelineEvents &event, mtx::common::Relations relations);

@ -106,8 +106,8 @@ EventStore::EventStore(std::string room_id, QObject *)
} }
std::visit( std::visit(
[this](auto e) { [this](const auto &e) {
auto txn_id = e.event_id; const auto &txn_id = e.event_id;
this->current_txn = txn_id; this->current_txn = txn_id;
if (txn_id.empty() || txn_id[0] != 'm') { if (txn_id.empty() || txn_id[0] != 'm') {
@ -207,7 +207,7 @@ EventStore::EventStore(std::string room_id, QObject *)
rel.event_id = event_id; rel.event_id = event_id;
} }
mtx::accessors::set_relations(related_event.data, relations); mtx::accessors::set_relations(related_event.data, std::move(relations));
cache::client()->replaceEvent(room_id_, related_event_id, related_event); cache::client()->replaceEvent(room_id_, related_event_id, related_event);
@ -451,8 +451,8 @@ EventStore::edits(const std::string &event_id)
std::holds_alternative<mtx::events::RoomEvent<mtx::events::msg::Redacted>>(*original_event)) std::holds_alternative<mtx::events::RoomEvent<mtx::events::msg::Redacted>>(*original_event))
return {}; return {};
auto original_sender = mtx::accessors::sender(*original_event); const auto &original_sender = mtx::accessors::sender(*original_event);
auto original_relations = mtx::accessors::relations(*original_event); const auto &original_relations = mtx::accessors::relations(*original_event);
std::vector<mtx::events::collections::TimelineEvents> edits; std::vector<mtx::events::collections::TimelineEvents> edits;
for (const auto &id : event_ids) { for (const auto &id : event_ids) {
@ -460,15 +460,15 @@ EventStore::edits(const std::string &event_id)
if (!related_event) if (!related_event)
continue; continue;
auto related_ev = *related_event; const auto &edit_rel = mtx::accessors::relations(*related_event);
auto edit_rel = mtx::accessors::relations(related_ev);
if (edit_rel.replaces() == event_id && if (edit_rel.replaces() == event_id &&
original_sender == mtx::accessors::sender(related_ev)) { original_sender == mtx::accessors::sender(*related_event)) {
auto related_ev = *related_event;
if (edit_rel.synthesized && original_relations.reply_to() && !edit_rel.reply_to()) { if (edit_rel.synthesized && original_relations.reply_to() && !edit_rel.reply_to()) {
edit_rel.relations.push_back( auto edit_rel_copy = edit_rel;
edit_rel_copy.relations.push_back(
{mtx::common::RelationType::InReplyTo, original_relations.reply_to().value()}); {mtx::common::RelationType::InReplyTo, original_relations.reply_to().value()});
mtx::accessors::set_relations(related_ev, std::move(edit_rel)); mtx::accessors::set_relations(related_ev, std::move(edit_rel_copy));
} }
edits.push_back(std::move(related_ev)); edits.push_back(std::move(related_ev));
} }
@ -728,7 +728,10 @@ EventStore::enableKeyRequests(bool suppressKeyRequests_)
} }
mtx::events::collections::TimelineEvents * mtx::events::collections::TimelineEvents *
EventStore::get(std::string id, std::string_view related_to, bool decrypt, bool resolve_edits) EventStore::get(const std::string &id,
std::string_view related_to,
bool decrypt,
bool resolve_edits)
{ {
if (this->thread() != QThread::currentThread()) if (this->thread() != QThread::currentThread())
nhlog::db()->warn("{} called from a different thread!", __func__); nhlog::db()->warn("{} called from a different thread!", __func__);
@ -736,7 +739,7 @@ EventStore::get(std::string id, std::string_view related_to, bool decrypt, bool
if (id.empty()) if (id.empty())
return nullptr; return nullptr;
IdIndex index{room_id_, std::move(id)}; IdIndex index{room_id_, id};
if (resolve_edits) { if (resolve_edits) {
auto edits_ = edits(index.id); auto edits_ = edits(index.id);
if (!edits_.empty()) { if (!edits_.empty()) {

@ -69,7 +69,7 @@ public:
// optionally returns the event or nullptr and fetches it, after which it emits a // optionally returns the event or nullptr and fetches it, after which it emits a
// relatedFetched event // relatedFetched event
mtx::events::collections::TimelineEvents *get(std::string id, mtx::events::collections::TimelineEvents *get(const std::string &id,
std::string_view related_to, std::string_view related_to,
bool decrypt = true, bool decrypt = true,
bool resolve_edits = true); bool resolve_edits = true);

@ -441,7 +441,7 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj
QHash<int, QByteArray> QHash<int, QByteArray>
TimelineModel::roleNames() const TimelineModel::roleNames() const
{ {
return { static QHash<int, QByteArray> roles{
{Type, "type"}, {Type, "type"},
{TypeString, "typeString"}, {TypeString, "typeString"},
{IsOnlyEmoji, "isOnlyEmoji"}, {IsOnlyEmoji, "isOnlyEmoji"},
@ -479,6 +479,8 @@ TimelineModel::roleNames() const
{Dump, "dump"}, {Dump, "dump"},
{RelatedEventCacheBuster, "relatedEventCacheBuster"}, {RelatedEventCacheBuster, "relatedEventCacheBuster"},
}; };
return roles;
} }
int int
TimelineModel::rowCount(const QModelIndex &parent) const TimelineModel::rowCount(const QModelIndex &parent) const
@ -658,16 +660,14 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
return {!is_state_event(event) && return {!is_state_event(event) &&
mtx::accessors::sender(event) == http::client()->user_id().to_string()}; mtx::accessors::sender(event) == http::client()->user_id().to_string()};
case IsEncrypted: { case IsEncrypted: {
auto id = event_id(event); auto encrypted_event = events.get(event_id(event), "", false);
auto encrypted_event = events.get(id, "", false);
return encrypted_event && return encrypted_event &&
std::holds_alternative<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>( std::holds_alternative<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
*encrypted_event); *encrypted_event);
} }
case Trustlevel: { case Trustlevel: {
auto id = event_id(event); auto encrypted_event = events.get(event_id(event), "", false);
auto encrypted_event = events.get(id, "", false);
if (encrypted_event) { if (encrypted_event) {
if (auto encrypted = if (auto encrypted =
std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>( std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
@ -1225,7 +1225,7 @@ TimelineModel::redactEvent(const QString &id)
// redact all edits to prevent leaks // redact all edits to prevent leaks
for (const auto &e : edits) { for (const auto &e : edits) {
auto id_ = mtx::accessors::event_id(e); const auto &id_ = mtx::accessors::event_id(e);
http::client()->redact_event( http::client()->redact_event(
room_id_.toStdString(), room_id_.toStdString(),
id_, id_,

Loading…
Cancel
Save