From 6672f896f120d71263ca29956a3fb056f2d8d607 Mon Sep 17 00:00:00 2001 From: Jim Nelson Date: Fri, 22 Aug 2014 16:02:29 -0700 Subject: [PATCH] Search for incomplete messages in chunks: Bug #725929 This reduces one source of database pauses by searching for incomplete messages in chunks (rather than pull in all the messages in one go). --- src/engine/imap-db/imap-db-folder.vala | 45 +++++++++++++++++++------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/src/engine/imap-db/imap-db-folder.vala b/src/engine/imap-db/imap-db-folder.vala index 32a58d2e..02d73c07 100644 --- a/src/engine/imap-db/imap-db-folder.vala +++ b/src/engine/imap-db/imap-db-folder.vala @@ -2081,20 +2081,41 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics { if (locations == null || locations.size == 0) return; - StringBuilder sql = new StringBuilder(""" - SELECT id FROM MessageTable WHERE fields <> ? - """); - - Db.Statement stmt = cx.prepare(sql.str); - stmt.bind_int(0, Geary.Email.Field.ALL); - - Db.Result results = stmt.exec(cancellable); - + // fetch incomplete locations in chunks Gee.HashSet incomplete_locations = new Gee.HashSet(Collection.int64_hash_func, Collection.int64_equal_func); - while (!results.finished) { - incomplete_locations.add(results.int64_at(0)); - results.next(cancellable); + int start = 0; + for (;;) { + if (start >= locations.size) + break; + + int end = (start + LIST_EMAIL_FIELDS_CHUNK_COUNT).clamp(0, locations.size); + Gee.List slice = locations.slice(start, end); + + StringBuilder sql = new StringBuilder(""" + SELECT id FROM MessageTable WHERE id IN ( + """); + bool first = true; + foreach (LocationIdentifier location_id in slice) { + if (!first) + sql.append(","); + + sql.append(location_id.message_id.to_string()); + first = false; + } + sql.append(") AND fields <> ?"); + + Db.Statement stmt = cx.prepare(sql.str); + stmt.bind_int(0, Geary.Email.Field.ALL); + + Db.Result results = stmt.exec(cancellable); + + while (!results.finished) { + incomplete_locations.add(results.int64_at(0)); + results.next(cancellable); + } + + start = end; } if (incomplete_locations.size == 0) {