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 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 {
std::unique_ptr<Cache> instance_ = nullptr;
}
@ -1504,7 +1511,7 @@ Cache::getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb)
return "Empty Room";
}
JoinRule
mtx::events::state::JoinRule
Cache::getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb)
{
using namespace mtx::events;
@ -1516,14 +1523,14 @@ Cache::getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb)
if (res) {
try {
StateEvent<JoinRules> msg =
StateEvent<state::JoinRules> msg =
json::parse(std::string(event.data(), event.size()));
return msg.content.join_rule;
} catch (const json::exception &e) {
nhlog::db()->warn("failed to parse m.room.join_rule event: {}", e.what());
}
}
return JoinRule::Knock;
return state::JoinRule::Knock;
}
bool
@ -2313,3 +2320,91 @@ from_json(const json &j, RoomInfo &info)
if (j.count("tags"))
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 <nlohmann/json.hpp>
#include <mtx/events/join_rules.hpp>
#include <mtx/responses.hpp>
#include <mtxclient/crypto/client.hpp>
#include "CacheCryptoStructs.h"
#include "CacheStructs.h"
#include "Logging.h"
#include "MatrixClient.h"
using mtx::events::state::JoinRule;
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;
};
int
numeric_key_comparison(const MDB_val *a, const MDB_val *b);
class Cache : public QObject
{
@ -287,7 +79,7 @@ public:
//! Calculate & return the name of the room.
QString getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
//! 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);
//! Retrieve the topic of the room if any.
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 <QWidget>
#include "Cache.h"
#include "CacheStructs.h"
#include "CommunitiesList.h"
#include "MatrixClient.h"
#include "Utils.h"

View file

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

View file

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

View file

@ -22,9 +22,10 @@
#include <QSharedPointer>
#include <QWidget>
#include "Cache.h"
#include <mtx/responses.hpp>
#include "CacheStructs.h"
class Menu;
class RippleOverlay;
@ -64,7 +65,7 @@ class RoomInfoListItem : public QWidget
Q_PROPERTY(QColor btnTextColor READ btnTextColor WRITE setBtnTextColor)
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 clearUnreadMessageCount() { updateUnreadMessageCount(0, 0); };

View file

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

View file

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

View file

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