[geary] Search for incomplete messages in chunks: Bug #725929



commit 6672f896f120d71263ca29956a3fb056f2d8d607
Author: Jim Nelson <jim yorba org>
Date:   Fri Aug 22 16:02:29 2014 -0700

    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 files 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 32a58d2..02d73c0 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<int64?> incomplete_locations = new Gee.HashSet<int64?>(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<LocationIdentifier> 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) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]