From 65ab7cdfa34897c79ba283a53490232548d2fb3c Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Wed, 29 Nov 2017 11:33:43 +0100 Subject: [PATCH] feat(chat-message): supports cache partially --- src/CMakeLists.txt | 2 + src/chat/chat-message/chat-message-p.h | 8 ++- src/chat/chat-message/chat-message.h | 1 + src/core/core.h | 3 +- src/db/main-db-chat-message-key.cpp | 44 ++++++++++++ src/db/main-db-chat-message-key.h | 41 +++++++++++ src/db/main-db-p.h | 8 ++- src/db/main-db.cpp | 97 ++++++++++++++++++-------- src/db/main-db.h | 1 + 9 files changed, 172 insertions(+), 33 deletions(-) create mode 100644 src/db/main-db-chat-message-key.cpp create mode 100644 src/db/main-db-chat-message-key.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f9d78b8fc..bf085340b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -96,6 +96,7 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES core/platform-helpers/platform-helpers.h db/abstract/abstract-db-p.h db/abstract/abstract-db.h + db/main-db-chat-message-key.h db/main-db-event-key.h db/main-db-key-p.h db/main-db-key.h @@ -200,6 +201,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES core/paths/paths.cpp core/platform-helpers/platform-helpers.cpp db/abstract/abstract-db.cpp + db/main-db-chat-message-key.cpp db/main-db-event-key.cpp db/main-db-key.cpp db/main-db.cpp diff --git a/src/chat/chat-message/chat-message-p.h b/src/chat/chat-message/chat-message-p.h index 784fd062b..6d3f2761f 100644 --- a/src/chat/chat-message/chat-message-p.h +++ b/src/chat/chat-message/chat-message-p.h @@ -30,6 +30,7 @@ #include "content/content.h" #include "content/file-content.h" #include "content/file-transfer-content.h" +#include "db/main-db-chat-message-key.h" #include "event-log/conference/conference-chat-message-event.h" #include "object/object-p.h" #include "sal/sal.h" @@ -148,11 +149,16 @@ private: ContentType cContentType; std::string cText; + std::weak_ptr chatEvent; + // TODO: Remove my comment. VARIABLES OK. // Do not expose. +public: + mutable MainDbChatMessageKey dbKey; + +private: std::weak_ptr chatRoom; - std::weak_ptr chatEvent; ChatRoomId chatRoomId; IdentityAddress fromAddress; IdentityAddress toAddress; diff --git a/src/chat/chat-message/chat-message.h b/src/chat/chat-message/chat-message.h index 7fdf0e61d..a582dcee8 100644 --- a/src/chat/chat-message/chat-message.h +++ b/src/chat/chat-message/chat-message.h @@ -45,6 +45,7 @@ class LINPHONE_PUBLIC ChatMessage : public Object, public CoreAccessor { friend class ChatRoomPrivate; friend class CpimChatMessageModifier; friend class FileTransferChatMessageModifier; + friend class MainDb; friend class MainDbPrivate; friend class RealTimeTextChatRoomPrivate; friend class ServerGroupChatRoomPrivate; diff --git a/src/core/core.h b/src/core/core.h index 9a4efbfe1..9aeab7697 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -36,12 +36,13 @@ class CorePrivate; class IdentityAddress; class LINPHONE_PUBLIC Core : public Object { + friend class ChatMessagePrivate; friend class ChatRoom; friend class ChatRoomPrivate; - friend class ChatMessagePrivate; friend class ClientGroupChatRoom; friend class LocalConferenceEventHandlerPrivate; friend class MainDb; + friend class MainDbChatMessageKey; friend class MainDbEventKey; friend class ServerGroupChatRoomPrivate; diff --git a/src/db/main-db-chat-message-key.cpp b/src/db/main-db-chat-message-key.cpp new file mode 100644 index 000000000..1d327e057 --- /dev/null +++ b/src/db/main-db-chat-message-key.cpp @@ -0,0 +1,44 @@ +/* + * main-db-chat-message-key.cpp + * Copyright (C) 2010-2017 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "core/core-p.h" +#include "main-db-chat-message-key.h" +#include "main-db-key-p.h" +#include "main-db-p.h" + +// ============================================================================= + +using namespace std; + +LINPHONE_BEGIN_NAMESPACE + +// ----------------------------------------------------------------------------- + +MainDbChatMessageKey::MainDbChatMessageKey () : MainDbKey() {}; + +MainDbChatMessageKey::MainDbChatMessageKey (const shared_ptr &core, long long storageId) : MainDbKey(core, storageId) {} + +MainDbChatMessageKey::~MainDbChatMessageKey () { + L_D(); + + if (isValid()) + d->core.lock()->getPrivate()->mainDb->getPrivate()->storageIdToChatMessage.erase(d->storageId); +} + +LINPHONE_END_NAMESPACE diff --git a/src/db/main-db-chat-message-key.h b/src/db/main-db-chat-message-key.h new file mode 100644 index 000000000..2a952684f --- /dev/null +++ b/src/db/main-db-chat-message-key.h @@ -0,0 +1,41 @@ +/* + * main-db-chat-message-key.h + * Copyright (C) 2010-2017 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MAIN_DB_CHAT_MESSAGE_KEY_H_ +#define _MAIN_DB_CHAT_MESSAGE_KEY_H_ + +#include "main-db-key.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class MainDbChatMessageKey : public MainDbKey { +public: + MainDbChatMessageKey (); + MainDbChatMessageKey (const std::shared_ptr &core, long long storageId); + ~MainDbChatMessageKey (); + +private: + L_DECLARE_PRIVATE(MainDbKey); +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _MAIN_DB_CHAT_MESSAGE_KEY_H_ diff --git a/src/db/main-db-p.h b/src/db/main-db-p.h index 85376da2f..e871661d2 100644 --- a/src/db/main-db-p.h +++ b/src/db/main-db-p.h @@ -37,6 +37,7 @@ class Content; class MainDbPrivate : public AbstractDbPrivate { public: mutable std::unordered_map> storageIdToEvent; + mutable std::unordered_map> storageIdToChatMessage; private: // --------------------------------------------------------------------------- @@ -136,7 +137,12 @@ private: // Cache API. // --------------------------------------------------------------------------- - std::shared_ptr getEventFromCache (long long eventId) const; + void cache (const std::shared_ptr &eventLog, long long storageId) const; + void cache (const std::shared_ptr &chatMessage, long long storageId) const; + + std::shared_ptr getEventFromCache (long long storageId) const; + std::shared_ptr getChatMessageFromCache (long long storageId) const; + void invalidConferenceEventsFromQuery (const std::string &query, long long chatRoomId); L_DECLARE_PUBLIC(MainDb); diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index 822b27a05..188b3f693 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -343,8 +343,6 @@ MainDb::MainDb (const shared_ptr &core) : AbstractDb(*new MainDbPrivate), time_t creationTime, const ChatRoomId &chatRoomId ) const { - L_Q(); - shared_ptr eventLog; switch (type) { @@ -382,16 +380,10 @@ MainDb::MainDb (const shared_ptr &core) : AbstractDb(*new MainDbPrivate), break; } - if (eventLog) { - EventLogPrivate *dEventLog = eventLog->getPrivate(); - L_ASSERT(!dEventLog->dbKey.isValid()); - dEventLog->dbKey = MainDbEventKey(q->getCore(), eventId); - storageIdToEvent[eventId] = eventLog; - L_ASSERT(dEventLog->dbKey.isValid()); - return eventLog; - } + if (eventLog) + cache(eventLog, eventId); - return nullptr; + return eventLog; } shared_ptr MainDbPrivate::selectConferenceEvent ( @@ -426,15 +418,14 @@ MainDb::MainDb (const shared_ptr &core) : AbstractDb(*new MainDbPrivate), L_Q(); shared_ptr core = q->getCore(); - shared_ptr chatRoom = core->findChatRoom(chatRoomId); if (!chatRoom) return nullptr; - // TODO: Use cache, do not fetch the same message twice. - // 1 - Fetch chat message. - shared_ptr chatMessage; + shared_ptr chatMessage = getChatMessageFromCache(eventId); + if (chatMessage) + goto end; { string fromSipAddress; string toSipAddress; @@ -509,7 +500,7 @@ MainDb::MainDb (const shared_ptr &core) : AbstractDb(*new MainDbPrivate), } } - // TODO: Use cache. + end: return make_shared( creationTime, chatMessage @@ -800,8 +791,8 @@ MainDb::MainDb (const shared_ptr &core) : AbstractDb(*new MainDbPrivate), // ----------------------------------------------------------------------------- - shared_ptr MainDbPrivate::getEventFromCache (long long eventId) const { - auto it = storageIdToEvent.find(eventId); + shared_ptr MainDbPrivate::getEventFromCache (long long storageId) const { + auto it = storageIdToEvent.find(storageId); if (it == storageIdToEvent.cend()) return nullptr; @@ -811,6 +802,37 @@ MainDb::MainDb (const shared_ptr &core) : AbstractDb(*new MainDbPrivate), return eventLog; } + shared_ptr MainDbPrivate::getChatMessageFromCache (long long storageId) const { + auto it = storageIdToChatMessage.find(storageId); + if (it == storageIdToChatMessage.cend()) + return nullptr; + + shared_ptr chatMessage = it->second.lock(); + // Must exist. If not, implementation bug. + L_ASSERT(chatMessage); + return chatMessage; + } + + void MainDbPrivate::cache (const shared_ptr &eventLog, long long storageId) const { + L_Q(); + + EventLogPrivate *dEventLog = eventLog->getPrivate(); + L_ASSERT(!dEventLog->dbKey.isValid()); + dEventLog->dbKey = MainDbEventKey(q->getCore(), storageId); + storageIdToEvent[storageId] = eventLog; + L_ASSERT(dEventLog->dbKey.isValid()); + } + + void MainDbPrivate::cache (const shared_ptr &chatMessage, long long storageId) const { + L_Q(); + + ChatMessagePrivate *dChatMessage = chatMessage->getPrivate(); + L_ASSERT(!dChatMessage->dbKey.isValid()); + dChatMessage->dbKey = MainDbChatMessageKey(q->getCore(), storageId); + storageIdToChatMessage[storageId] = chatMessage; + L_ASSERT(dChatMessage->dbKey.isValid()); + } + void MainDbPrivate::invalidConferenceEventsFromQuery (const string &query, long long chatRoomId) { soci::session *session = dbSession.getBackendSession(); soci::rowset rows = (session->prepare << query, soci::use(chatRoomId)); @@ -1127,7 +1149,8 @@ MainDb::MainDb (const shared_ptr &core) : AbstractDb(*new MainDbPrivate), soci::transaction tr(*d->dbSession.getBackendSession()); - switch (eventLog->getType()) { + EventLog::Type type = eventLog->getType(); + switch (type) { case EventLog::Type::None: return false; @@ -1162,18 +1185,18 @@ MainDb::MainDb (const shared_ptr &core) : AbstractDb(*new MainDbPrivate), break; } - if ((soFarSoGood = storageId >= 0)) + if (storageId >= 0) { tr.commit(); + d->cache(eventLog, storageId); + + if (type == EventLog::Type::ConferenceChatMessage) + d->cache(static_pointer_cast(eventLog)->getChatMessage(), storageId); + + soFarSoGood = true; + } L_END_LOG_EXCEPTION - if (soFarSoGood) { - L_ASSERT(!dEventLog->dbKey.isValid()); - dEventLog->dbKey = MainDbEventKey(getCore(), storageId); - d->storageIdToEvent[storageId] = eventLog; - L_ASSERT(dEventLog->dbKey.isValid()); - } - return soFarSoGood; } @@ -1246,11 +1269,18 @@ MainDb::MainDb (const shared_ptr &core) : AbstractDb(*new MainDbPrivate), soci::session *session = mainDb.getPrivate()->dbSession.getBackendSession(); *session << "DELETE FROM event WHERE id = :id", soci::use(dEventKey->storageId); - L_END_LOG_EXCEPTION - dEventLog->dbKey = MainDbEventKey(); + if (eventLog->getType() == EventLog::Type::ConferenceChatMessage) + static_pointer_cast( + eventLog + )->getChatMessage()->getPrivate()->dbKey = MainDbChatMessageKey(); + return true; + + L_END_LOG_EXCEPTION + + return false; } int MainDb::getEventsCount (FilterMask mask) const { @@ -1705,7 +1735,14 @@ MainDb::MainDb (const shared_ptr &core) : AbstractDb(*new MainDbPrivate), continue; } - chatRoom = make_shared(core, chatRoomId.getPeerAddress(), me, subject, move(participants), lastNotifyId); + chatRoom = make_shared( + core, + chatRoomId.getPeerAddress(), + me, + subject, + move(participants), + lastNotifyId + ); } if (!chatRoom) diff --git a/src/db/main-db.h b/src/db/main-db.h index 2cd5de58f..7c371444e 100644 --- a/src/db/main-db.h +++ b/src/db/main-db.h @@ -37,6 +37,7 @@ class EventLog; class MainDbPrivate; class MainDb : public AbstractDb, public CoreAccessor { + friend class MainDbChatMessageKey; friend class MainDbEventKey; public: