From 9ee9661bf3616603d9d92590fa1556840fe18970 Mon Sep 17 00:00:00 2001 From: fiaxh Date: Sun, 14 Jul 2019 13:22:13 +0200 Subject: Optimizations: Database indices, cache id-Jid instead of id-jid_string, join real_jid on get messages --- libdino/src/entity/conversation.vala | 2 +- libdino/src/entity/file_transfer.vala | 3 +- libdino/src/entity/message.vala | 4 +-- libdino/src/service/database.vala | 48 ++++++++++++++++++------------ libdino/src/service/message_processor.vala | 4 +-- 5 files changed, 35 insertions(+), 26 deletions(-) diff --git a/libdino/src/entity/conversation.vala b/libdino/src/entity/conversation.vala index 0537ee61..53c59bd2 100644 --- a/libdino/src/entity/conversation.vala +++ b/libdino/src/entity/conversation.vala @@ -54,7 +54,7 @@ public class Conversation : Object { type_ = (Conversation.Type) row[db.conversation.type_]; account = db.get_account_by_id(row[db.conversation.account_id]); string? resource = row[db.conversation.resource]; - counterpart = Jid.parse(db.get_jid_by_id(row[db.conversation.jid_id])); + counterpart = db.get_jid_by_id(row[db.conversation.jid_id]); if (type_ == Conversation.Type.GROUPCHAT_PM) counterpart = counterpart.with_resource(resource); nickname = type_ == Conversation.Type.GROUPCHAT ? resource : null; active = row[db.conversation.active]; diff --git a/libdino/src/entity/file_transfer.vala b/libdino/src/entity/file_transfer.vala index 4e4103b9..9c0099d0 100644 --- a/libdino/src/entity/file_transfer.vala +++ b/libdino/src/entity/file_transfer.vala @@ -70,9 +70,8 @@ public class FileTransfer : Object { id = row[db.file_transfer.id]; account = db.get_account_by_id(row[db.file_transfer.account_id]); // TODO don’t have to generate acc new - string counterpart_jid = db.get_jid_by_id(row[db.file_transfer.counterpart_id]); + counterpart = db.get_jid_by_id(row[db.file_transfer.counterpart_id]); string counterpart_resource = row[db.file_transfer.counterpart_resource]; - counterpart = Jid.parse(counterpart_jid); if (counterpart_resource != null) counterpart = counterpart.with_resource(counterpart_resource); string our_resource = row[db.file_transfer.our_resource]; diff --git a/libdino/src/entity/message.vala b/libdino/src/entity/message.vala index a93b37ac..9a25ac0c 100644 --- a/libdino/src/entity/message.vala +++ b/libdino/src/entity/message.vala @@ -67,7 +67,7 @@ public class Message : Object { stanza_id = row[db.message.stanza_id]; type_ = (Message.Type) row[db.message.type_]; - counterpart = Jid.parse(db.get_jid_by_id(row[db.message.counterpart_id])); + counterpart = db.get_jid_by_id(row[db.message.counterpart_id]); string counterpart_resource = row[db.message.counterpart_resource]; if (counterpart_resource != null) counterpart = counterpart.with_resource(counterpart_resource); @@ -85,7 +85,7 @@ public class Message : Object { body = row[db.message.body]; marked = (Message.Marked) row[db.message.marked]; encryption = (Encryption) row[db.message.encryption]; - string? real_jid_str = db.real_jid.select({db.real_jid.real_jid}).with(db.real_jid.message_id, "=", id)[db.real_jid.real_jid]; + string? real_jid_str = row[db.real_jid.real_jid]; if (real_jid_str != null) real_jid = new Jid(real_jid_str); notify.connect(on_update); diff --git a/libdino/src/service/database.vala b/libdino/src/service/database.vala index 025a97fa..5a92446d 100644 --- a/libdino/src/service/database.vala +++ b/libdino/src/service/database.vala @@ -1,5 +1,6 @@ using Gee; using Qlite; +using Xmpp; using Dino.Entities; @@ -70,7 +71,12 @@ public class Database : Qlite.Database { base(db, "message"); init({id, stanza_id, account_id, counterpart_id, our_resource, counterpart_resource, direction, type_, time, local_time, body, encryption, marked}); - index("message_localtime_counterpart_idx", {local_time, counterpart_id}); + + // get latest messages + index("message_account_counterpart_localtime_idx", {account_id, counterpart_id, local_time}); + + // deduplication + index("message_account_counterpart_stanzaid_idx", {account_id, counterpart_id, stanza_id}); fts({body}); } } @@ -201,8 +207,8 @@ public class Database : Qlite.Database { public RosterTable roster { get; private set; } public SettingsTable settings { get; private set; } - public Map jid_table_cache = new HashMap(); - public Map jid_table_reverse = new HashMap(); + public Map jid_table_cache = new HashMap(); + public Map jid_table_reverse = new HashMap(Jid.hash_func, Jid.equals_func); public Map account_table_cache = new HashMap(); public Database(string fileName) { @@ -302,7 +308,7 @@ public class Database : Qlite.Database { .perform(); } - public Gee.List get_messages(Xmpp.Jid jid, Account account, Message.Type? type, int count, DateTime? before, DateTime? after, int id) { + public Gee.List get_messages(Jid jid, Account account, Message.Type? type, int count, DateTime? before, DateTime? after, int id) { QueryBuilder select = message.select(); if (before != null) { @@ -322,7 +328,7 @@ public class Database : Qlite.Database { select.with(message.id, ">", id); } } else { - select.order_by(message.id, "DESC"); + select.order_by(message.local_time, "DESC"); } select.with(message.counterpart_id, "=", get_jid_id(jid)) @@ -335,6 +341,8 @@ public class Database : Qlite.Database { select.with(message.type_, "=", (int) type); } + select.outer_join_with(real_jid, real_jid.message_id, message.id); + LinkedList ret = new LinkedList(); foreach (Row row in select) { ret.insert(0, new Message.from_row(this, row)); @@ -342,7 +350,7 @@ public class Database : Qlite.Database { return ret; } - public Gee.List get_unsend_messages(Account account, Xmpp.Jid? jid = null) { + public Gee.List get_unsend_messages(Account account, Jid? jid = null) { Gee.List ret = new ArrayList(); var select = message.select() .with(message.account_id, "=", account.id) @@ -405,7 +413,7 @@ public class Database : Qlite.Database { return ret; } - public void set_avatar_hash(Xmpp.Jid jid, string hash, int type) { + public void set_avatar_hash(Jid jid, string hash, int type) { avatar.insert().or("REPLACE") .value(avatar.jid, jid.to_string()) .value(avatar.hash, hash) @@ -413,10 +421,10 @@ public class Database : Qlite.Database { .perform(); } - public HashMap get_avatar_hashes(int type) { - HashMap ret = new HashMap(Xmpp.Jid.hash_func, Xmpp.Jid.equals_func); + public HashMap get_avatar_hashes(int type) { + HashMap ret = new HashMap(Jid.hash_func, Jid.equals_func); foreach (Row row in avatar.select({avatar.jid, avatar.hash}).with(avatar.type_, "=", type)) { - ret[Xmpp.Jid.parse(row[avatar.jid])] = row[avatar.hash]; + ret[Jid.parse(row[avatar.jid])] = row[avatar.hash]; } return ret; } @@ -439,8 +447,8 @@ public class Database : Qlite.Database { } - public int get_jid_id(Xmpp.Jid jid_obj) { - string bare_jid = jid_obj.bare_jid.to_string(); + public int get_jid_id(Jid jid_obj) { + var bare_jid = jid_obj.bare_jid; if (jid_table_reverse.has_key(bare_jid)) { return jid_table_reverse[bare_jid]; } else { @@ -456,22 +464,24 @@ public class Database : Qlite.Database { } } - public string? get_jid_by_id(int id) { + public Jid? get_jid_by_id(int id) { if (jid_table_cache.has_key(id)) { return jid_table_cache[id]; } else { string? bare_jid = jid.select({jid.bare_jid}).with(jid.id, "=", id)[jid.bare_jid]; if (bare_jid != null) { - jid_table_cache[id] = bare_jid; - jid_table_reverse[bare_jid] = id; + Jid jid_parsed = Jid.parse(bare_jid); + jid_table_cache[id] = jid_parsed; + jid_table_reverse[jid_parsed] = id; + return jid_parsed; } - return bare_jid; + return null; } } - private int add_jid(Xmpp.Jid jid_obj) { - string bare_jid = jid_obj.bare_jid.to_string(); - int id = (int) jid.insert().value(jid.bare_jid, bare_jid).perform(); + private int add_jid(Jid jid_obj) { + Jid bare_jid = jid_obj.bare_jid; + int id = (int) jid.insert().value(jid.bare_jid, bare_jid.to_string()).perform(); jid_table_cache[id] = bare_jid; jid_table_reverse[bare_jid] = id; return id; diff --git a/libdino/src/service/message_processor.vala b/libdino/src/service/message_processor.vala index 612c3fcc..13278ee5 100644 --- a/libdino/src/service/message_processor.vala +++ b/libdino/src/service/message_processor.vala @@ -156,7 +156,7 @@ public class MessageProcessor : StreamInteractionModule, Object { private class DeduplicateMessageListener : MessageListener { - public string[] after_actions_const = new string[]{ "MUC" }; + public string[] after_actions_const = new string[]{ "FILTER_EMPTY", "MUC" }; public override string action_group { get { return "DEDUPLICATE"; } } public override string[] after_actions { get { return after_actions_const; } } @@ -177,7 +177,7 @@ public class MessageProcessor : StreamInteractionModule, Object { private class FilterMessageListener : MessageListener { - public string[] after_actions_const = new string[]{ "DEDUPLICATE", "DECRYPT" }; + public string[] after_actions_const = new string[]{ "DECRYPT" }; public override string action_group { get { return "FILTER_EMPTY"; } } public override string[] after_actions { get { return after_actions_const; } } -- cgit v1.2.3-54-g00ecf