Commit f83c0538 authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Reworked sendDeliveryNotifications() called in Core's init to improve...

Reworked sendDeliveryNotifications() called in Core's init to improve performances on large databases
parent a60141b3
......@@ -52,7 +52,9 @@ IdentityAddressParser::IdentityAddressParser () : Singleton(*new IdentityAddress
"scheme = \"sip\" / \"sips\" \r\n"
"user = 1*( alphanum / escaped / \"-\" / \"+\" / \"_\" / \"~\" ) \r\n"
"escaped = \"%\" HEXDIG HEXDIG \r\n"
"host = 1*( alphanum / \".\" ) \r\n"
"host = *( domainlabel \".\" ) toplabel [ \".\" ] \r\n"
"domainlabel = alphanum / (alphanum *( alphanum / ( *(\"-\") alphanum) ) ) \r\n"
"toplabel = ALPHA / (ALPHA *( alphanum / (*(\"-\") alphanum ) ) ) \r\n"
"gruu-parameter = \";gr=\" gruu-value \r\n"
"gruu-value = 1*( alphanum / \"-\" / \"_\" / \":\" ) \r\n"
"alphanum = ALPHA / DIGIT \r\n";
......
......@@ -47,7 +47,7 @@ public:
virtual void addTransientEvent (const std::shared_ptr<EventLog> &eventLog) = 0;
virtual void removeTransientEvent (const std::shared_ptr<EventLog> &eventLog) = 0;
virtual void sendDeliveryNotifications () = 0;
virtual void sendDeliveryNotifications (const std::shared_ptr<ChatMessage> &chatMessage) = 0;
virtual void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) = 0;
virtual void notifyUndecryptableChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) = 0;
......
......@@ -75,7 +75,7 @@ public:
void sendDeliveryErrorNotification (const std::shared_ptr<ChatMessage> &chatMessage, LinphoneReason reason);
void sendDeliveryNotification (const std::shared_ptr<ChatMessage> &chatMessage);
void sendDeliveryNotifications () override;
void sendDeliveryNotifications (const std::shared_ptr<ChatMessage> &chatMessage) override;
void sendDisplayNotification (const std::shared_ptr<ChatMessage> &chatMessage);
void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override;
......
......@@ -186,18 +186,11 @@ void ChatRoomPrivate::sendDeliveryNotification (const shared_ptr<ChatMessage> &c
}
}
void ChatRoomPrivate::sendDeliveryNotifications () {
L_Q();
LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(q->getCore()->getCCore());
if (linphone_im_notif_policy_get_send_imdn_delivered(policy)) {
auto chatMessages = q->getCore()->getPrivate()->mainDb->findChatMessagesToBeNotifiedAsDelivered(q->getConferenceId());
for (const auto &chatMessage : chatMessages) {
ChatMessagePrivate *dChatMessage = chatMessage->getPrivate();
if (dChatMessage->getPositiveDeliveryNotificationRequired()) {
dChatMessage->setPositiveDeliveryNotificationRequired(false);
imdnHandler->notifyDelivery(chatMessage);
}
}
void ChatRoomPrivate::sendDeliveryNotifications (const std::shared_ptr<ChatMessage> &chatMessage) {
ChatMessagePrivate *dChatMessage = chatMessage->getPrivate();
if (dChatMessage->getPositiveDeliveryNotificationRequired()) {
dChatMessage->setPositiveDeliveryNotificationRequired(false);
imdnHandler->notifyDelivery(chatMessage);
}
}
......
......@@ -65,8 +65,8 @@ public:
chatRoom->getPrivate()->removeTransientChatMessage(message);
}
inline void sendDeliveryNotifications () override {
chatRoom->getPrivate()->sendDeliveryNotifications();
inline void sendDeliveryNotifications (const std::shared_ptr<ChatMessage> &chatMessage) override {
chatRoom->getPrivate()->sendDeliveryNotifications(chatMessage);
}
inline void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override {
......
......@@ -311,7 +311,18 @@ void CorePrivate::loadChatRooms () {
if (!mainDb->isInitialized()) return;
for (auto &chatRoom : mainDb->getChatRooms()) {
insertChatRoom(chatRoom);
chatRoom->getPrivate()->sendDeliveryNotifications();
}
sendDeliveryNotifications();
}
void CorePrivate::sendDeliveryNotifications () {
L_Q();
LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(q->getCCore());
if (linphone_im_notif_policy_get_send_imdn_delivered(policy)) {
auto chatMessages = mainDb->findChatMessagesToBeNotifiedAsDelivered();
for (const auto &chatMessage : chatMessages) {
chatMessage->getChatRoom()->getPrivate()->sendDeliveryNotifications(chatMessage);
}
}
}
......
......@@ -74,6 +74,7 @@ public:
void setPlaybackGainDb (AudioStream *stream, float gain);
void loadChatRooms ();
void sendDeliveryNotifications ();
void insertChatRoom (const std::shared_ptr<AbstractChatRoom> &chatRoom);
void insertChatRoomWithDb (const std::shared_ptr<AbstractChatRoom> &chatRoom, unsigned int notifyId = 0);
std::shared_ptr<AbstractChatRoom> createBasicChatRoom (const ConferenceId &conferenceId, AbstractChatRoom::CapabilitiesMask capabilities, const std::shared_ptr<ChatRoomParams> &params);
......
......@@ -39,6 +39,7 @@ 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;
mutable std::unordered_map<long long, ConferenceId> storageIdToConferenceId;
private:
// ---------------------------------------------------------------------------
......@@ -67,6 +68,7 @@ private:
long long selectSipAddressId (const std::string &sipAddress) const;
long long selectChatRoomId (long long peerSipAddressId, long long localSipAddressId) const;
long long selectChatRoomId (const ConferenceId &conferenceId) const;
ConferenceId selectConferenceId (const long long chatRoomId) const;
long long selectChatRoomParticipantId (long long chatRoomId, long long participantSipAddressId) const;
long long selectOneToOneChatRoomId (long long sipAddressIdA, long long sipAddressIdB, bool encrypted) const;
......@@ -79,7 +81,7 @@ private:
// ---------------------------------------------------------------------------
long long getConferenceEventIdFromRow (const soci::row &row) const {
return dbSession.resolveId(row, -1);
return dbSession.resolveId(row, 0);
}
time_t getConferenceEventCreationTimeFromRow (const soci::row &row) const {
......@@ -169,9 +171,11 @@ private:
void cache (const std::shared_ptr<EventLog> &eventLog, long long storageId) const;
void cache (const std::shared_ptr<ChatMessage> &chatMessage, long long storageId) const;
void cache (const ConferenceId &conferenceId, long long storageId) const;
std::shared_ptr<EventLog> getEventFromCache (long long storageId) const;
std::shared_ptr<ChatMessage> getChatMessageFromCache (long long storageId) const;
ConferenceId getConferenceIdFromCache(long long storageId) const;
void invalidConferenceEventsFromQuery (const std::string &query, long long chatRoomId);
......
......@@ -468,7 +468,32 @@ long long MainDbPrivate::selectChatRoomId (const ConferenceId &conferenceId) con
if (localSipAddressId < 0)
return -1;
return selectChatRoomId(peerSipAddressId, localSipAddressId);
long long id = selectChatRoomId(peerSipAddressId, localSipAddressId);
if (id != -1) {
cache(conferenceId, id);
}
return id;
}
ConferenceId MainDbPrivate::selectConferenceId (const long long chatRoomId) const {
string peerSipAddress;
string localSipAddress;
string query = "SELECT peer_sip_address_id, local_sip_address_id FROM chat_room WHERE id = :1";
soci::session *session = dbSession.getBackendSession();
*session << query, soci::use(chatRoomId), soci::into(peerSipAddress), soci::into(localSipAddress);
ConferenceId conferenceId = ConferenceId(
IdentityAddress(peerSipAddress),
IdentityAddress(localSipAddress)
);
if (conferenceId.isValid()) {
cache(conferenceId, chatRoomId);
}
return conferenceId;
}
long long MainDbPrivate::selectChatRoomParticipantId (long long chatRoomId, long long participantSipAddressId) const {
......@@ -1064,6 +1089,15 @@ shared_ptr<ChatMessage> MainDbPrivate::getChatMessageFromCache (long long storag
return chatMessage;
}
ConferenceId MainDbPrivate::getConferenceIdFromCache(long long storageId) const {
auto it = storageIdToConferenceId.find(storageId);
if (it == storageIdToConferenceId.cend())
return ConferenceId();
ConferenceId conferenceId = it->second;
return conferenceId;
}
void MainDbPrivate::cache (const shared_ptr<EventLog> &eventLog, long long storageId) const {
L_Q();
......@@ -1084,6 +1118,11 @@ void MainDbPrivate::cache (const shared_ptr<ChatMessage> &chatMessage, long long
L_ASSERT(dChatMessage->dbKey.isValid());
}
void MainDbPrivate::cache (const ConferenceId &conferenceId, long long storageId) const {
L_ASSERT(conferenceId.isValid());
storageIdToConferenceId[storageId] = conferenceId;
}
void MainDbPrivate::invalidConferenceEventsFromQuery (const string &query, long long chatRoomId) {
soci::rowset<soci::row> rows = (dbSession.getBackendSession()->prepare << query, soci::use(chatRoomId));
for (const auto &row : rows) {
......@@ -2302,11 +2341,14 @@ list<shared_ptr<ChatMessage>> MainDb::findChatMessages (
};
}
list<shared_ptr<ChatMessage>> MainDb::findChatMessagesToBeNotifiedAsDelivered (
const ConferenceId &conferenceId
) const {
static const string query = Statements::get(Statements::SelectConferenceEvents) +
string(" AND direction = :direction AND delivery_notification_required <> 0");
list<shared_ptr<ChatMessage>> MainDb::findChatMessagesToBeNotifiedAsDelivered () const {
static const string query = "SELECT conference_event_view.id AS event_id, type, creation_time, from_sip_address.value, to_sip_address.value, time, imdn_message_id, state, direction, is_secured, notify_id, device_sip_address.value, participant_sip_address.value, subject, delivery_notification_required, display_notification_required, security_alert, faulty_device, marked_as_read, chat_room_id"
" FROM conference_event_view"
" LEFT JOIN sip_address AS from_sip_address ON from_sip_address.id = from_sip_address_id"
" LEFT JOIN sip_address AS to_sip_address ON to_sip_address.id = to_sip_address_id"
" LEFT JOIN sip_address AS device_sip_address ON device_sip_address.id = device_sip_address_id"
" LEFT JOIN sip_address AS participant_sip_address ON participant_sip_address.id = participant_sip_address_id"
" WHERE conference_event_view.id IN (SELECT event_id FROM conference_chat_message_event WHERE direction = :direction AND delivery_notification_required <> 0)";
/*
DurationLogger durationLogger(
......@@ -2318,21 +2360,28 @@ list<shared_ptr<ChatMessage>> MainDb::findChatMessagesToBeNotifiedAsDelivered (
return L_DB_TRANSACTION {
L_D();
shared_ptr<AbstractChatRoom> chatRoom = d->findChatRoom(conferenceId);
list<shared_ptr<ChatMessage>> chatMessages;
if (!chatRoom)
return chatMessages;
const long long &dbChatRoomId = d->selectChatRoomId(conferenceId);
const int &direction = int(ChatMessage::Direction::Incoming);
soci::rowset<soci::row> rows = (
d->dbSession.getBackendSession()->prepare << query, soci::use(dbChatRoomId), soci::use(direction)
d->dbSession.getBackendSession()->prepare << query, soci::use(direction)
);
for (const auto &row : rows) {
shared_ptr<EventLog> event = d->selectGenericConferenceEvent(chatRoom, row);
if (event) {
L_ASSERT(event->getType() == EventLog::Type::ConferenceChatMessage);
chatMessages.push_back(static_pointer_cast<ConferenceChatMessageEvent>(event)->getChatMessage());
const long long &dbChatRoomId = d->dbSession.resolveId(row, 19);
ConferenceId conferenceId = d->getConferenceIdFromCache(dbChatRoomId);
if (!conferenceId.isValid()) {
conferenceId = d->selectConferenceId(dbChatRoomId);
}
if (conferenceId.isValid()) {
shared_ptr<AbstractChatRoom> chatRoom = d->findChatRoom(conferenceId);
if (chatRoom) {
shared_ptr<EventLog> event = d->selectGenericConferenceEvent(chatRoom, row);
if (event) {
L_ASSERT(event->getType() == EventLog::Type::ConferenceChatMessage);
chatMessages.push_back(static_pointer_cast<ConferenceChatMessageEvent>(event)->getChatMessage());
}
}
}
}
......@@ -2579,12 +2628,16 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms () const {
IdentityAddress(row.get<string>(1)),
IdentityAddress(row.get<string>(2))
);
shared_ptr<AbstractChatRoom> chatRoom = core->findChatRoom(conferenceId);
if (chatRoom) {
chatRooms.push_back(chatRoom);
continue;
}
const long long &dbChatRoomId = d->dbSession.resolveId(row, 0);
d->cache(conferenceId, dbChatRoomId);
time_t creationTime = d->dbSession.getTime(row, 3);
time_t lastUpdateTime = d->dbSession.getTime(row, 4);
int capabilities = row.get<int>(5);
......@@ -2600,7 +2653,6 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms () const {
} else if (capabilities & ChatRoom::CapabilitiesMask(ChatRoom::Capabilities::Conference)) {
list<shared_ptr<Participant>> participants;
const long long &dbChatRoomId = d->dbSession.resolveId(row, 0);
static const string query = "SELECT chat_room_participant.id, sip_address.value, is_admin"
" FROM sip_address, chat_room, chat_room_participant"
" WHERE chat_room.id = :chatRoomId"
......
......@@ -126,9 +126,7 @@ public:
const std::string &imdnMessageId
) const;
std::list<std::shared_ptr<ChatMessage>> findChatMessagesToBeNotifiedAsDelivered (
const ConferenceId &conferenceId
) const;
std::list<std::shared_ptr<ChatMessage>> findChatMessagesToBeNotifiedAsDelivered () const;
// ---------------------------------------------------------------------------
// Conference events.
......
......@@ -245,9 +245,9 @@ long long DbSession::resolveId (const soci::row &row, int col) const {
switch (d->backend) {
case DbSessionPrivate::Backend::Mysql:
return static_cast<long long>(row.get<unsigned long long>(0));
return static_cast<long long>(row.get<unsigned long long>((std::size_t)col));
case DbSessionPrivate::Backend::Sqlite3:
return static_cast<long long>(row.get<int>(0));
return static_cast<long long>(row.get<int>((std::size_t)col));
case DbSessionPrivate::Backend::None:
return 0;
}
......
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