Optimizations: Database indices, cache id-Jid instead of id-jid_string, join real_jid on get messages
This commit is contained in:
parent
3719596059
commit
9ee9661bf3
|
@ -54,7 +54,7 @@ public class Conversation : Object {
|
||||||
type_ = (Conversation.Type) row[db.conversation.type_];
|
type_ = (Conversation.Type) row[db.conversation.type_];
|
||||||
account = db.get_account_by_id(row[db.conversation.account_id]);
|
account = db.get_account_by_id(row[db.conversation.account_id]);
|
||||||
string? resource = row[db.conversation.resource];
|
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);
|
if (type_ == Conversation.Type.GROUPCHAT_PM) counterpart = counterpart.with_resource(resource);
|
||||||
nickname = type_ == Conversation.Type.GROUPCHAT ? resource : null;
|
nickname = type_ == Conversation.Type.GROUPCHAT ? resource : null;
|
||||||
active = row[db.conversation.active];
|
active = row[db.conversation.active];
|
||||||
|
|
|
@ -70,9 +70,8 @@ public class FileTransfer : Object {
|
||||||
id = row[db.file_transfer.id];
|
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
|
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];
|
string counterpart_resource = row[db.file_transfer.counterpart_resource];
|
||||||
counterpart = Jid.parse(counterpart_jid);
|
|
||||||
if (counterpart_resource != null) counterpart = counterpart.with_resource(counterpart_resource);
|
if (counterpart_resource != null) counterpart = counterpart.with_resource(counterpart_resource);
|
||||||
|
|
||||||
string our_resource = row[db.file_transfer.our_resource];
|
string our_resource = row[db.file_transfer.our_resource];
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class Message : Object {
|
||||||
stanza_id = row[db.message.stanza_id];
|
stanza_id = row[db.message.stanza_id];
|
||||||
type_ = (Message.Type) row[db.message.type_];
|
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];
|
string counterpart_resource = row[db.message.counterpart_resource];
|
||||||
if (counterpart_resource != null) counterpart = counterpart.with_resource(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];
|
body = row[db.message.body];
|
||||||
marked = (Message.Marked) row[db.message.marked];
|
marked = (Message.Marked) row[db.message.marked];
|
||||||
encryption = (Encryption) row[db.message.encryption];
|
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);
|
if (real_jid_str != null) real_jid = new Jid(real_jid_str);
|
||||||
|
|
||||||
notify.connect(on_update);
|
notify.connect(on_update);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
using Qlite;
|
using Qlite;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
|
||||||
|
@ -70,7 +71,12 @@ public class Database : Qlite.Database {
|
||||||
base(db, "message");
|
base(db, "message");
|
||||||
init({id, stanza_id, account_id, counterpart_id, our_resource, counterpart_resource, direction,
|
init({id, stanza_id, account_id, counterpart_id, our_resource, counterpart_resource, direction,
|
||||||
type_, time, local_time, body, encryption, marked});
|
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});
|
fts({body});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,8 +207,8 @@ public class Database : Qlite.Database {
|
||||||
public RosterTable roster { get; private set; }
|
public RosterTable roster { get; private set; }
|
||||||
public SettingsTable settings { get; private set; }
|
public SettingsTable settings { get; private set; }
|
||||||
|
|
||||||
public Map<int, string> jid_table_cache = new HashMap<int, string>();
|
public Map<int, Jid> jid_table_cache = new HashMap<int, Jid>();
|
||||||
public Map<string, int> jid_table_reverse = new HashMap<string, int>();
|
public Map<Jid, int> jid_table_reverse = new HashMap<Jid, int>(Jid.hash_func, Jid.equals_func);
|
||||||
public Map<int, Account> account_table_cache = new HashMap<int, Account>();
|
public Map<int, Account> account_table_cache = new HashMap<int, Account>();
|
||||||
|
|
||||||
public Database(string fileName) {
|
public Database(string fileName) {
|
||||||
|
@ -302,7 +308,7 @@ public class Database : Qlite.Database {
|
||||||
.perform();
|
.perform();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gee.List<Message> get_messages(Xmpp.Jid jid, Account account, Message.Type? type, int count, DateTime? before, DateTime? after, int id) {
|
public Gee.List<Message> get_messages(Jid jid, Account account, Message.Type? type, int count, DateTime? before, DateTime? after, int id) {
|
||||||
QueryBuilder select = message.select();
|
QueryBuilder select = message.select();
|
||||||
|
|
||||||
if (before != null) {
|
if (before != null) {
|
||||||
|
@ -322,7 +328,7 @@ public class Database : Qlite.Database {
|
||||||
select.with(message.id, ">", id);
|
select.with(message.id, ">", id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
select.order_by(message.id, "DESC");
|
select.order_by(message.local_time, "DESC");
|
||||||
}
|
}
|
||||||
|
|
||||||
select.with(message.counterpart_id, "=", get_jid_id(jid))
|
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.with(message.type_, "=", (int) type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select.outer_join_with(real_jid, real_jid.message_id, message.id);
|
||||||
|
|
||||||
LinkedList<Message> ret = new LinkedList<Message>();
|
LinkedList<Message> ret = new LinkedList<Message>();
|
||||||
foreach (Row row in select) {
|
foreach (Row row in select) {
|
||||||
ret.insert(0, new Message.from_row(this, row));
|
ret.insert(0, new Message.from_row(this, row));
|
||||||
|
@ -342,7 +350,7 @@ public class Database : Qlite.Database {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gee.List<Message> get_unsend_messages(Account account, Xmpp.Jid? jid = null) {
|
public Gee.List<Message> get_unsend_messages(Account account, Jid? jid = null) {
|
||||||
Gee.List<Message> ret = new ArrayList<Message>();
|
Gee.List<Message> ret = new ArrayList<Message>();
|
||||||
var select = message.select()
|
var select = message.select()
|
||||||
.with(message.account_id, "=", account.id)
|
.with(message.account_id, "=", account.id)
|
||||||
|
@ -405,7 +413,7 @@ public class Database : Qlite.Database {
|
||||||
return ret;
|
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")
|
avatar.insert().or("REPLACE")
|
||||||
.value(avatar.jid, jid.to_string())
|
.value(avatar.jid, jid.to_string())
|
||||||
.value(avatar.hash, hash)
|
.value(avatar.hash, hash)
|
||||||
|
@ -413,10 +421,10 @@ public class Database : Qlite.Database {
|
||||||
.perform();
|
.perform();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap<Xmpp.Jid, string> get_avatar_hashes(int type) {
|
public HashMap<Jid, string> get_avatar_hashes(int type) {
|
||||||
HashMap<Xmpp.Jid, string> ret = new HashMap<Xmpp.Jid, string>(Xmpp.Jid.hash_func, Xmpp.Jid.equals_func);
|
HashMap<Jid, string> ret = new HashMap<Jid, string>(Jid.hash_func, Jid.equals_func);
|
||||||
foreach (Row row in avatar.select({avatar.jid, avatar.hash}).with(avatar.type_, "=", type)) {
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -439,8 +447,8 @@ public class Database : Qlite.Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int get_jid_id(Xmpp.Jid jid_obj) {
|
public int get_jid_id(Jid jid_obj) {
|
||||||
string bare_jid = jid_obj.bare_jid.to_string();
|
var bare_jid = jid_obj.bare_jid;
|
||||||
if (jid_table_reverse.has_key(bare_jid)) {
|
if (jid_table_reverse.has_key(bare_jid)) {
|
||||||
return jid_table_reverse[bare_jid];
|
return jid_table_reverse[bare_jid];
|
||||||
} else {
|
} 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)) {
|
if (jid_table_cache.has_key(id)) {
|
||||||
return jid_table_cache[id];
|
return jid_table_cache[id];
|
||||||
} else {
|
} else {
|
||||||
string? bare_jid = jid.select({jid.bare_jid}).with(jid.id, "=", id)[jid.bare_jid];
|
string? bare_jid = jid.select({jid.bare_jid}).with(jid.id, "=", id)[jid.bare_jid];
|
||||||
if (bare_jid != null) {
|
if (bare_jid != null) {
|
||||||
jid_table_cache[id] = bare_jid;
|
Jid jid_parsed = Jid.parse(bare_jid);
|
||||||
jid_table_reverse[bare_jid] = id;
|
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) {
|
private int add_jid(Jid jid_obj) {
|
||||||
string bare_jid = jid_obj.bare_jid.to_string();
|
Jid bare_jid = jid_obj.bare_jid;
|
||||||
int id = (int) jid.insert().value(jid.bare_jid, bare_jid).perform();
|
int id = (int) jid.insert().value(jid.bare_jid, bare_jid.to_string()).perform();
|
||||||
jid_table_cache[id] = bare_jid;
|
jid_table_cache[id] = bare_jid;
|
||||||
jid_table_reverse[bare_jid] = id;
|
jid_table_reverse[bare_jid] = id;
|
||||||
return id;
|
return id;
|
||||||
|
|
|
@ -156,7 +156,7 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
|
|
||||||
private class DeduplicateMessageListener : MessageListener {
|
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 action_group { get { return "DEDUPLICATE"; } }
|
||||||
public override string[] after_actions { get { return after_actions_const; } }
|
public override string[] after_actions { get { return after_actions_const; } }
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
|
|
||||||
private class FilterMessageListener : MessageListener {
|
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 action_group { get { return "FILTER_EMPTY"; } }
|
||||||
public override string[] after_actions { get { return after_actions_const; } }
|
public override string[] after_actions { get { return after_actions_const; } }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue