Commit 65ab7cdf authored by Ronan's avatar Ronan

feat(chat-message): supports cache partially

parent bed2dbf6
......@@ -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
......
......@@ -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<ConferenceChatMessageEvent> chatEvent;
// TODO: Remove my comment. VARIABLES OK.
// Do not expose.
public:
mutable MainDbChatMessageKey dbKey;
private:
std::weak_ptr<ChatRoom> chatRoom;
std::weak_ptr<ConferenceChatMessageEvent> chatEvent;
ChatRoomId chatRoomId;
IdentityAddress fromAddress;
IdentityAddress toAddress;
......
......@@ -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;
......
......@@ -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;
......
/*
* 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> &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
/*
* 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> &core, long long storageId);
~MainDbChatMessageKey ();
private:
L_DECLARE_PRIVATE(MainDbKey);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _MAIN_DB_CHAT_MESSAGE_KEY_H_
......@@ -37,6 +37,7 @@ class Content;
class MainDbPrivate : public AbstractDbPrivate {
public:
mutable std::unordered_map<long long, std::weak_ptr<EventLog>> storageIdToEvent;
mutable std::unordered_map<long long, std::weak_ptr<ChatMessage>> storageIdToChatMessage;
private:
// ---------------------------------------------------------------------------
......@@ -136,7 +137,12 @@ private:
// Cache API.
// ---------------------------------------------------------------------------
std::shared_ptr<EventLog> getEventFromCache (long long eventId) const;
void cache (const std::shared_ptr<EventLog> &eventLog, long long storageId) const;
void cache (const std::shared_ptr<ChatMessage> &chatMessage, long long storageId) const;
std::shared_ptr<EventLog> getEventFromCache (long long storageId) const;
std::shared_ptr<ChatMessage> getChatMessageFromCache (long long storageId) const;
void invalidConferenceEventsFromQuery (const std::string &query, long long chatRoomId);
L_DECLARE_PUBLIC(MainDb);
......
......@@ -343,8 +343,6 @@ MainDb::MainDb (const shared_ptr<Core> &core) : AbstractDb(*new MainDbPrivate),
time_t creationTime,
const ChatRoomId &chatRoomId
) const {
L_Q();
shared_ptr<EventLog> eventLog;
switch (type) {
......@@ -382,16 +380,10 @@ MainDb::MainDb (const shared_ptr<Core> &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<EventLog> MainDbPrivate::selectConferenceEvent (
......@@ -426,15 +418,14 @@ MainDb::MainDb (const shared_ptr<Core> &core) : AbstractDb(*new MainDbPrivate),
L_Q();
shared_ptr<Core> core = q->getCore();
shared_ptr<ChatRoom> 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> chatMessage;
shared_ptr<ChatMessage> chatMessage = getChatMessageFromCache(eventId);
if (chatMessage)
goto end;
{
string fromSipAddress;
string toSipAddress;
......@@ -509,7 +500,7 @@ MainDb::MainDb (const shared_ptr<Core> &core) : AbstractDb(*new MainDbPrivate),
}
}
// TODO: Use cache.
end:
return make_shared<ConferenceChatMessageEvent>(
creationTime,
chatMessage
......@@ -800,8 +791,8 @@ MainDb::MainDb (const shared_ptr<Core> &core) : AbstractDb(*new MainDbPrivate),
// -----------------------------------------------------------------------------
shared_ptr<EventLog> MainDbPrivate::getEventFromCache (long long eventId) const {
auto it = storageIdToEvent.find(eventId);
shared_ptr<EventLog> 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> &core) : AbstractDb(*new MainDbPrivate),
return eventLog;
}
shared_ptr<ChatMessage> MainDbPrivate::getChatMessageFromCache (long long storageId) const {
auto it = storageIdToChatMessage.find(storageId);
if (it == storageIdToChatMessage.cend())
return nullptr;
shared_ptr<ChatMessage> chatMessage = it->second.lock();
// Must exist. If not, implementation bug.
L_ASSERT(chatMessage);
return chatMessage;
}
void MainDbPrivate::cache (const shared_ptr<EventLog> &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> &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::session>();
soci::rowset<soci::row> rows = (session->prepare << query, soci::use(chatRoomId));
......@@ -1127,7 +1149,8 @@ MainDb::MainDb (const shared_ptr<Core> &core) : AbstractDb(*new MainDbPrivate),
soci::transaction tr(*d->dbSession.getBackendSession<soci::session>());
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> &core) : AbstractDb(*new MainDbPrivate),
break;
}
if ((soFarSoGood = storageId >= 0))
if (storageId >= 0) {
tr.commit();
d->cache(eventLog, storageId);
L_END_LOG_EXCEPTION
if (type == EventLog::Type::ConferenceChatMessage)
d->cache(static_pointer_cast<ConferenceChatMessageEvent>(eventLog)->getChatMessage(), storageId);
if (soFarSoGood) {
L_ASSERT(!dEventLog->dbKey.isValid());
dEventLog->dbKey = MainDbEventKey(getCore(), storageId);
d->storageIdToEvent[storageId] = eventLog;
L_ASSERT(dEventLog->dbKey.isValid());
soFarSoGood = true;
}
L_END_LOG_EXCEPTION
return soFarSoGood;
}
......@@ -1246,11 +1269,18 @@ MainDb::MainDb (const shared_ptr<Core> &core) : AbstractDb(*new MainDbPrivate),
soci::session *session = mainDb.getPrivate()->dbSession.getBackendSession<soci::session>();
*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<ConferenceChatMessageEvent>(
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> &core) : AbstractDb(*new MainDbPrivate),
continue;
}
chatRoom = make_shared<ClientGroupChatRoom>(core, chatRoomId.getPeerAddress(), me, subject, move(participants), lastNotifyId);
chatRoom = make_shared<ClientGroupChatRoom>(
core,
chatRoomId.getPeerAddress(),
me,
subject,
move(participants),
lastNotifyId
);
}
if (!chatRoom)
......
......@@ -37,6 +37,7 @@ class EventLog;
class MainDbPrivate;
class MainDb : public AbstractDb, public CoreAccessor {
friend class MainDbChatMessageKey;
friend class MainDbEventKey;
public:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment