Reduce some include of Cache.h since it needs 11s on average

This commit is contained in:
Nicolas Werner 2019-12-14 23:39:02 +01:00
parent 6b16616e3a
commit 13df852479
11 changed files with 275 additions and 226 deletions

View file

@ -78,6 +78,13 @@ constexpr auto OUTBOUND_MEGOLM_SESSIONS_DB("outbound_megolm_sessions");
using CachedReceipts = std::multimap<uint64_t, std::string, std::greater<uint64_t>>; using CachedReceipts = std::multimap<uint64_t, std::string, std::greater<uint64_t>>;
using Receipts = std::map<std::string, std::map<std::string, uint64_t>>; using Receipts = std::map<std::string, std::map<std::string, uint64_t>>;
Q_DECLARE_METATYPE(SearchResult)
Q_DECLARE_METATYPE(QVector<SearchResult>)
Q_DECLARE_METATYPE(RoomMember)
Q_DECLARE_METATYPE(mtx::responses::Timeline)
Q_DECLARE_METATYPE(RoomSearchResult)
Q_DECLARE_METATYPE(RoomInfo)
namespace { namespace {
std::unique_ptr<Cache> instance_ = nullptr; std::unique_ptr<Cache> instance_ = nullptr;
} }
@ -1504,7 +1511,7 @@ Cache::getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb)
return "Empty Room"; return "Empty Room";
} }
JoinRule mtx::events::state::JoinRule
Cache::getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb) Cache::getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb)
{ {
using namespace mtx::events; using namespace mtx::events;
@ -1516,14 +1523,14 @@ Cache::getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb)
if (res) { if (res) {
try { try {
StateEvent<JoinRules> msg = StateEvent<state::JoinRules> msg =
json::parse(std::string(event.data(), event.size())); json::parse(std::string(event.data(), event.size()));
return msg.content.join_rule; return msg.content.join_rule;
} catch (const json::exception &e) { } catch (const json::exception &e) {
nhlog::db()->warn("failed to parse m.room.join_rule event: {}", e.what()); nhlog::db()->warn("failed to parse m.room.join_rule event: {}", e.what());
} }
} }
return JoinRule::Knock; return state::JoinRule::Knock;
} }
bool bool
@ -2313,3 +2320,91 @@ from_json(const json &j, RoomInfo &info)
if (j.count("tags")) if (j.count("tags"))
info.tags = j.at("tags").get<std::vector<std::string>>(); info.tags = j.at("tags").get<std::vector<std::string>>();
} }
int
numeric_key_comparison(const MDB_val *a, const MDB_val *b)
{
auto lhs = std::stoull(std::string((char *)a->mv_data, a->mv_size));
auto rhs = std::stoull(std::string((char *)b->mv_data, b->mv_size));
if (lhs < rhs)
return 1;
else if (lhs == rhs)
return 0;
return -1;
}
void
to_json(json &j, const ReadReceiptKey &key)
{
j = json{{"event_id", key.event_id}, {"room_id", key.room_id}};
}
void
from_json(const json &j, ReadReceiptKey &key)
{
key.event_id = j.at("event_id").get<std::string>();
key.room_id = j.at("room_id").get<std::string>();
}
void
to_json(json &j, const MemberInfo &info)
{
j["name"] = info.name;
j["avatar_url"] = info.avatar_url;
}
void
from_json(const json &j, MemberInfo &info)
{
info.name = j.at("name");
info.avatar_url = j.at("avatar_url");
}
void
to_json(nlohmann::json &obj, const OutboundGroupSessionData &msg)
{
obj["session_id"] = msg.session_id;
obj["session_key"] = msg.session_key;
obj["message_index"] = msg.message_index;
}
void
from_json(const nlohmann::json &obj, OutboundGroupSessionData &msg)
{
msg.session_id = obj.at("session_id");
msg.session_key = obj.at("session_key");
msg.message_index = obj.at("message_index");
}
void
to_json(nlohmann::json &obj, const DevicePublicKeys &msg)
{
obj["ed25519"] = msg.ed25519;
obj["curve25519"] = msg.curve25519;
}
void
from_json(const nlohmann::json &obj, DevicePublicKeys &msg)
{
msg.ed25519 = obj.at("ed25519");
msg.curve25519 = obj.at("curve25519");
}
void
to_json(nlohmann::json &obj, const MegolmSessionIndex &msg)
{
obj["room_id"] = msg.room_id;
obj["session_id"] = msg.session_id;
obj["sender_key"] = msg.sender_key;
}
void
from_json(const nlohmann::json &obj, MegolmSessionIndex &msg)
{
msg.room_id = obj.at("room_id");
msg.session_id = obj.at("session_id");
msg.sender_key = obj.at("sender_key");
}

View file

@ -28,224 +28,16 @@
#include <lmdb++.h> #include <lmdb++.h>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <mtx/events/join_rules.hpp>
#include <mtx/responses.hpp> #include <mtx/responses.hpp>
#include <mtxclient/crypto/client.hpp> #include <mtxclient/crypto/client.hpp>
#include "CacheCryptoStructs.h"
#include "CacheStructs.h"
#include "Logging.h" #include "Logging.h"
#include "MatrixClient.h" #include "MatrixClient.h"
using mtx::events::state::JoinRule; int
numeric_key_comparison(const MDB_val *a, const MDB_val *b);
struct RoomMember
{
QString user_id;
QString display_name;
QImage avatar;
};
struct SearchResult
{
QString user_id;
QString display_name;
};
static int
numeric_key_comparison(const MDB_val *a, const MDB_val *b)
{
auto lhs = std::stoull(std::string((char *)a->mv_data, a->mv_size));
auto rhs = std::stoull(std::string((char *)b->mv_data, b->mv_size));
if (lhs < rhs)
return 1;
else if (lhs == rhs)
return 0;
return -1;
}
Q_DECLARE_METATYPE(SearchResult)
Q_DECLARE_METATYPE(QVector<SearchResult>)
Q_DECLARE_METATYPE(RoomMember)
Q_DECLARE_METATYPE(mtx::responses::Timeline)
//! Used to uniquely identify a list of read receipts.
struct ReadReceiptKey
{
std::string event_id;
std::string room_id;
};
inline void
to_json(json &j, const ReadReceiptKey &key)
{
j = json{{"event_id", key.event_id}, {"room_id", key.room_id}};
}
inline void
from_json(const json &j, ReadReceiptKey &key)
{
key.event_id = j.at("event_id").get<std::string>();
key.room_id = j.at("room_id").get<std::string>();
}
struct DescInfo
{
QString event_id;
QString userid;
QString body;
QString timestamp;
QDateTime datetime;
};
//! UI info associated with a room.
struct RoomInfo
{
//! The calculated name of the room.
std::string name;
//! The topic of the room.
std::string topic;
//! The calculated avatar url of the room.
std::string avatar_url;
//! The calculated version of this room set at creation time.
std::string version;
//! Whether or not the room is an invite.
bool is_invite = false;
//! Total number of members in the room.
int16_t member_count = 0;
//! Who can access to the room.
JoinRule join_rule = JoinRule::Public;
bool guest_access = false;
//! Metadata describing the last message in the timeline.
DescInfo msgInfo;
//! The list of tags associated with this room
std::vector<std::string> tags;
};
void
to_json(json &j, const RoomInfo &info);
void
from_json(const json &j, RoomInfo &info);
//! Basic information per member;
struct MemberInfo
{
std::string name;
std::string avatar_url;
};
inline void
to_json(json &j, const MemberInfo &info)
{
j["name"] = info.name;
j["avatar_url"] = info.avatar_url;
}
inline void
from_json(const json &j, MemberInfo &info)
{
info.name = j.at("name");
info.avatar_url = j.at("avatar_url");
}
struct RoomSearchResult
{
std::string room_id;
RoomInfo info;
};
Q_DECLARE_METATYPE(RoomSearchResult)
Q_DECLARE_METATYPE(RoomInfo)
// Extra information associated with an outbound megolm session.
struct OutboundGroupSessionData
{
std::string session_id;
std::string session_key;
uint64_t message_index = 0;
};
inline void
to_json(nlohmann::json &obj, const OutboundGroupSessionData &msg)
{
obj["session_id"] = msg.session_id;
obj["session_key"] = msg.session_key;
obj["message_index"] = msg.message_index;
}
inline void
from_json(const nlohmann::json &obj, OutboundGroupSessionData &msg)
{
msg.session_id = obj.at("session_id");
msg.session_key = obj.at("session_key");
msg.message_index = obj.at("message_index");
}
struct OutboundGroupSessionDataRef
{
OlmOutboundGroupSession *session;
OutboundGroupSessionData data;
};
struct DevicePublicKeys
{
std::string ed25519;
std::string curve25519;
};
inline void
to_json(nlohmann::json &obj, const DevicePublicKeys &msg)
{
obj["ed25519"] = msg.ed25519;
obj["curve25519"] = msg.curve25519;
}
inline void
from_json(const nlohmann::json &obj, DevicePublicKeys &msg)
{
msg.ed25519 = obj.at("ed25519");
msg.curve25519 = obj.at("curve25519");
}
//! Represents a unique megolm session identifier.
struct MegolmSessionIndex
{
//! The room in which this session exists.
std::string room_id;
//! The session_id of the megolm session.
std::string session_id;
//! The curve25519 public key of the sender.
std::string sender_key;
};
inline void
to_json(nlohmann::json &obj, const MegolmSessionIndex &msg)
{
obj["room_id"] = msg.room_id;
obj["session_id"] = msg.session_id;
obj["sender_key"] = msg.sender_key;
}
inline void
from_json(const nlohmann::json &obj, MegolmSessionIndex &msg)
{
msg.room_id = obj.at("room_id");
msg.session_id = obj.at("session_id");
msg.sender_key = obj.at("sender_key");
}
struct OlmSessionStorage
{
// Megolm sessions
std::map<std::string, mtx::crypto::InboundGroupSessionPtr> group_inbound_sessions;
std::map<std::string, mtx::crypto::OutboundGroupSessionPtr> group_outbound_sessions;
std::map<std::string, OutboundGroupSessionData> group_outbound_session_data;
// Guards for accessing megolm sessions.
std::mutex group_outbound_mtx;
std::mutex group_inbound_mtx;
};
class Cache : public QObject class Cache : public QObject
{ {
@ -287,7 +79,7 @@ public:
//! Calculate & return the name of the room. //! Calculate & return the name of the room.
QString getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); QString getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
//! Get room join rules //! Get room join rules
JoinRule getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb); mtx::events::state::JoinRule getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb);
bool getRoomGuestAccess(lmdb::txn &txn, lmdb::dbi &statesdb); bool getRoomGuestAccess(lmdb::txn &txn, lmdb::dbi &statesdb);
//! Retrieve the topic of the room if any. //! Retrieve the topic of the room if any.
QString getRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb); QString getRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb);

67
src/CacheCryptoStructs.h Normal file
View file

@ -0,0 +1,67 @@
#pragma once
#include <map>
#include <mutex>
//#include <nlohmann/json.hpp>
#include <mtx/responses.hpp>
#include <mtxclient/crypto/client.hpp>
// Extra information associated with an outbound megolm session.
struct OutboundGroupSessionData
{
std::string session_id;
std::string session_key;
uint64_t message_index = 0;
};
void
to_json(nlohmann::json &obj, const OutboundGroupSessionData &msg);
void
from_json(const nlohmann::json &obj, OutboundGroupSessionData &msg);
struct OutboundGroupSessionDataRef
{
OlmOutboundGroupSession *session;
OutboundGroupSessionData data;
};
struct DevicePublicKeys
{
std::string ed25519;
std::string curve25519;
};
void
to_json(nlohmann::json &obj, const DevicePublicKeys &msg);
void
from_json(const nlohmann::json &obj, DevicePublicKeys &msg);
//! Represents a unique megolm session identifier.
struct MegolmSessionIndex
{
//! The room in which this session exists.
std::string room_id;
//! The session_id of the megolm session.
std::string session_id;
//! The curve25519 public key of the sender.
std::string sender_key;
};
void
to_json(nlohmann::json &obj, const MegolmSessionIndex &msg);
void
from_json(const nlohmann::json &obj, MegolmSessionIndex &msg);
struct OlmSessionStorage
{
// Megolm sessions
std::map<std::string, mtx::crypto::InboundGroupSessionPtr> group_inbound_sessions;
std::map<std::string, mtx::crypto::OutboundGroupSessionPtr> group_outbound_sessions;
std::map<std::string, OutboundGroupSessionData> group_outbound_session_data;
// Guards for accessing megolm sessions.
std::mutex group_outbound_mtx;
std::mutex group_inbound_mtx;
};

91
src/CacheStructs.h Normal file
View file

@ -0,0 +1,91 @@
#pragma once
#include <QDateTime>
#include <QImage>
#include <QString>
#include <string>
#include <mtx/events/join_rules.hpp>
struct RoomMember
{
QString user_id;
QString display_name;
QImage avatar;
};
struct SearchResult
{
QString user_id;
QString display_name;
};
//! Used to uniquely identify a list of read receipts.
struct ReadReceiptKey
{
std::string event_id;
std::string room_id;
};
void
to_json(json &j, const ReadReceiptKey &key);
void
from_json(const json &j, ReadReceiptKey &key);
struct DescInfo
{
QString event_id;
QString userid;
QString body;
QString timestamp;
QDateTime datetime;
};
//! UI info associated with a room.
struct RoomInfo
{
//! The calculated name of the room.
std::string name;
//! The topic of the room.
std::string topic;
//! The calculated avatar url of the room.
std::string avatar_url;
//! The calculated version of this room set at creation time.
std::string version;
//! Whether or not the room is an invite.
bool is_invite = false;
//! Total number of members in the room.
int16_t member_count = 0;
//! Who can access to the room.
mtx::events::state::JoinRule join_rule = mtx::events::state::JoinRule::Public;
bool guest_access = false;
//! Metadata describing the last message in the timeline.
DescInfo msgInfo;
//! The list of tags associated with this room
std::vector<std::string> tags;
};
void
to_json(json &j, const RoomInfo &info);
void
from_json(const json &j, RoomInfo &info);
//! Basic information per member;
struct MemberInfo
{
std::string name;
std::string avatar_url;
};
void
to_json(json &j, const MemberInfo &info);
void
from_json(const json &j, MemberInfo &info);
struct RoomSearchResult
{
std::string room_id;
RoomInfo info;
};

View file

@ -32,7 +32,7 @@
#include <QTimer> #include <QTimer>
#include <QWidget> #include <QWidget>
#include "Cache.h" #include "CacheStructs.h"
#include "CommunitiesList.h" #include "CommunitiesList.h"
#include "MatrixClient.h" #include "MatrixClient.h"
#include "Utils.h" #include "Utils.h"

View file

@ -4,7 +4,7 @@
#include <QSharedPointer> #include <QSharedPointer>
#include <QVBoxLayout> #include <QVBoxLayout>
#include "Cache.h" #include "CacheStructs.h"
#include "CommunitiesListItem.h" #include "CommunitiesListItem.h"
#include "ui/Theme.h" #include "ui/Theme.h"
@ -53,3 +53,4 @@ private:
std::map<QString, QSharedPointer<CommunitiesListItem>> communities_; std::map<QString, QSharedPointer<CommunitiesListItem>> communities_;
}; };

View file

@ -97,7 +97,7 @@ RoomInfoListItem::init(QWidget *parent)
menu_->addAction(leaveRoom_); menu_->addAction(leaveRoom_);
} }
RoomInfoListItem::RoomInfoListItem(QString room_id, RoomInfo info, QWidget *parent) RoomInfoListItem::RoomInfoListItem(QString room_id, const RoomInfo &info, QWidget *parent)
: QWidget(parent) : QWidget(parent)
, roomType_{info.is_invite ? RoomType::Invited : RoomType::Joined} , roomType_{info.is_invite ? RoomType::Invited : RoomType::Joined}
, roomId_(std::move(room_id)) , roomId_(std::move(room_id))

View file

@ -22,9 +22,10 @@
#include <QSharedPointer> #include <QSharedPointer>
#include <QWidget> #include <QWidget>
#include "Cache.h"
#include <mtx/responses.hpp> #include <mtx/responses.hpp>
#include "CacheStructs.h"
class Menu; class Menu;
class RippleOverlay; class RippleOverlay;
@ -64,7 +65,7 @@ class RoomInfoListItem : public QWidget
Q_PROPERTY(QColor btnTextColor READ btnTextColor WRITE setBtnTextColor) Q_PROPERTY(QColor btnTextColor READ btnTextColor WRITE setBtnTextColor)
public: public:
RoomInfoListItem(QString room_id, RoomInfo info, QWidget *parent = 0); RoomInfoListItem(QString room_id, const RoomInfo &info, QWidget *parent = 0);
void updateUnreadMessageCount(int count, int highlightedCount); void updateUnreadMessageCount(int count, int highlightedCount);
void clearUnreadMessageCount() { updateUnreadMessageCount(0, 0); }; void clearUnreadMessageCount() { updateUnreadMessageCount(0, 0); };

View file

@ -248,10 +248,10 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
switch (index) { switch (index) {
case 0: case 0:
case 1: case 1:
event.join_rule = JoinRule::Public; event.join_rule = state::JoinRule::Public;
break; break;
default: default:
event.join_rule = JoinRule::Invite; event.join_rule = state::JoinRule::Invite;
} }
return event; return event;
@ -260,7 +260,7 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
updateAccessRules(room_id_.toStdString(), join_rule, guest_access); updateAccessRules(room_id_.toStdString(), join_rule, guest_access);
}); });
if (info_.join_rule == JoinRule::Public) { if (info_.join_rule == state::JoinRule::Public) {
if (info_.guest_access) { if (info_.guest_access) {
accessCombo->setCurrentIndex(0); accessCombo->setCurrentIndex(0);
} else { } else {
@ -342,7 +342,7 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
} }
// Hide encryption option for public rooms. // Hide encryption option for public rooms.
if (!usesEncryption_ && (info_.join_rule == JoinRule::Public)) { if (!usesEncryption_ && (info_.join_rule == state::JoinRule::Public)) {
encryptionToggle_->hide(); encryptionToggle_->hide();
encryptionLabel->hide(); encryptionLabel->hide();

View file

@ -10,6 +10,8 @@
#include "../ChatPage.h" #include "../ChatPage.h"
#include "PopupItem.h" #include "PopupItem.h"
Q_DECLARE_METATYPE(QVector<SearchResult>)
class SuggestionsPopup : public QWidget class SuggestionsPopup : public QWidget
{ {
Q_OBJECT Q_OBJECT

View file

@ -9,7 +9,7 @@
#include <mtx/common.hpp> #include <mtx/common.hpp>
#include <mtx/responses.hpp> #include <mtx/responses.hpp>
#include "Cache.h" #include "CacheCryptoStructs.h"
#include "Logging.h" #include "Logging.h"
#include "MatrixClient.h" #include "MatrixClient.h"