add imap number cache to SqliteMailbox
authoradam <adam@megacz.com>
Sat, 1 Mar 2008 07:42:17 +0000 (07:42 +0000)
committeradam <adam@megacz.com>
Sat, 1 Mar 2008 07:42:17 +0000 (07:42 +0000)
darcs-hash:20080301074217-5007d-58d4bffdc10cc4a7fbbc6db7427d5ee03add07a8.gz

src/org/ibex/mail/SqliteMailbox.java

index 0d80532..c880f75 100644 (file)
@@ -54,6 +54,7 @@ public class SqliteMailbox extends Mailbox.Default implements MailTree {
     private final File file;
     public  int uidValidity()  { return uidValidity; }
 
+    public String toString() { return file.getName(); }
     public SqliteMailbox(String filename) throws SQLException {
         try {
             this.file = new File(filename);
@@ -77,6 +78,44 @@ public class SqliteMailbox extends Mailbox.Default implements MailTree {
         catch (ClassNotFoundException e) { throw new RuntimeException(e); }
     }
 
+    private HashMap<Integer,Integer> imapToUid = new HashMap<Integer,Integer>();
+    private HashMap<Integer,Integer> uidToImap = new HashMap<Integer,Integer>();
+    private boolean imapNumberCacheValid = false;
+    public void updateImapNumberCache() throws SQLException {
+        synchronized(this) {
+            Log.warn(this+"", "rebuilding imapNumberCache...");
+            imapToUid.clear();
+            uidToImap.clear();
+            PreparedStatement q = conn.prepareStatement("select uid_ from mail");
+            ResultSet rs = q.executeQuery();
+            int num = 1;
+            while(rs.next()) {
+                imapToUid.put(num, rs.getInt(1));
+                uidToImap.put(rs.getInt(1), num);
+                num++;
+            }
+            imapNumberCacheValid = true;
+        }
+    }
+    public int queryImapNumberCache(int uid) throws SQLException {
+        synchronized(this) {
+            if (!imapNumberCacheValid) updateImapNumberCache();
+            Integer ret = uidToImap.get(uid);
+            if (ret == null) return -1;
+            return ret;
+        }
+    }
+    public int queryUidForImapNum(int imapNumber) throws SQLException {
+        synchronized(this) {
+            if (!imapNumberCacheValid) updateImapNumberCache();
+            Integer ret = imapToUid.get(imapNumber);
+            if (ret == null) return -1;
+            return ret;
+        }
+    }
+
+
+    public int maxuid() { return uidNext(); }
     public int uidNext() {
         try {
             PreparedStatement q = conn.prepareStatement("select max(uid_) from mail");
@@ -86,8 +125,12 @@ public class SqliteMailbox extends Mailbox.Default implements MailTree {
         } catch (Exception e) { throw new RuntimeException(e); }
     }
 
-    public Mailbox.Iterator iterator()                   { return new SqliteJdbcIterator(); }
-    private static String set(int[] set, String arg) {
+    public Mailbox.Iterator iterator() {
+        Log.warn(this, "performance warning: called iterator() on entire mailbox");
+        Log.printStackTrace(this, Log.WARN);
+        return new SqliteJdbcIterator();
+    }
+    private String set(int[] set, String arg) {
         String whereClause = "";
         boolean needsOr = false;
         for(int i=0; i<set.length; i+=2) {
@@ -178,6 +221,9 @@ public class SqliteMailbox extends Mailbox.Default implements MailTree {
             add.setString(7, streamToString(m.getBody().getStream()));
             add.setInt   (8, flags);
             add.executeUpdate();
+
+            // FIXME: be smarter here?
+            imapNumberCacheValid = false;
         } catch (Exception e) { throw new RuntimeException(e); }
     }
 
@@ -204,15 +250,11 @@ public class SqliteMailbox extends Mailbox.Default implements MailTree {
                 query.setString(1, rs.getString(1));
 
                 ResultSet rs2 = query.executeQuery();
-                if (!rs2.next()) {
-                    Log.error("XXX", "should not happen");
-                    return null;
-                }
+                if (!rs2.next()) { Log.error("XXX", "should not happen"); return null; }
                 m = Message.newMessage(Fountain.Util.concat(Fountain.Util.create(rs2.getString(1)),
                                                             Fountain.Util.create("\r\n\r\n"),
                                                             Fountain.Util.create(rs2.getString(2))));
                 flags = rs2.getInt(3);
-
                 return m;
             } catch (Exception e) { throw new RuntimeException(e); }
         }
@@ -255,6 +297,10 @@ public class SqliteMailbox extends Mailbox.Default implements MailTree {
                 PreparedStatement update = conn.prepareStatement("delete from mail where uid_=?");
                 update.setInt(1, uid());
                 update.executeUpdate();
+
+                // FIXME: be smarter here?
+                imapNumberCacheValid = false;
+
             } catch (Exception e) { throw new RuntimeException(e); }
         }
     }