Commit 36eea822 authored by François Grisez's avatar François Grisez

Add a cache for unread messagaes count in LinphoneChatRoom

That fix a performance issue when typing a message. The sqlite database
was accessed each time a character was typed in order to mark all
preceeding messages as read. That was done even if all message was marked
as read.

This patch add cache for unread messages count. Then, the count is only carried out
at the first call of linphone_chat_room_get_unread_messages_count(). This function
is used in linphone_chat_room_mark_as_read() to prevent database from being accessed
if all messages are already marked as read.
parent fc5efd1f
......@@ -400,6 +400,7 @@ static LinphoneChatRoom * _linphone_core_create_chat_room(LinphoneCore *lc, Linp
cr->lc = lc;
cr->peer = linphone_address_as_string(addr);
cr->peer_url = addr;
cr->unread_count = -1;
lc->chatrooms = ms_list_append(lc->chatrooms, (void *)cr);
return cr;
}
......@@ -619,6 +620,8 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
msg->dir=LinphoneChatMessageOutgoing;
msg->from=linphone_address_new(identity);
msg->storage_id=linphone_chat_message_store(msg);
if(cr->unread_count >= 0 && !msg->is_read) cr->unread_count++;
// add to transient list
cr->transient_messages = ms_list_append(cr->transient_messages, linphone_chat_message_ref(msg));
......@@ -772,6 +775,10 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
linphone_address_destroy(addr);
msg->storage_id=linphone_chat_message_store(msg);
if(cr->unread_count < 0) cr->unread_count = 1;
else cr->unread_count++;
linphone_chat_room_message_received(cr,lc,msg);
linphone_chat_message_unref(msg);
}
......
......@@ -38,6 +38,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MAX_PATH_SIZE 1024
#include "sqlite3.h"
#include <assert.h>
static ORTP_INLINE LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, unsigned int storage_id){
MSList* transients = cr->transient_messages;
......@@ -286,6 +287,9 @@ void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){
char *buf;
if (lc->db==NULL) return ;
// optimization: do not modify the database if no message is marked as unread
if(linphone_chat_room_get_unread_messages_count(cr) == 0) return;
peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));
buf=sqlite3_mprintf("UPDATE history SET read=%i WHERE remoteContact = %Q;",
......@@ -293,6 +297,8 @@ void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){
linphone_sql_request(lc->db,buf);
sqlite3_free(buf);
ms_free(peer);
cr->unread_count = 0;
}
void linphone_chat_room_update_url(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
......@@ -315,6 +321,9 @@ static int linphone_chat_room_get_messages_count(LinphoneChatRoom *cr, bool_t un
int returnValue;
if (lc->db==NULL) return 0;
// optimization: do not read database if the count is already available in memory
if(unread_only && cr->unread_count >= 0) return cr->unread_count;
peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));
buf=sqlite3_mprintf("SELECT count(*) FROM history WHERE remoteContact = %Q %s;",peer,unread_only?"AND read = 0":"");
......@@ -327,6 +336,11 @@ static int linphone_chat_room_get_messages_count(LinphoneChatRoom *cr, bool_t un
sqlite3_finalize(selectStatement);
sqlite3_free(buf);
ms_free(peer);
/* no need to test the sign of cr->unread_count here
* because it has been tested above */
if(unread_only) cr->unread_count = numrows;
return numrows;
}
......@@ -347,6 +361,11 @@ void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage
buf=sqlite3_mprintf("DELETE FROM history WHERE id = %i;", msg->storage_id);
linphone_sql_request(lc->db,buf);
sqlite3_free(buf);
if(cr->unread_count >= 0 && !msg->is_read) {
assert(cr->unread_count > 0);
cr->unread_count--;
}
}
void linphone_chat_room_delete_history(LinphoneChatRoom *cr){
......@@ -361,6 +380,8 @@ void linphone_chat_room_delete_history(LinphoneChatRoom *cr){
linphone_sql_request(lc->db,buf);
sqlite3_free(buf);
ms_free(peer);
if(cr->unread_count > 0) cr->unread_count = 0;
}
MSList *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int startm, int endm){
......
......@@ -556,6 +556,7 @@ struct _LinphoneChatRoom{
LinphoneAddress *peer_url;
MSList *messages_hist;
MSList *transient_messages;
int unread_count;
LinphoneIsComposingState remote_is_composing;
LinphoneIsComposingState is_composing;
belle_sip_source_t *remote_composing_refresh_timer;
......
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